Рассчитать расстояние между двумя GeoLocation

Я пытаюсь рассчитать расстояние между двумя географическими точками. У меня проблема в следующем: я пытался с библиотеками, такими как: формулы Geocalc и Haversine, например:

public static final double RKilometers = 6371;

public static double calculationByDistance(double lat1, double lon1, double lat2, double lon2) {
    double dLat = Math.toRadians(lat2 - lat1);
    double dLon = Math.toRadians(lon2 - lon1);
    lat1 = Math.toRadians(lat1);
    lat2 = Math.toRadians(lat2);

    double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
    double c = 2 * Math.asin(Math.sqrt(a));
    return RKilometers * c;
}

Но я получаю одинаковые неправильные значения со всеми этими опциями. Для коротких расстояний это работает отлично, но для больших расстояний это не так.

Это тест, который я сделал:

//distance between Barrow Island(Australia) and Tavatave(Madagascar)
assertEquals(calculationByDistance(20.82, 115.4, 18.15, 49.4), 6885, 20);
//get 6875.965169284442

//here is the problem
//distance between Rio Grande and Glasgow
assertEquals(calculationByDistance(32.05, 52.11, 55.83, 4.25), 10744, 20);
//get 4522.502442756569

Кто-нибудь знает, где моя ошибка? Спасибо!

4 ответа

Решение

Я нашел ошибку. Проблема заключалась в том, что значения для широты и долготы были неправильными. Я взял данные от Wolframalpha, и они не показывают знаки для значений. Значения прав для моего теста:

assertEquals(calculationByDistance(-32.05, 52.11, 55.83, -4.25), 10744, 20); 

Спасибо за потраченное время!!! И извините за глупую ошибку:)

У меня был этот код давным-давно, я даже не помню, написал ли я его сам или получил от кого-то. Насколько я помню, это дает довольно хорошую оценку, вы можете попробовать и посмотреть, работает ли она для вас. (правки приветствуются)

public static double distFrom(double lat1, double lng1, double lat2, double lng2) {
        double earthRadius = 3958.75;  //this is in miles I believe
        double dLat = Math.toRadians(lat2-lat1);
        double dLng = Math.toRadians(lng2-lng1);
        double sindLat = Math.sin(dLat / 2);
        double sindLng = Math.sin(dLng / 2);
        double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2)
                * Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2));
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
        double dist = earthRadius * c;

        return dist;
}
public static float distFrom(float lat1, float lng1, float lat2, float lng2) 
{
    // Earth Radius in meters

    double earthRadius = 6371000; 
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2-lng1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
               Math.cos(Math.toRadians(lat1)) *
               Math.cos(Math.toRadians(lat2)) *
               Math.sin(dLng/2) * Math.sin(dLng/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    float dist = (float) (earthRadius * c);

    System.out.println("Distance is : " + dist);
    return dist; // distance in meters
}

Трудно предложить вам какой-либо фрагмент кода или существующие инструменты и сервисы. Просто потому, что расчет расстояния зависит от конкретной задачи. Существует много видов картографических проекций и соответствующих формул.

Например, если вы используете карты Google, вы, вероятно, можете сделать более точный расчет с учетом различий в высоте. OpenStreetMap, например, не предоставляет (по крайней мере пару лет назад) никакой информации о высоте, поэтому ваша точность может варьироваться (сравните точность, достигнутую с помощью OpenStreetMap для "плоского" города в Восточной Европе и Сан-Франциско, например).

Я удовлетворен https://code.google.com/p/simplelatlng/. Это действительно просто и избавляет вас от написания стандартного кода.

Для больших расстояний определенные веб-сервисы могут работать хорошо (особенно когда сервис агрегирует данные из нескольких других сервисов).

Другие вопросы по тегам