c#GPS 2個の緯度点算間の距離
変換元:http://chageoni.iteye.com/blog/929884
2点の緯度に基づいて距離を計算する
経緯交換
度(DDD):E 108.95593度 N 34.2163度
度(DDD):108.95593度を度分秒(DMS)東経E 108度54分22.2秒に換算するにはどうすればいいですか.変換方法は、108.90593の整数ビットを108(度)に変更する、0.90593*60=54.3558で整数ビット54(分)、0.3558*60=21.348で整数ビット21(秒)を取るので、108度54分21秒に変換する.
同様に度分秒(DMS):東経E 108度54分22.2秒を度(DDD)に換算する方法は、108度54分22.2秒=108+(54/60)+(22.2/3600)=108.96616度
計算時に小数位が保持されるため,正逆計算に一定の誤差が生じるが,誤差の影響は大きくない.1秒の誤差は数メートルの様子です.GPSの車友は上記の方法で自分の必要な単位座標に換算することができます.
経緯度をメートルに換算する
緯度は60分に分けられ、1分ごとに60秒と秒の小数に分けられる.緯度線は図上で水平に見える平行線に投影されるが、実際には異なる半径の円である.同じ特定の緯度を持つすべての位置は同じ緯線にあります.赤道の緯度は0°で、惑星を南半球と北半球に分けます.緯度とは、ある点と地球の球心との連線と地球赤道面との線面角を指し、その数値は0〜90度である.赤道以北に位置する点の緯度を北緯といい、Nと記し、赤道以南に位置する点の緯度を南緯といい、Sと記す.緯度値が0〜30度の地域を低緯地域、緯度値が30〜60度の地域を中緯地域、緯度値が60〜90度の地域を高緯地域と呼ぶ.赤道、南回帰線、北回帰線、南極圏、北極圏は特殊な緯線である.緯度1秒の長さ地球の子午線の全長は約4008 km.平均:緯度1度=約111 km緯度1分=約1.85 km緯度1秒=約30.9 m
WGS 84座標系下(通常我々が採用するGPS内の座標系)
中国でよく使われるWGS 1984の緯度座標であれば、1秒で33メートルに相当する.具体的には以下の通りです.
経度1度=85.39 km
経度1分=1.42 km
経度1秒=23.6 m
地球上の任意の2点の緯度に基づいて2点間の距離を計算する
地球は標準に近い楕円体で、赤道半径は6378.140キロ、極半径は6356.755キロ、平均半径は6371.004キロです.もし私たちが地球が完璧な球体であると仮定すれば、その半径は地球の平均半径であり、Rと表記されている.0度の経線を基準にすれば、地球表面の任意の2点の緯度に基づいて、この2点間の地表距離を算出することができる(ここでは、地球表面地形が計算に与える誤差を無視し、理論的な推定値にすぎない).第1点Aの緯度を(LonA,LatA)、第2点Bの緯度を(LonB,LatB)とし、0度経線の基準で東経が経度の正値(Longitude)、西が経度負値(-Longgitude)、北緯が90-緯度値(90-Latitude)、南緯度が90+緯度値(90+Latitude)をとると、上記処理後の2点を(MLonA,MLatA)および(MLonB,MLatB)とする.では、三角の導出に基づいて、2点距離を計算する次の式を得ることができます.
C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)*cos(MLatB)
Distance = R*Arccos(C)*Pi/180
ここで、RはDistance単位と同じであり、半径として6371.004 kmを採用する場合、Distanceはkm単位であり、mileなどの他の単位を使用する場合は単位換算が必要であり、1 km=0.621371192 mile
緯度を90-Latitude(北半球と仮定し、南半球はオーストラリアのみが適用される)ではなく、経度のみを正負に処理する場合、式は次のようになります.
C = sin(LatA)*sin(LatB) + cos(LatA)*cos(LatB)*cos(MLonA-MLonB)
Distance = R*Arccos(C)*Pi/180
以上は簡単な三角変換で出すことができます.
三角関数の入力と出力にラジアン値を使用する場合は、式を書くこともできます.
C = sin(LatA*Pi/180)*sin(LatB*Pi/180) + cos(LatA*Pi/180)*cos(LatB*Pi/180)*cos((MLonA-MLonB)*Pi/180)
Distance = R*Arccos(C)*Pi/180
つまり、
C = sin(LatA/57.2958)*sin(LatB/57.2958) + cos(LatA/57.2958)*cos(LatB/57.2958)*cos((MLonA-MLonB)/57.2958)
Distance = R*Arccos(C) = 6371.004*Arccos(C) kilometer = 0.621371192*6371.004*Arccos(C) mile = 3958.758349716768*Arccos(C) mile
実際の応用では,一般に1つの個体の郵便番号によってその郵便番号に対応する地域中心の緯度を検索し,これらの緯度に基づいて互いの距離を計算し,ある集団間のほぼ距離範囲を推定する.(例えば、ホテルの旅客の分布範囲-各旅客の郵便番号に対応する経緯度とホテルの経緯度で計算される距離範囲-など)なので、郵便番号で経緯度を調べるというデータベースは有用なリソースです.付:C#コード:
private const double EARTH_RADIUS=6378.137;//地球半径private static double rad(double d){ return d * Math.PI/180.0; }
public static double GetDistance(double lat1, double lng1, double lat2, double lng2) { double radLat1 = rad(lat1); double radLat2 = rad(lat2); double a = radLat1 - radLat2; double b = rad(lng1) - rad(lng2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2) + Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2))); s = s * EARTH_RADIUS; s = Math.Round(s * 10000)/10000; return s; }
2点の緯度に基づいて距離を計算する
? (
), , ,
“ ”。 , , “ ”; ,
。 , 90 , , 。
90 , 90 。 , ,
, 。
, , , “ ”;
, 。 1884 ,
, , “ ”。 , 180 ;
, 180 。 , 180 180 。
180 “ ”。 ,
。
60 , 60 。 ,
, 。 ?
116 24 , 39 54 。 ,
, 。 90 。 0 , , ,
。
, 。
, 。
。 , 。 ,
, 1884 , 、
( ) , 。
, 。 , 。
, , , ,
。 , 。 0° ,
180°, 180°, 、 180° , ,
180° 。
。 , 。 , 。
。 , 、 ,
, 。 , 。
0° , 90°, ; 90°, 。
経緯交換
度(DDD):E 108.95593度 N 34.2163度
度(DDD):108.95593度を度分秒(DMS)東経E 108度54分22.2秒に換算するにはどうすればいいですか.変換方法は、108.90593の整数ビットを108(度)に変更する、0.90593*60=54.3558で整数ビット54(分)、0.3558*60=21.348で整数ビット21(秒)を取るので、108度54分21秒に変換する.
同様に度分秒(DMS):東経E 108度54分22.2秒を度(DDD)に換算する方法は、108度54分22.2秒=108+(54/60)+(22.2/3600)=108.96616度
計算時に小数位が保持されるため,正逆計算に一定の誤差が生じるが,誤差の影響は大きくない.1秒の誤差は数メートルの様子です.GPSの車友は上記の方法で自分の必要な単位座標に換算することができます.
経緯度をメートルに換算する
緯度は60分に分けられ、1分ごとに60秒と秒の小数に分けられる.緯度線は図上で水平に見える平行線に投影されるが、実際には異なる半径の円である.同じ特定の緯度を持つすべての位置は同じ緯線にあります.赤道の緯度は0°で、惑星を南半球と北半球に分けます.緯度とは、ある点と地球の球心との連線と地球赤道面との線面角を指し、その数値は0〜90度である.赤道以北に位置する点の緯度を北緯といい、Nと記し、赤道以南に位置する点の緯度を南緯といい、Sと記す.緯度値が0〜30度の地域を低緯地域、緯度値が30〜60度の地域を中緯地域、緯度値が60〜90度の地域を高緯地域と呼ぶ.赤道、南回帰線、北回帰線、南極圏、北極圏は特殊な緯線である.緯度1秒の長さ地球の子午線の全長は約4008 km.平均:緯度1度=約111 km緯度1分=約1.85 km緯度1秒=約30.9 m
WGS 84座標系下(通常我々が採用するGPS内の座標系)
中国でよく使われるWGS 1984の緯度座標であれば、1秒で33メートルに相当する.具体的には以下の通りです.
経度1度=85.39 km
経度1分=1.42 km
経度1秒=23.6 m
地球上の任意の2点の緯度に基づいて2点間の距離を計算する
地球は標準に近い楕円体で、赤道半径は6378.140キロ、極半径は6356.755キロ、平均半径は6371.004キロです.もし私たちが地球が完璧な球体であると仮定すれば、その半径は地球の平均半径であり、Rと表記されている.0度の経線を基準にすれば、地球表面の任意の2点の緯度に基づいて、この2点間の地表距離を算出することができる(ここでは、地球表面地形が計算に与える誤差を無視し、理論的な推定値にすぎない).第1点Aの緯度を(LonA,LatA)、第2点Bの緯度を(LonB,LatB)とし、0度経線の基準で東経が経度の正値(Longitude)、西が経度負値(-Longgitude)、北緯が90-緯度値(90-Latitude)、南緯度が90+緯度値(90+Latitude)をとると、上記処理後の2点を(MLonA,MLatA)および(MLonB,MLatB)とする.では、三角の導出に基づいて、2点距離を計算する次の式を得ることができます.
C = sin(MLatA)*sin(MLatB)*cos(MLonA-MLonB) + cos(MLatA)*cos(MLatB)
Distance = R*Arccos(C)*Pi/180
ここで、RはDistance単位と同じであり、半径として6371.004 kmを採用する場合、Distanceはkm単位であり、mileなどの他の単位を使用する場合は単位換算が必要であり、1 km=0.621371192 mile
緯度を90-Latitude(北半球と仮定し、南半球はオーストラリアのみが適用される)ではなく、経度のみを正負に処理する場合、式は次のようになります.
C = sin(LatA)*sin(LatB) + cos(LatA)*cos(LatB)*cos(MLonA-MLonB)
Distance = R*Arccos(C)*Pi/180
以上は簡単な三角変換で出すことができます.
三角関数の入力と出力にラジアン値を使用する場合は、式を書くこともできます.
C = sin(LatA*Pi/180)*sin(LatB*Pi/180) + cos(LatA*Pi/180)*cos(LatB*Pi/180)*cos((MLonA-MLonB)*Pi/180)
Distance = R*Arccos(C)*Pi/180
つまり、
C = sin(LatA/57.2958)*sin(LatB/57.2958) + cos(LatA/57.2958)*cos(LatB/57.2958)*cos((MLonA-MLonB)/57.2958)
Distance = R*Arccos(C) = 6371.004*Arccos(C) kilometer = 0.621371192*6371.004*Arccos(C) mile = 3958.758349716768*Arccos(C) mile
実際の応用では,一般に1つの個体の郵便番号によってその郵便番号に対応する地域中心の緯度を検索し,これらの緯度に基づいて互いの距離を計算し,ある集団間のほぼ距離範囲を推定する.(例えば、ホテルの旅客の分布範囲-各旅客の郵便番号に対応する経緯度とホテルの経緯度で計算される距離範囲-など)なので、郵便番号で経緯度を調べるというデータベースは有用なリソースです.付:C#コード:
private const double EARTH_RADIUS=6378.137;//地球半径private static double rad(double d){ return d * Math.PI/180.0; }
public static double GetDistance(double lat1, double lng1, double lat2, double lng2) { double radLat1 = rad(lat1); double radLat2 = rad(lat2); double a = radLat1 - radLat2; double b = rad(lng1) - rad(lng2);
double s = 2 * Math.Asin(Math.Sqrt(Math.Pow(Math.Sin(a/2),2) + Math.Cos(radLat1)*Math.Cos(radLat2)*Math.Pow(Math.Sin(b/2),2))); s = s * EARTH_RADIUS; s = Math.Round(s * 10000)/10000; return s; }