Ich habe eine WGS84-Entfernungsfunktion implementiert, die den Durchschnitt der Start- und Endhöhe als konstante Höhe verwendet. Wenn Sie sicher sind, dass sich auf Ihrem Weg relativ wenig Höhenschwankungen ergeben, funktioniert dies akzeptabel (der Fehler ist relativ zum Höhenunterschied Ihrer beiden LLA-Punkte).
Hier ist mein Code (C#):
/// <summary>
/// Gets the geodesic distance between two pathpoints in the current mode's coordinate system
/// </summary>
/// <param name="point1">First point</param>
/// <param name="point2">Second point</param>
/// <param name="mode">Coordinate mode that both points are in</param>
/// <returns>Distance between the two points in the current coordinate mode</returns>
public static double GetGeodesicDistance(PathPoint point1, PathPoint point2, CoordMode mode) {
// calculate proper geodesics for LLA paths
if (mode == CoordMode.LLA) {
// meeus approximation
double f = (point1.Y + point2.Y)/2 * LatLonAltTransformer.DEGTORAD;
double g = (point1.Y - point2.Y)/2 * LatLonAltTransformer.DEGTORAD;
double l = (point1.X - point2.X)/2 * LatLonAltTransformer.DEGTORAD;
double sinG = Math.Sin(g);
double sinL = Math.Sin(l);
double sinF = Math.Sin(f);
double s, c, w, r, d, h1, h2;
// not perfect but use the average altitude
double a = (LatLonAltTransformer.A + point1.Z + LatLonAltTransformer.A + point2.Z)/2.0;
sinG *= sinG;
sinL *= sinL;
sinF *= sinF;
s = sinG * (1 - sinL) + (1 - sinF) * sinL;
c = (1 - sinG) * (1 - sinL) + sinF * sinL;
w = Math.Atan(Math.Sqrt(s/c));
r = Math.Sqrt(s * c)/w;
d = 2 * w * a;
h1 = (3 * r - 1)/2/c;
h2 = (3 * r + 1)/2/s;
return d * (1 + (1/LatLonAltTransformer.RF) * (h1 * sinF * (1 - sinG) - h2 * (1 - sinF) * sinG));
}
PathPoint diff = new PathPoint(point2.X - point1.X, point2.Y - point1.Y, point2.Z - point1.Z, 0);
return Math.Sqrt(diff.X * diff.X + diff.Y * diff.Y + diff.Z * diff.Z);
}
In der Praxis wir, dass die Höhendifferenz einen großen Unterschied macht selten gefunden haben, unsere Wege werden typischerweise 1-2 km lang mit der Höhe in der Größenordnung von 100 m variiert und wir sehen ungefähr ~ 5m Änderung im Vergleich zur Verwendung des WGS84 Ellipsoids unmodifiziert.
Edit:
dazu hinzuzufügen, wenn Sie große Höhenänderungen tun erwarten, können Sie konvertieren Sie Ihre WGS84 zu ECEF-Koordinaten (Erde zentrierte Erde fest) und bewerten geradlinige Pfade als meine am unteren Ende gezeigt Funktion. um einen Punkt zu ECEF Umwandlung ist einfach zu tun:
/// <summary>
/// Converts a point in the format (Lon, Lat, Alt) to ECEF
/// </summary>
/// <param name="point">Point as (Lon, Lat, Alt)</param>
/// <returns>Point in ECEF</returns>
public static PathPoint WGS84ToECEF(PathPoint point) {
PathPoint outPoint = new PathPoint(0);
double lat = point.Y * DEGTORAD;
double lon = point.X * DEGTORAD;
double e2 = 1.0/RF * (2.0 - 1.0/RF);
double sinLat = Math.Sin(lat), cosLat = Math.Cos(lat);
double chi = A/Math.Sqrt(1 - e2 * sinLat * sinLat);
outPoint.X = (chi + point.Z) * cosLat * Math.Cos(lon);
outPoint.Y = (chi + point.Z) * cosLat * Math.Sin(lon);
outPoint.Z = (chi * (1 - e2) + point.Z) * sinLat;
return outPoint;
}
Edit 2:
ich über einige der anderen Variablen in meinem Code gefragt wurde:
// RF is the eccentricity of the WGS84 ellipsoid
public const double RF = 298.257223563;
// A is the radius of the earth in meters
public const double A = 6378137.0;
LatLonAltTransformer
ist eine Klasse I verwendet Konvertieren von LatLonAlt-Koordinaten in ECEF-Koordinaten und definiert die obigen Konstanten.
Ich habe nicht an den WGS84 Gleichungen sah, so schreibe ich nicht dies als eine Antwort. Das heißt, es scheint mir, dass Sie in der Lage sein sollten, einen Radius oder zwei zu optimieren, um Ihre Messpunkte zu der "neuen" Oberfläche zu machen. Dies würde wahrscheinlich am besten funktionieren, wenn Ihre Höhenmessungen GPS-basiert sind; auf der Grundlage mechanischer Mittel (z. B. Luftdruck) kann "Meereshöhe" eine sehr geringe Beziehung zum Modell-Geoid haben. – kdgregory
Haben Sie jemals eine gute Lösung dafür gefunden? – lnafziger