嚴格來說,你想要使用Haversine formula。
然而,儘管你可能在遠北或遠南的地方略微偏出一點,但你也許可以假裝墨卡託投影對距離是準確的,而忽略了地球的曲率。如果你要有很多城市,尤其如此,因爲錯誤更大,其他點來自目標點。因此,你只想用畢達哥拉斯:
relDist = √((xLat - yLat) × (xLat - yLat) + (xLng - yLng) × (xLng - yLng))
但因爲你只關心(並且只得到)的相對排序,你可以跳過平方根位,這是最重的步:
relDist = (xLat - yLat) × (xLat - yLat) + (xLng - yLng) × (xLng - yLng)
如果您將座標存儲爲實際座標的倍數(例如,將紐約(40.664167,-73.938611)存儲爲一對(406642, - ),則可以合理預整型爲整數, 739386)如果你想快速地將大量的地點按照接近指定點的順序排序,這可能是一個很大的提升。
然而,如果你真的關心精度的事實,地球是圓的,面部,隨後下列工具半正矢:
private const double radiusE = 6378135; // Equatorial radius
private const double radiusP = 6356750; // Polar radius
private const double radianConv = 180/Math.PI;
public static double GetDistanceBetweenPoints(double lat1, double long1, double lat2, double long2)
{
double dLat = (lat2 - lat1)/radianConv;
double dLong = (long2 - long1)/radianConv;
double a = Math.Sin(dLat/2) * Math.Sin(dLat/2) + Math.Cos(lat2) * Math.Sin(dLong/2) * Math.Sin(dLong/2);
return Math.Sqrt((Math.Pow(radiusE * radiusP * Math.Cos(lat1/radianConv), 2))/(Math.Pow(radiusE * Math.Cos(lat1/radianConv), 2) + Math.Pow(radiusP * Math.Sin(lat1/radianConv), 2))) * (2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a)));
}
這是不完全正確。在40°N時,一定的緯度比一個經度的距離更長。請參閱http://en.wikipedia.org/wiki/Longitude#Length_of_a_degree_of_longitude –
@EeroAaltonen我的回答(或者說,我給出的替代方案之一)處理這個問題,但這對於某些目的來說足夠接近,並且更快計算。我唯一的反對意見是不需要的'sqrt',它不會影響相對順序。 –