시작 고도와 종료 고도의 평균을 상수 고도로 사용하여 WGS84 거리 함수를 구현했습니다. 당신의 경로를 따른 고도 변화가 비교적 적다는 것이 확실하다면 이것은 잘 작동합니다 (오류는 두 LLA 포인트의 고도 차이에 비례합니다). 우리는 고도 차이가 거의 큰 차이가없는 것으로 나타났습니다 실제로
/// <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);
}
는, 우리의 경로는 일반적으로 고도가 100m 정도의 변화와 함께 긴 1-2km됩니다 여기
내 코드 (C#을)입니다 수정되지 않은 WGS84 타원체를 사용하는 것보다 평균 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 좌표를 ECEF 좌표로 변환하고 위의 상수를 정의합니다.
나는 WGS84 방정식에보고하지 않은, 그래서 대답으로이 글을 쓰는 있지 않다. 즉, 측정 지점을 "새로운"표면으로 만들려면 반경 또는 두 개를 조정할 수 있어야합니다. 이것은 아마도 고도 측정이 GPS 기반이라면 가장 잘 작동 할 것입니다. 기계적 수단 (예 : 공기압)을 기반으로한다면, "해수면"은 모델 지오이드와의 관계가 거의 없을 수 있습니다. – kdgregory
당신은 이것에 대한 좋은 해결책을 내놓은 적이 있습니까? – lnafziger