web-dev-qa-db-ja.com

2つのジオポイント間の距離を取得する

ユーザーがいる最も近い場所をチェックするアプリを作りたいです。ユーザーの位置を簡単に取得でき、緯度と経度の場所のリストが既にあります。

現在のユーザーの場所に対してリストの最も近い場所を知る最良の方法は何でしょうか。

Google APIには何も見つかりませんでした。

106
Location loc1 = new Location("");
loc1.setLatitude(lat1);
loc1.setLongitude(lon1);

Location loc2 = new Location("");
loc2.setLatitude(lat2);
loc2.setLongitude(lon2);

float distanceInMeters = loc1.distanceTo(loc2);

リファレンス: http://developer.Android.com/reference/Android/location/Location.html#distanceTo(Android.location.Location)

151
praveen

http://developer.Android.com/reference/Android/location/Location.html

DistanceToまたはdistanceBetweenを調べます。緯度と経度からLocationオブジェクトを作成できます。

Location location = new Location("");
location.setLatitude(lat);
location.setLongitude(lon);
122
haseman

近似解(正距円筒図法に基づく)、はるかに高速(1つのトリガと1つの平方根のみが必要です)。

この近似は、ポイントがそれほど離れていない場合に関係します。 常に過大評価実際のヘイバーシン距離と比較されます。たとえば、2つのポイント間のデルタ緯度または経度が実際の距離に.05382%以下を追加します小数点以下4度を超えない

標準式(Haversine)はexact one(つまり、地球上の任意の経度/緯度で機能します)ですが、much sloweであり、7つの三角関数と2平方根。いくつかの点が離れすぎておらず、絶対精度が最重要ではない場合は、この近似バージョン(Equirectangular)を使用できます。これは、三角関数と平方根を1つだけ使用するため、はるかに高速です。

// Approximate Equirectangular -- works if (lat1,lon1) ~ (lat2,lon2)
int R = 6371; // km
double x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2);
double y = (lat2 - lat1);
double distance = Math.sqrt(x * x + y * y) * R;

次のいずれかの方法でこれをさらに最適化できます。

  1. 距離の平方根の削除単に距離を別の距離と比較する場合(その場合は、両方の距離を比較します);
  2. コサインの因数分解 1つのマスターポイントから他の多くのポイントまでの距離を計算する場合(その場合、マスターポイントを中心とした正距円筒図法を実行するため、すべての比較に対してコサインを1回計算できます) 。

詳細については、以下を参照してください: http://www.movable-type.co.uk/scripts/latlong.html

いくつかの言語でHaversine式のニース参照実装があります: http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe

30

使用できる方法はいくつかありますが、どれが最適かを判断するには、まずユーザーの高度と他のポイントの高度を認識しているかどうかを知る必要がありますか?

求めている精度のレベルに応じて、HaversineまたはVincentyのいずれかの式を調べることができます。

これらのページでは、数式の詳細を説明します。数学的にそれほど傾いていない人のために、それらをスクリプトに実装する方法についても説明しています。

Haversine Formula: http://www.movable-type.co.uk/scripts/latlong.html

ビンセント式: http://www.movable-type.co.uk/scripts/latlong-vincenty.html

式の意味のいずれかに問題がある場合は、コメントしてください。私はそれらに答えるために最善を尽くします:)

11
Dwaine Bailey

LatLng間の距離を取得するには2つの方法があります。

public static void distanceBetween (double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)

こちらを参照

そして第二

public float distanceTo (Location dest) praveenの回答通り。

4
Xar E Ahmer
private float getDistance(double lat1, double lon1, double lat2, double lon2) {
        float[] distance = new float[2];
        Location.distanceBetween(lat1, lon1, lat2, lon2, distance);
        return distance[0];
    }
3
Levon Petrosyan

次の方法を使用して、緯度と経度を渡し、メートル単位で距離を取得します。

private static double distance_in_meter(final double lat1, final double lon1, final double lat2, final double lon2) {
    double R = 6371000f; // Radius of the earth in m
    double dLat = (lat1 - lat2) * Math.PI / 180f;
    double dLon = (lon1 - lon2) * Math.PI / 180f;
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.cos(latlong1.latitude * Math.PI / 180f) * Math.cos(latlong2.latitude * Math.PI / 180f) *
                    Math.sin(dLon/2) * Math.sin(dLon/2);
    double c = 2f * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double d = R * c;
    return d;
}
1
farhad.kargaran

google Map APIを使用して距離と時間を取得できます Google Map API

ダウンロードしたJSONをこのメソッドに渡すだけで、2つの緯度経度間のリアルタイムの距離と時間を取得できます。

void parseJSONForDurationAndKMS(String json) throws JSONException {

    Log.d(TAG, "called parseJSONForDurationAndKMS");
    JSONObject jsonObject = new JSONObject(json);
    String distance;
    String duration;
    distance = jsonObject.getJSONArray("routes").getJSONObject(0).getJSONArray("legs").getJSONObject(0).getJSONObject("distance").getString("text");
    duration = jsonObject.getJSONArray("routes").getJSONObject(0).getJSONArray("legs").getJSONObject(0).getJSONObject("duration").getString("text");

    Log.d(TAG, "distance : " + distance);
    Log.d(TAG, "duration : " + duration);

    distanceBWLats.setText("Distance : " + distance + "\n" + "Duration : " + duration);


}
0
saigopi