現在、以下の機能を使用していますが、正しく機能しません。 Googleマップによると、 これらの座標 (59.3293371,13.4877472
から59.3225525,13.4619422
)までの距離は2.2
キロメートルですが、関数は1.6
キロメートルを返します。この関数が正しい距離を返すようにするにはどうすればよいですか?
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)
}
jsFiddle: http://jsfiddle.net/edgren/gAHJB/
使用しているものは haversine formula と呼ばれ、球体上の2点間の距離をカラスが飛ぶように計算します 。指定したGoogleマップのリンクでは、直線ではないため、距離は2.2 kmと表示されます。
Wolphram Alphaは、地理計算を行うための優れたリソースであり、 これら2つのポイント間の1.652 km の距離も示しています。
(カラスファイルとして)直線距離を探している場合、関数は正しく動作しています。必要なものが運転距離(または自転車の距離、公共交通機関の距離、徒歩の距離)の場合、マッピングAPIを使用する必要があります( Google または Bing 人気のある)距離を含む適切なルートを取得します。
ちなみに、Google Maps APIは google.maps.geometry.spherical
名前空間 (computeDistanceBetween
を探して)で球面距離のパッケージ化されたメソッドを提供します。たぶん、あなた自身のものを転がすよりも良いでしょう(まず、地球の半径により正確な値を使用します)。
私たちの間のうるさい人のために、「直線距離」と言うとき、私はもちろん「球上の直線」を指します。これは、実際には曲線(つまり、大円距離)です。
私は以前に同様の方程式を書きました-それをテストし、1.6 kmを得ました。
Googleマップに運転距離が表示されていました。
あなたの関数は、カラスが飛ぶように計算しています(直線距離)。
alert(calcCrow(59.3293371,13.4877472,59.3225525,13.4619422).toFixed(1));
//This function takes in latitude and longitude of two location and returns the distance between them as the crow flies (in km)
function calcCrow(lat1, lon1, lat2, lon2)
{
var R = 6371; // km
var dLat = toRad(lat2-lat1);
var dLon = toRad(lon2-lon1);
var lat1 = toRad(lat1);
var lat2 = toRad(lat2);
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
return d;
}
// Converts numeric degrees to radians
function toRad(Value)
{
return Value * Math.PI / 180;
}
Derekのソリューションは私にとっては問題なく機能し、単にPHPに変換しただけです。
function calcCrow($lat1, $lon1, $lat2, $lon2){
$R = 6371; // km
$dLat = toRad($lat2-$lat1);
$dLon = toRad($lon2-$lon1);
$lat1 = toRad($lat1);
$lat2 = toRad($lat2);
$a = sin($dLat/2) * sin($dLat/2) +sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2);
$c = 2 * atan2(sqrt($a), sqrt(1-$a));
$d = $R * $c;
return $d;
}
// Converts numeric degrees to radians
function toRad($Value)
{
return $Value * pi() / 180;
}
これを試して。これはVB.netにあり、Javascriptに変換する必要があります。この関数は、10分の単位でパラメーターを受け入れます。
Private Function calculateDistance(ByVal long1 As String, ByVal lat1 As String, ByVal long2 As String, ByVal lat2 As String) As Double
long1 = Double.Parse(long1)
lat1 = Double.Parse(lat1)
long2 = Double.Parse(long2)
lat2 = Double.Parse(lat2)
'conversion to radian
lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0
long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0
lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0
long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0
' use to different earth axis length
Dim a As Double = 6378137.0 ' Earth Major Axis (WGS84)
Dim b As Double = 6356752.3142 ' Minor Axis
Dim f As Double = (a - b) / a ' "Flattening"
Dim e As Double = 2.0 * f - f * f ' "Eccentricity"
Dim beta As Double = (a / Math.Sqrt(1.0 - e * Math.Sin(lat1) * Math.Sin(lat1)))
Dim cos As Double = Math.Cos(lat1)
Dim x As Double = beta * cos * Math.Cos(long1)
Dim y As Double = beta * cos * Math.Sin(long1)
Dim z As Double = beta * (1 - e) * Math.Sin(lat1)
beta = (a / Math.Sqrt(1.0 - e * Math.Sin(lat2) * Math.Sin(lat2)))
cos = Math.Cos(lat2)
x -= (beta * cos * Math.Cos(long2))
y -= (beta * cos * Math.Sin(long2))
z -= (beta * (1 - e) * Math.Sin(lat2))
Return Math.Sqrt((x * x) + (y * y) + (z * z))
End Function
編集 JavaScriptで変換された関数
function calculateDistance(lat1, long1, lat2, long2)
{
//radians
lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0;
long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0;
lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0;
long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0;
// use to different earth axis length
var a = 6378137.0; // Earth Major Axis (WGS84)
var b = 6356752.3142; // Minor Axis
var f = (a-b) / a; // "Flattening"
var e = 2.0*f - f*f; // "Eccentricity"
var beta = (a / Math.sqrt( 1.0 - e * Math.sin( lat1 ) * Math.sin( lat1 )));
var cos = Math.cos( lat1 );
var x = beta * cos * Math.cos( long1 );
var y = beta * cos * Math.sin( long1 );
var z = beta * ( 1 - e ) * Math.sin( lat1 );
beta = ( a / Math.sqrt( 1.0 - e * Math.sin( lat2 ) * Math.sin( lat2 )));
cos = Math.cos( lat2 );
x -= (beta * cos * Math.cos( long2 ));
y -= (beta * cos * Math.sin( long2 ));
z -= (beta * (1 - e) * Math.sin( lat2 ));
return (Math.sqrt( (x*x) + (y*y) + (z*z) )/1000);
}
JavaScriptで2点間の距離を計算する
function distance(lat1, lon1, lat2, lon2, unit) {
var radlat1 = Math.PI * lat1/180
var radlat2 = Math.PI * lat2/180
var radlon1 = Math.PI * lon1/180
var radlon2 = Math.PI * lon2/180
var theta = lon1-lon2
var radtheta = Math.PI * theta/180
var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
dist = Math.acos(dist)
dist = dist * 180/Math.PI
dist = dist * 60 * 1.1515
if (unit=="K") { dist = dist * 1.609344 }
if (unit=="N") { dist = dist * 0.8684 }
return dist
}
詳細については、これを参照してください。 参照リンク