【问题标题】:Calculating distance between two points using latitude longitude and altitude (elevation)使用纬度经度和高度(海拔)计算两点之间的距离
【发布时间】:2023-12-17 20:34:01
【问题描述】:

我正在尝试使用纬度经度和高度(海拔)计算两点之间的距离。

我使用 euklides 公式来计算距离:

D=√((Long1-Long2)²+(Lat1-Lat2)²+(Alt1-Alt2)²)

我的点是地理坐标,当然高度是我在海面上的高度。 我只有 lat 和 lng,我正在使用 GOOGLE API Elevation 来获取我的高度。

我正在开发一个应用程序来计算我的行进距离(在我的滑雪板上)。我使用过的每个应用程序都会以包含的高度进行距离旅行。像 #Endomondo 或 #Garmin 一样,我无法在 2D 空间中获得距离,因为真实距离会与我返回的距离不同。

哪个公式最适合计算我的距离?当然包括高度。

我正在使用 Python 和 PostGis 编写我的应用程序。

【问题讨论】:

  • 为什么不在Postgis中存储坐标并使用ST_distance函数?
  • 有几篇文章对 Garmin 和其他公司在计算中使用海拔高度的说法提出异议。 trailhunger.com/info/articles/garmin-distance-calculation 。在等式中,您将度数和米数结合起来。
  • 嘿,@sebb,你觉得答案有帮助吗?

标签: python django postgis geodjango geographic-distance


【解决方案1】:

您可以使用geopy 包或Vincenty's 公式计算平面坐标之间的距离,例如米,直接粘贴坐标。假设结果是d 米。那么总行驶距离为sqrt(d**2 + h**2),其中h 是以米为单位的海拔变化。

【讨论】:

    【解决方案2】:

    EDIT 2019:自从有了这个答案,我就编写了一个问答风格的例子来回答类似的问题(包括这个作为例子):How to calculate 3D distance (including altitude) between two points in GeoDjango

    排序中:

    我们需要使用Haversine formulaVicenty formula 计算两点之间的二维great-circle distance,然后我们可以将其与两点之间的高度差(增量)结合起来计算Euclidean distance它们之间的关系如下:

    dist = sqrt(great_circle((lat_1, lon_1), (lat_2, lon_2)).m**2, (alt_1 - alt_2)**2)
    

    该解决方案假定高度以米为单位,因此也将great_circle 的结果转换为米。


    您可以通过将您的坐标从Polar (long, lat, alt) 转换为Cartesian (x, y, z) 来得到正确的计算:

    • 让:
      polar_point_1 = (long_1, lat_1, alt_1)

      polar_point_2 = (long_2, lat_2, alt_2)
    • 利用以下公式将每个点转换为笛卡尔等价物:

      x = alt * cos(lat) * sin(long)
      y = alt * sin(lat)
      z = alt * cos(lat) * cos(long)
      

      您将分别获得p_1 = (x_1, y_1, z_1)p_2 = (x_2, y_2, z_2) 积分。

    • 最后使用欧几里得公式:

      dist = sqrt((x_2-x_1)**2 + (y_2-y_1)**2 + (z_2-z_1)**2)
      

    【讨论】:

    • 这个距离的测量单位是什么,你将如何将它转换回米??
    • @AngryDuck 由于我们使用的是 Google Elevation API,alt 以米为单位,因此dist 将以米为单位。
    • 好吧,只要我的高度以米为单位,我就可以取dist的值,它会以米为单位?
    • @AngryDuck 是的,情况就是这样(您将拥有与 alt 变量相同的单位)!
    • 在转换为笛卡尔坐标时,不应该修改高度以考虑地球半径吗? IE。在转换方程中使用 alt+earth_radius?
    【解决方案3】:

    我使用了 John Moutafis 提供的解决方案,但没有得到正确答案。公式需要进行一些更正。您将在http://electron9.phys.utk.edu/vectors/3dcoordinates.htm 处获得从极坐标到笛卡尔坐标 (x, y, z) 的转换。 使用上述公式将球坐标(极坐标)转换为笛卡尔坐标并计算欧几里得距离。

    我在控制台应用程序中使用了以下 c#。 考虑跟随虚拟经纬度

           double lat_1 = 18.457793 * (Math.PI / 180);
           double lon_1 = 73.3951930277778 *(Math.PI/180);
           double alt_1 = 270.146;
    
           double lat_2 = 18.4581253333333 * (Math.PI / 180);
           double lon_2 = 73.3963755277778 * (Math.PI / 180);
           double alt_2 = 317.473;
    
           const Double r = 6376.5 *1000; // Radius of Earth in metres
    
           double x_1 = r * Math.Sin(lon_1) * Math.Cos(lat_1);
           double y_1 = r * Math.Sin(lon_1) * Math.Sin(lat_1);
           double z_1 = r * Math.Cos(lon_1);
    
           double x_2 = r * Math.Sin(lon_2) * Math.Cos(lat_2);
           double y_2 = r * Math.Sin(lon_2) * Math.Sin(lat_2);
           double z_2 = r * Math.Cos(lon_2);
    
           double dist = Math.Sqrt((x_2 - x_1) * (x_2 - x_1) + (y_2 - y_1) *    
                                   (y_2 - y_1) + (z_2 - z_1) * (z_2 - z_1));
    

    【讨论】:

    • 这似乎只考虑了r 中的地球半径,但还应包括每个点的地球表面以上的高程,例如第 1 点和第 2 点的 r 应该不同,例如 r1 = r + alt1r2 = r + alt2。通过这种修改,这似乎比@John Moutafis 的答案更直观(由于在这个答案中假设球形地球,因此与 XY 的 Haversine 计算最直接可比),尽管它们最终可能在数学上都是正确的。跨度>