计算两个经纬度点之间的距离? (Haversine公式)
时间:2020-03-05 18:43:16 来源:igfitidea点击:
如何计算经度和纬度指定的两点之间的距离?
为了澄清起见,我想要以千米为单位的距离;这些要点使用WGS84系统,我想了解可用方法的相对准确性。
解决方案
回答
该链接可能会对我们有所帮助,因为它详细说明了使用Haversine公式计算距离的方法。
摘抄:
This script [in Javascript] calculates great-circle distances between the two points – that is, the shortest distance over the earth’s surface – using the ‘Haversine’ formula.
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) { var R = 6371; // Radius of the earth in km var dLat = deg2rad(lat2-lat1); // deg2rad below var dLon = deg2rad(lon2-lon1); var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon/2) * Math.sin(dLon/2) ; var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; // Distance in km return d; } function deg2rad(deg) { return deg * (Math.PI/180) }
回答
而是取决于我们想要的精度以及定义纬度和经度的基准。非常非常近似地,我们进行了一些球形的触发,但是校正地球不是球形的事实会使公式变得更加复杂。
回答
要计算球面上两个点之间的距离,我们需要进行"大圆"计算。
如果需要将距离重新投影到平面上,有许多C / C ++库可帮助MapTools进行地图投影。为此,我们将需要各种坐标系的投影字符串。
我们可能还会发现MapWindow是可视化这些点的有用工具。作为其开源,它也是如何使用proj.dll库的有用指南,该库似乎是核心的开源投影库。
回答
这是一个实现:
static class DistanceAlgorithm { const double PIx = 3.141592653589793; const double RADIUS = 6378.16; /// <summary> /// Convert degrees to Radians /// </summary> /// <param name="x">Degrees</param> /// <returns>The equivalent in radians</returns> public static double Radians(double x) { return x * PIx / 180; } /// <summary> /// Calculate the distance between two places. /// </summary> /// <param name="lon1"></param> /// <param name="lat1"></param> /// <param name="lon2"></param> /// <param name="lat2"></param> /// <returns></returns> public static double DistanceBetweenPlaces( double lon1, double lat1, double lon2, double lat2) { double dlon = Radians(lon2 - lon1); double dlat = Radians(lat2 - lat1); double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos(Radians(lat1)) * Math.Cos(Radians(lat2)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2)); double angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)); return angle * RADIUS; }
回答
非常感谢所有这些。我在Objective-C iPhone应用程序中使用了以下代码:
const double PIx = 3.141592653589793; const double RADIO = 6371; // Mean radius of Earth in Km double convertToRadians(double val) { return val * PIx / 180; } -(double)kilometresBetweenPlace1:(CLLocationCoordinate2D) place1 andPlace2:(CLLocationCoordinate2D) place2 { double dlon = convertToRadians(place2.longitude - place1.longitude); double dlat = convertToRadians(place2.latitude - place1.latitude); double a = ( pow(sin(dlat / 2), 2) + cos(convertToRadians(place1.latitude))) * cos(convertToRadians(place2.latitude)) * pow(sin(dlon / 2), 2); double angle = 2 * asin(sqrt(a)); return angle * RADIO; }
纬度和经度以十进制表示。我没有对asin()调用使用min(),因为我使用的距离非常小,以至于他们不需要它。
直到我在Radians中传递值之前,它给出的答案都是错误的,现在它与从Apple的Map应用程序获取的值几乎相同:-)
额外更新:
如果我们使用的是iOS4或者更高版本,则Apple提供了一些方法来执行此操作,因此可以使用以下方法实现相同的功能:
-(double)kilometresBetweenPlace1:(CLLocationCoordinate2D) place1 andPlace2:(CLLocationCoordinate2D) place2 { MKMapPoint start, finish; start = MKMapPointForCoordinate(place1); finish = MKMapPointForCoordinate(place2); return MKMetersBetweenMapPoints(start, finish) / 1000; }