地球上兩點距離

張貼日期:2011/6/14 上午 04:14:05

小範圍方法(例如台灣),簡單誤差大

距離排序X^2+Y^2

真實距離=開根(X^2+Y^2)

球面法餘弦

haversine formula半正矢公式,圓形計算,比橢圓計算多出0.3%誤差,實測250KM誤差1KM

javascript:

function distance(sX,sY,eX,eY){

var lat = [sX, eX]

var lng = [sY, sY] //var R = 6371; // km (change this constant to get miles)

var R = 6378137; // In meters

var dLat = (lat[1] - lat[0]) * Math.PI / 180;

var dLng = (lng[1] - lng[0]) * Math.PI / 180;

var dLat1 = lat[0] * Math.PI / 180;

var dLat2 = lat[1] * Math.PI / 180;

var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(dLat1) * Math.cos(dLat1) * Math.sin(dLng / 2) * Math.sin(dLng / 2);

var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

var d = R * c;

return Math.round(d);

}

java:

double haversine( final double ax , final double ay , final double bx ,

final double by ) {

final double //

dLat = ( ( bx - ax ) * Math.PI ) / 180 , //

dLng = ( ( by - ay ) * Math.PI ) / 180 , //

dLat1 = ( ax * Math.PI ) / 180 , //

dLat2 = ( bx * Math.PI ) / 180;

final double a =

( Math.sin( dLat / 2 ) * Math.sin( dLat / 2 ) )

+ ( Math.cos( dLat1 ) * Math.cos( dLat1 ) * Math.sin( dLng / 2 ) * Math

.sin( dLng / 2 ) );

final double c = 2 * Math.atan2( Math.sqrt( a ) , Math.sqrt( 1 - a ) );

//6378.1=km,

//6378137=In meters

return( c * 6378.1 );

}

sql:

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance

FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance

FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;

vincenty formula 最精確,支持橢球體