मैंने निरंतर ऊंचाई के रूप में प्रारंभ और अंत ऊंचाई के औसत का उपयोग करके एक डब्लूजीएस 84 दूरी समारोह लागू किया। यदि आप निश्चित हैं कि आपके पथ के साथ अपेक्षाकृत कम ऊंचाई भिन्नता होगी तो यह स्वीकार्य रूप से अच्छी तरह से काम करता है (त्रुटि आपके दो एलएलए बिंदुओं के ऊंचाई अंतर के सापेक्ष है)।
/// <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);
}
अभ्यास में हमने पाया है कि ऊंचाई अंतर शायद ही कभी एक बड़े फर्क नहीं पड़ता, हमारे पथ आमतौर पर ऊंचाई 100 मीटर के आदेश पर बदलती के साथ लंबे समय 1-2km रहे हैं:
यहाँ मेरी कोड (सी #) है और हम WGS84 ellipsoid unmodified का उपयोग कर औसत बनाम ~ 5m परिवर्तन के बारे में देखते हैं।
संपादित करें:
यह करने के लिए जोड़ने के लिए, यदि आप बड़े ऊंचाई परिवर्तन की उम्मीद करते हैं, तो आप अपने WGS84 ECEF (पृथ्वी केन्द्रित पृथ्वी निर्धारित) के लिए निर्देशांक परिवर्तित कर सकते हैं और के रूप में के निचले भाग में दिखाया गया है सीधे लाइन पथ का मूल्यांकन मेरी समारोह। ECEF करने के लिए एक बिंदु परिवर्तित करने के लिए सरल है:
/// <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;
}
संपादित करें 2:
मैं अपने कोड में अन्य चर से कुछ के बारे में पूछा गया था:
// 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
एक वर्ग मैं प्रयोग किया जाता है LatLonAlt से कनवर्ट करने के लिए ईसीईएफ निर्देशांक को निर्देशांक और उपरोक्त स्थिरांक परिभाषित करता है।
मैं WGS84 समीकरणों को देखा नहीं है, तो एक जवाब के रूप में इस लेखन नहीं कर रहा हूँ। उस ने कहा, ऐसा लगता है कि आप अपने माप बिंदु को "नई" सतह बनाने के लिए त्रिज्या या दो को ट्विक करने में सक्षम होना चाहिए। यदि आपकी ऊंचाई माप जीपीएस आधारित है तो यह शायद सबसे अच्छा काम करेगा; यदि यांत्रिक साधनों (उदाहरण के लिए, वायु दाब) पर आधारित है, तो "समुद्र स्तर" मॉडल geoid के साथ बहुत कम संबंध हो सकता है। – kdgregory
क्या आपने कभी इसके लिए एक अच्छा समाधान किया है? – lnafziger