在计算测地距离时考虑高度

Joa*_*mer 12 geometry gps geospatial

我目前正在处理gps数据和精确的高度测量.我想计算两个连续点之间的距离.有很多关于使用WGS84椭圆体等计算两点之间距离的信息.

但是,我没有找到任何将海拔高度变化考虑在内的距离计算信息.

有没有人知道一些描述这种方法的网站,论文,书籍等?谢谢

编辑:Sql Server 2008地理扩展也在计算距离时忽略高度信息.

Ron*_*lic 8

我使用起始高度和结束高度的平均值作为恒定高度来实现WGS84距离函数.如果您确定沿着您的路径会有相对较小的高度变化,这可以很好地工作(误差是相对于您的两个LLA点的高度差).

这是我的代码(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);
    }
Run Code Online (Sandbox Code Playgroud)

在实践中,我们发现高度差异很少产生很大的差异,我们的路径通常为1-2km长,高度在100m的数量级上变化,我们看到平均变化约为5m,与使用未经修改的WGS84椭球相比.

编辑:

要添加到这一点,如果你不希望较大的高度变化,您可以将您的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;
    }
Run Code Online (Sandbox Code Playgroud)

编辑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;
Run Code Online (Sandbox Code Playgroud)

LatLonAltTransformer 是一个我用来从LatLonAlt坐标转换为ECEF坐标的类,并定义了上面的常量.

  • 我认为你在假设他想要的东西时过于宽泛.他正在使用GPS数据点,这些数据点间隔很近,而不是相距60英里.对于这种情况,使用直线近似是非常好的,并且实际上可以产生比大的高度变化的大圆距离更好的结果.如果您在近地面处间隔60英里,则必须使用地形数据(DTED)并跟踪路径,因为地形特征非常重要,它们将是您距离的主要贡献者. (4认同)

Jos*_*hua 0

我建议,在任何距离上,使用 WGS84 都会给您带来明显更好的精度,而海拔差异并不重要。在海拔差异很重要的任何距离上,您可能应该只使用直线近似。