Получить расстояние между двумя географическими точками - PullRequest
106 голосов
/ 30 апреля 2010

Я хочу создать приложение, которое проверяет ближайшее место, где находится пользователь. Я легко могу узнать местоположение пользователя, и у меня уже есть список мест с широтой и долготой.

Какой самый лучший способ узнать ближайшее место списка относительно текущего местоположения пользователя.

Я не смог найти ничего в API Google.

Ответы [ 8 ]

149 голосов
/ 16 декабря 2013
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)

122 голосов
/ 30 апреля 2010

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

Посмотрите на расстояние или расстояние между. Вы можете создать объект Location из широты и долготы:

Location location = new Location("");
location.setLatitude(lat);
location.setLongitude(lon);
30 голосов
/ 02 декабря 2010

Приближенное решение (на основе равносторонней проекции), намного быстрее (для этого требуется только 1 триг и 1 квадратный корень).

Это приближение уместно, если ваши точки не слишком далеко друг от друга. Он будет всегда переоценивать по сравнению с реальным расстоянием хаверсин. Например, он добавит не более 0,05382% к реальному расстоянию, если разность широты или долготы между вашими двумя точками не превышает 4 десятичных градуса .

Стандартная формула (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. Вычисление косинуса , если вы вычисляете расстояние от одной мастер-точки до многих других (в этом случае вы делаете равностороннюю проекцию с центром в мастер-точке, так что вы можете вычислить косинус один раз для всех сравнения).

Для получения дополнительной информации см .: http://www.movable -type.co.uk / scripts / latlong.html

Хорошая справочная реализация формулы Хаверсайна на нескольких языках: http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe

11 голосов
/ 30 апреля 2010

Есть несколько методов, которые вы могли бы использовать, но чтобы определить, какой из них лучше, нам сначала нужно узнать, знаете ли вы высоту пользователя, а также высоту других точек?

В зависимости от уровня точности, к которому вы стремитесь, вы можете изучить формулы Хаверсайна или Винсенти ...

На этих страницах подробно изложены формулы, а для менее математически склонных также дается объяснение того, как реализовать их в сценарии!

Формула Haversine: http://www.movable -type.co.uk / scripts / latlong.html

Формула Винсенти: http://www.movable -type.co.uk / scripts / latlong-vincenty.html

Если у вас возникли проблемы с каким-либо из значений в формулах, просто прокомментируйте, и я сделаю все возможное, чтобы ответить на них:)

4 голосов
/ 01 августа 2015

Есть два способа получить расстояние между LatLng.

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

Смотрите это

и второй

public float distanceTo (Location dest) в ответ на правин.

2 голосов
/ 25 февраля 2018
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];
    }
0 голосов
/ 02 августа 2018

Вы можете узнать расстояние и время, используя Google Map API API Google Map

просто передайте скачанный JSON этому методу, вы получите в реальном времени расстояние и время между двумя латлонгами

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 голосов
/ 09 сентября 2016

Просто используйте следующий метод, передайте его 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...