157

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

編集:私がやりたいことは簡単にはできないようですが、私が本当にやりたいことは次のとおりです。

ウェイポイントの緯度と経度があり、ユーザーの緯度と経度があるとします。それらを比較して、ウェイポイントからかなり近い距離にいることをいつユーザーに伝えるかを決定する簡単な方法はありますか? 合理的であることが主題であることは理解していますが、これは簡単に実行できますか、それとも過度に数学的ですか?

4

16 に答える 16

213

ここに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 点間の大圏距離を決定します。

于 2012-06-23T20:20:08.947 に答える
85

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

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

経度 1°の長さ = 40075 km * cos(緯度) / 360

于 2016-09-16T21:29:20.653 に答える
35

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) );

ウィキペディアのエントリには、距離の計算は経度 100 km で 0.6 m 以内、緯度 100 km で 1 cm 以内であると記載されています。

于 2013-10-14T08:46:12.107 に答える
7

これを簡単にする多くのツールがあります。関係する内容の詳細については、monjardin の回答を参照してください。

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

UTM はメートル単位なので操作が簡単です。ただし、うまく機能させるには、適切なUTM ゾーンを取得する必要があります。緯度と経度のペアに適したゾーンを見つけるために、グーグル経由で利用できるいくつかの簡単なコードがあります。

于 2009-03-12T17:59:40.483 に答える
7

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

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

于 2009-03-12T18:59:45.787 に答える
2

1海里(1852メートル)は、赤道での経度の1分角として定義されます。ただし、変換を実際に意味のあるものにするために作業している地図投影法UTMも参照)を定義する必要があります。

于 2009-03-12T17:42:37.733 に答える
2

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

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

于 2009-03-12T18:34:02.087 に答える
1
    '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
于 2009-03-12T18:01:44.800 に答える
1

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

于 2013-03-02T06:12:09.917 に答える
0

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

于 2010-04-16T10:11:14.910 に答える
-1

地球の度数の平均距離に基づいています。

1° = 111km;

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

それから:

const RAD = 0.000008998719243599958;
Math.sqrt(Math.pow(lat1 - lat2, 2) + Math.pow(long1 - long2, 2)) / RAD;
于 2013-08-28T14:34:00.000 に答える
-2

球面ジオメトリを行うには、座標をラジアンに変換する必要があります。変換したら、2 点間の距離を計算できます。その後、距離は任意の単位に変換できます。

于 2010-03-24T11:20:17.810 に答える