-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDatum.cs
109 lines (90 loc) · 3.16 KB
/
Datum.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System;
namespace WinCachebox
{
public class Datum
{
public struct Vector3
{
public float X;
public float Y;
public float Z;
public static Vector3 operator +(Vector3 v1, Vector3 v2)
{
Vector3 result;
result.X = v1.X + v2.X;
result.Y = v1.Y + v2.Y;
result.Z = v1.Z + v2.Z;
return result;
}
public static Vector3 operator -(Vector3 v1, Vector3 v2)
{
Vector3 result;
result.X = v1.X - v2.X;
result.Y = v1.Y - v2.Y;
result.Z = v1.Z - v2.Z;
return result;
}
public float Length()
{
return (float)Math.Sqrt(X * X + Y * Y + Z * Z);
}
};
public static Datum WGS84 = new Datum(6378137, 1.0 / 298.257223563, 0, 0, 0);
protected double a;
protected double b;
protected double e;
protected double e_;
protected double f;
protected double xShift;
protected double yShift;
protected double zShift;
public Datum(double a, double f, double xShift, double yShift, double zShift)
{
this.a = a;
this.f = f;
this.b = a * (1 - f);
this.xShift = xShift;
this.yShift = yShift;
this.zShift = zShift;
e = Math.Sqrt((a * a - b * b) / (a * a));
e_ = Math.Sqrt((a * a - b * b) / (b * b));
}
public Vector3 ToECEF(double latitude, double longitude, double elevation)
{
return ToECEF(this, latitude, longitude, elevation);
}
public static Vector3 ToECEF(Datum datum, double latitude, double longitude, double elevation)
{
double radLat = (Math.PI / 180) * latitude;
double radLon = (Math.PI / 180) * longitude;
double N = datum.radiusOfCurvature(latitude);
Vector3 Result;
Result.X = (float)((N + elevation) * Math.Cos(radLat) * Math.Cos(radLon) + datum.xShift);
Result.Y = (float)((N + elevation) * Math.Cos(radLat) * Math.Sin(radLon) + datum.yShift);
Result.Z = (float)(((datum.b * datum.b * N) / (datum.a * datum.a)) * Math.Sin(radLat) + datum.zShift);
return Result;
}
public float Distance(double latFrom, double lonFrom, double latTo, double lonTo)
{
Vector3 diff = ToECEF(this, latFrom, lonFrom, 0) - ToECEF(this, latTo, lonTo, 0);
return diff.Length();
}
public Coordinate FromECEF(Vector3 position, Datum datum)
{
Coordinate coord = new Coordinate
{
Longitude = Math.Atan2(position.Y, position.X) * 180.0 / Math.PI
};
double p = Math.Sqrt((double)position.X * (double)position.X + (double)position.Y * (double)position.Y);
double theta = Math.Atan2((double)position.Z * datum.a, p * datum.b);
double phi = Math.Atan2((double)position.Z + e_ * e_ * datum.b * Math.Pow(Math.Sin(theta), 3), p - datum.e * datum.e * datum.a * Math.Pow(Math.Cos(theta), 3));
coord.Latitude = phi * 180.0 / Math.PI;
coord.Elevation = p / Math.Cos(phi) - radiusOfCurvature(coord.Latitude);
return coord;
}
protected double radiusOfCurvature(double latitude)
{
return a / Math.Sqrt(1 - e * e * Math.Pow(Math.Sin(latitude * Math.PI / 180.0), 2));
}
}
}