web-dev-qa-db-ja.com

緯度または経度をメートルに変換する方法は?

標準のNMEA形式で緯度または経度の読み取り値がある場合、その読み取り値をメートルに変換する簡単な方法/数式はありますか。それをJava(J9)で実装できますか?

編集:Okは私がやりたいことは不可能だと思われる簡単に、しかし私が本当にやりたいことは:

緯度と経度の中間地点があり、緯度と経度のユーザーがあるとすると、それらを比較して、ユーザーに彼らが合理的に近い距離にいることを伝えるタイミングを決定する簡単な方法があるとしましょうウェイポイント?私は合理的であることが主題であると理解していますが、これは簡単にできるのですか、それとも過度に数学的ですか?

108
Adam Taylor

JavaScript関数は次のとおりです。

function measure(lat1, lon1, lat2, lon2){  // generally used geo measurement function
    var R = 6378.137; // Radius of earth in KM
    var dLat = lat2 * Math.PI / 180 - lat1 * Math.PI / 180;
    var dLon = lon2 * Math.PI / 180 - lon1 * Math.PI / 180;
    var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
    Math.sin(dLon/2) * Math.sin(dLon/2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    var d = R * c;
    return d * 1000; // meters
}

説明: https://en.wikipedia.org/wiki/Haversine_formula

Haversineの式は、経度と緯度を指定して、球上の2点間の大圏距離を決定します。

143
b-h-

単純な数式を探しているのであれば、地球が40075 kmの球体であると仮定すると、おそらくこれが最も簡単な方法です。

緯度1°のメートル単位の長さ=常に111.32 km

経度1°のメートル単位の長さ= 40075 km * cos(緯度)/ 360

37
Ben

2つの座標間の短い距離を概算するために、 http://en.wikipedia.org/wiki/Lat-lon の式を使用しました。

m_per_deg_lat = 111132.954 - 559.822 * cos( 2 * latMid ) + 1.175 * cos( 4 * latMid);
m_per_deg_lon = 111132.954 * cos ( latMid );

以下のコードでは、ウィキペディアの式との関係を示すために生の数値を残しています。

double latMid, m_per_deg_lat, m_per_deg_lon, deltaLat, deltaLon,dist_m;

latMid = (Lat1+Lat2 )/2.0;  // or just use Lat1 for slightly less accurate estimate


m_per_deg_lat = 111132.954 - 559.822 * cos( 2.0 * latMid ) + 1.175 * cos( 4.0 * latMid);
m_per_deg_lon = (3.14159265359/180 ) * 6367449 * cos ( latMid );

deltaLat = fabs(Lat1 - Lat2);
deltaLon = fabs(Lon1 - Lon2);

dist_m = sqrt (  pow( deltaLat * m_per_deg_lat,2) + pow( deltaLon * m_per_deg_lon , 2) );

ウィキペディアのエントリには、距離計算は縦方向に100kmで0.6m以内、縦方向に100kmで1cm以内であると記載されていますが、その精度に近いため、これを検証していません。

28
JJones

緯度と経度は距離ではなくポイントを指定するため、質問は無意味です。 2つの(lat、lon)ポイント間の最短距離については、大圏距離に関する このWikipediaの記事 を参照してください。

12
John Feminella

地球は迷惑なほど不規則な表面なので、これを正確に行う簡単な公式はありません。地球のおおよそのモデルで生活し、その上に座標を投影する必要があります。このために通常使用されるモデルは、 WGS 84 です。これは、GPSデバイスがまったく同じ問題を解決するために通常使用するものです。

NOAAには、これを支援するためにダウンロードできるソフトウェアがいくつかあります Webサイト上

8
T.E.D.

これを容易にする多くのツールがあります。関係するものの詳細については、 monjardin's answer を参照してください。

ただし、これを行うことは必ずしも難しくありません。 Javaを使用しているようですが、 GDAL のようなものを調べることをお勧めします。ルーチンにJavaラッパーを提供し、Lat/Lon(地理座標)からUTM(投影座標系)またはその他の妥当な地図投影に変換するために必要なすべてのツールを備えています。

UTMは、メーターであるため操作が簡単なので、素晴らしいです。ただし、適切な処理を行うには、適切な TMゾーン を取得する必要があります。緯度/経度のペアに適切なゾーンを見つけるために、グーグル経由で利用できるいくつかの簡単なコードがあります。

7
Reed Copsey

念のため、Rバージョンの b-h-の関数 を示します。

measure <- function(lon1,lat1,lon2,lat2) {
    R <- 6378.137                                # radius of earth in Km
    dLat <- (lat2-lat1)*pi/180
    dLon <- (lon2-lon1)*pi/180
    a <- sin((dLat/2))^2 + cos(lat1*pi/180)*cos(lat2*pi/180)*(sin(dLon/2))^2
    c <- 2 * atan2(sqrt(a), sqrt(1-a))
    d <- R * c
    return (d * 1000)                            # distance in meters
}
5
Rodrigo

地球の退行の平均距離に基づいています。

1°= 111km;

これをラジアンに変換し、メートルに分割すると、RADのマジックナンバーがメートルで表示されます。0.000008998719243599958;

その後:

const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
2
Jaykon

これを計算する方法はかなりあります。それらのすべては、半径が地球のものである球面三角法の近似を使用します。

http://www.movable-type.co.uk/scripts/latlong.html を試して、さまざまな言語のメソッドとコードを少し見つけてください。

2
rcaval

1海里(1852メートル)は、赤道で1 arcminute 経度として定義されます。ただし、変換が実際に意味をなすように作業している mapprojectionUTM も参照)を定義する必要があります。

2
Judge Maygarden
    'below is from
'http://www.zipcodeworld.com/samples/distance.vbnet.html
Public Function distance(ByVal lat1 As Double, ByVal lon1 As Double, _
                         ByVal lat2 As Double, ByVal lon2 As Double, _
                         Optional ByVal unit As Char = "M"c) As Double
    Dim theta As Double = lon1 - lon2
    Dim dist As Double = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + _
                            Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * _
                            Math.Cos(deg2rad(theta))
    dist = Math.Acos(dist)
    dist = rad2deg(dist)
    dist = dist * 60 * 1.1515
    If unit = "K" Then
        dist = dist * 1.609344
    ElseIf unit = "N" Then
        dist = dist * 0.8684
    End If
    Return dist
End Function
Public Function Haversine(ByVal lat1 As Double, ByVal lon1 As Double, _
                         ByVal lat2 As Double, ByVal lon2 As Double, _
                         Optional ByVal unit As Char = "M"c) As Double
    Dim R As Double = 6371 'earth radius in km
    Dim dLat As Double
    Dim dLon As Double
    Dim a As Double
    Dim c As Double
    Dim d As Double
    dLat = deg2rad(lat2 - lat1)
    dLon = deg2rad((lon2 - lon1))
    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)
    c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a))
    d = R * c
    Select Case unit.ToString.ToUpper
        Case "M"c
            d = d * 0.62137119
        Case "N"c
            d = d * 0.5399568
    End Select
    Return d
End Function
Private Function deg2rad(ByVal deg As Double) As Double
    Return (deg * Math.PI / 180.0)
End Function
Private Function rad2deg(ByVal rad As Double) As Double
    Return rad / Math.PI * 180.0
End Function
1
dbasnett

緯度と経度をxおよびy表現に変換するには、使用するマップ投影のタイプを決定する必要があります。私にとっては、楕円形メルカトル図法は非常に良いようです。 ここ 実装を見つけることができます(Javaでも)。

1
Megamozg

十分に近い場合、それらを平面上の座標として扱うことで逃げることができます。これは、完全な精度が要求されず、任意の制限と比較するために必要な距離の大まかな推測だけである場合、たとえば、通りまたは都市レベルで機能します。

0
Bart