计算两个坐标之间的距离,考虑高度变化的短距离

Posted

技术标签:

【中文标题】计算两个坐标之间的距离,考虑高度变化的短距离【英文标题】:Calculate distance between two Coordinates, with short distances considering altitude variation 【发布时间】:2020-11-17 15:02:20 【问题描述】:

我正在开发用于农业用途的 GPS 应用程序。我需要一种方法来精确计算两个坐标之间的距离和差异(X,Y),使用纬度、经度和高度(高度以米为单位)。 这些点将彼此靠近,大约 10m 或更小,距离将用于其他计算,如面积,差值 (X, Y) 将用于渲染 2D 地图。

我的第一个想法是使用直角三角形计算 2D (X, Y),然后再次计算 3D 距离。

这里是一个脚本(在 javascript 中):

function xyDifference(lat1, lng1, lat2, lng2)
        var xdif = (lng1 - lng2)/0.00000898; //value to convert decimal degrees difference to meters
        var ydif = (lat1 - lat2)/0.00000898;
        return [xdif,ydif];


function distanceBetween2D(lat1,lng1,lat2,lng2) 
        var b = Math.abs(lat1 - lat2);
        var c = Math.abs(lng1 - lng2);
        var a = Math.sqrt(Math.pow(b,2) + Math.pow(c,2));
        var dst = a / 0.00000898; 
        return dst;


function distanceBetween3D(lat1,lng1,alt1,lat2,lng2,alt2)
        var dst = distanceBetween2D(lat1,lng1,lat2,lng2);
        a = Math.abs(alt1 - alt2);
        dst = Math.sqrt(Math.pow(dst,2) + Math.pow(a,2));
        return dst;


console.log(distanceBetween(-24.09234566666,-52.5289494999999,588,-24.09231633333,-52.5288795,589));

//It prints 8.51m
//Using Haversine formula with these values it gives something about 7.82m

我想知道这是否是一个好方法,或者是否有更好的方法。我看过 Haversine 公式,但我不知道如何使用它来处理海拔差异,以及如何获得 (X,Y) 差异来渲染地图。

【问题讨论】:

haversine 公式仅与distanceBetween2D afaik 的实现有关。 distanceBetween3D 根本不会改变。 【参考方案1】:

建议使用大地测量库,特别是https://www.movable-type.co.uk/scripts/geodesy-library.html。请注意,此库提供了许多可供选择的大地测量模型(例如,球形与椭圆形)。在您的特定情况下,我选择了两个不同的模块来举例说明它们的用途......

“latlon-ellipsoidal-vincenty.js”提供了计算Lat / Lon之间距离的功能,但不支持高度(altitude)的计算。 “latlon-ellipsoidal.js”提供将 Lat / Lon 转换为笛卡尔地心地球固定 (ECEF) 向量的功能,该向量会影响海拔高度。

<script type="module">

import LatLonE from 'https://cdn.jsdelivr.net/npm/geodesy@2/latlon-ellipsoidal-vincenty.js';
import LatLon,  Cartesian, Vector3d, Dms  from 'https://cdn.jsdelivr.net/npm/geodesy@2/latlon-ellipsoidal.js';

let latlon0 = new LatLonE( -24.09234566666, -52.5289494999999 );
let latlon1 = new LatLonE( -24.09231633333, -52.5288795 );
let latlonDistance = latlon0.distanceTo( latlon1 );

console.log( `Lat/Lon distance from $latlon0.toString() to $latlon1.toString() is $latlonDistancem` );

let cart0 = new LatLon( -24.09234566666, -52.5289494999999, 588 ).toCartesian();
let cart1 = new LatLon( -24.09231633333, -52.5288795, 589 ).toCartesian();
let cartDistance = Math.sqrt( ( cart1.x - cart0.x ) ** 2 + ( cart1.y - cart0.y ) ** 2 + ( cart1.z - cart0.z ) ** 2 );

console.log( `Cartesian distance from $cart0.toString() to $cart1.toString() is $cartDistancem` );

</script>

请注意,Lat / Lon 计算结果为您在 Haversine 公式中观察到的 7.824m。 (这也与@Bergi 的评论一致,因为Haversine 公式似乎没有考虑高度。)

转换为笛卡尔坐标和计算距离会产生一个更大的值,特别是 7.88836m,因为坐标之间存在 1m 的高程差。对边长为 7.824m 和 1m 的直角三角形的斜边进行直线计算,得到长度为 7.88765m,与库的结果非常接近。请记住,1)海拔越高,相同的纬度/经度变得越远,2)地球的椭圆形也会影响计算,那么库的结果在合理范围内......

【讨论】:

以上是关于计算两个坐标之间的距离,考虑高度变化的短距离的主要内容,如果未能解决你的问题,请参考以下文章

计算两个坐标之间距离的点

GPS已知首尾坐标 如何求距离

计算大量 GPS 坐标之间的成对路由距离

Android 百度地图API 如何计算两个坐标之间的驾车距离?

计算两个纬度和经度坐标之间的距离

如何使用 Mapbox Kotlin 计算两个坐标之间的距离