获取两个地理点之间的距离

时间:2010-04-29 23:30:12

标签: android geolocation maps

我想创建一个应用程序来检查用户所在的最近的位置。我可以很容易地获得用户的位置,我已经有了纬度和经度的地方列表。

知道列表最近的位置与当前用户位置的最佳方法是什么。

我在google API中找不到任何内容。

9 个答案:

答案 0 :(得分:147)

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)

答案 1 :(得分:121)

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

查看distanceTo或distanceBetween。您可以从纬度和经度创建位置对象:

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

答案 2 :(得分:30)

近似解(基于equirectangular投影),快得多(它只需要1个trig和1个平方根)。

如果您的点数相距太远,则此近似值是相关的。与实际的半径距离相比,总是高估。例如,如果两个点之间的差异纬度或经度不超过4个十进制度,它会将不超过0.05382%添加到实际距离。

标准公式(Haversine)是精确一个(也就是说,它适用于地球上任何一个经度/纬度)但是慢得多因为它需要7个三角和2个平方根。如果你的几个点不是太远,并且绝对精度不是最重要的,你可以使用这个近似版本(Equirectangular),因为它只使用一个三角函数和一个平方根,速度要快得多。

// 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. 分解余弦如果计算从一个主点到许多其他点的距离(在这种情况下,你会以主点为中心进行等距矩形投影,这样你就可以计算一次余弦所有比较)。
  3. 有关详细信息,请参阅:http://www.movable-type.co.uk/scripts/latlong.html

    在以下几种语言中,Haversine公式有一个很好的参考实现:http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe

答案 3 :(得分:11)

您可以使用几种方法,但要确定哪种方法最好,我们首先需要知道您是否知道用户的海拔高度以及其他点的海拔高度?

根据您所追求的准确程度,您可以查看Haversine或Vincenty公式......

这些页面详细说明了公式,并且对于数学上较不倾向的公式,还提供了如何在脚本中实现它们的说明!

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

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

如果您对公式中的任何含义有任何疑问,请发表评论,我会尽力回答:)

答案 4 :(得分:4)

有两种方法可以在LatLng之间找到距离。

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

See this

和第二

public float distanceTo (Location dest)由praveen回答。

答案 5 :(得分:2)

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];
    }

答案 6 :(得分:1)

a =sin²(Δφ/ 2)+ cosφ1⋅cosφ2⋅sin²(Δλ/ 2)

c = 2⋅atan2(√a,√(1-a))

距离= R⋅c

其中φ是纬度,λ是经度,R是地球半径(平均半径= 6,371km);

请注意,角度必须以弧度为单位才能传递给三角函数!

fun distanceInMeter(firstLocation: Location, secondLocation: Location): Double {
    val earthRadius = 6371000.0
    val deltaLatitudeDegree = (firstLocation.latitude - secondLocation.latitude) * Math.PI / 180f
    val deltaLongitudeDegree = (firstLocation.longitude - secondLocation.longitude) * Math.PI / 180f
    val a = sin(deltaLatitudeDegree / 2).pow(2) +
            cos(firstLocation.latitude * Math.PI / 180f) * cos(secondLocation.latitude * Math.PI / 180f) *
            sin(deltaLongitudeDegree / 2).pow(2)
    val c = 2f * atan2(sqrt(a), sqrt(1 - a))
    return earthRadius * c
}


data class Location(val latitude: Double, val longitude: Double)

答案 7 :(得分:0)

只需使用以下方法,将其传递给lat和long并以米为单位:

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

答案 8 :(得分:0)

您可以使用Google Map API获取距离和时间 Google Map API

只需将下载的JSON传递给此方法,您将获得两个latlong的实时距离和时间

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


}