средняя точка между двумя широтой и долготой - PullRequest
25 голосов
/ 11 января 2011

Я пытаюсь преобразовать фрагмент кода, указанный в этом http://www.movable -type.co.uk / scripts / latlong.html , в java. Но я не получаю тот же результат, что и на сайте. Вот мой код, чтобы найти среднюю точку между двумя точками, где даны их широта и долгота

midPoint(12.870672,77.658964,12.974831,77.60935);
    public static void midPoint(double lat1,double lon1,double lat2,double lon2)
    {
   double dLon = Math.toRadians(lon2-lon1);
        double Bx = Math.cos(lat2) * Math.cos(dLon);
        double By = Math.cos(lat2) * Math.sin(dLon);
        double lat3 = Math.atan2(Math.sin(lat1)+Math.sin(lat2),Math.sqrt( (Math.cos(lat1)+Bx)*(Math.cos(lat1)+Bx) + By*By) );
        double lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);
        System.out.print(lat3 +" " + lon3 );
    }

Я не уверен, правильно ли ДЛон или нет. Поэтому, пожалуйста, помогите мне, ребята, понять это. P.S. Мне нужно найти широту и долготу средней точки

Ответы [ 5 ]

66 голосов
/ 11 января 2011

Вам необходимо пересчитать в радианы.Измените его на следующее:

public static void midPoint(double lat1,double lon1,double lat2,double lon2){

    double dLon = Math.toRadians(lon2 - lon1);

    //convert to radians
    lat1 = Math.toRadians(lat1);
    lat2 = Math.toRadians(lat2);
    lon1 = Math.toRadians(lon1);

    double Bx = Math.cos(lat2) * Math.cos(dLon);
    double By = Math.cos(lat2) * Math.sin(dLon);
    double lat3 = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By));
    double lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);

    //print out in degrees
    System.out.println(Math.toDegrees(lat3) + " " + Math.toDegrees(lon3));
}
12 голосов
/ 24 августа 2017

Еще проще с Утилитами Google Maps для Android :

LatLngBounds bounds = new LatLngBounds(start, dest);
bounds.getCenter();

Обновление: Лучше использовать конструктор (почему см. Плохой ответ проигравшего ):

LatLngBounds.builder().include(start).include(dest).build().getCenter();
2 голосов
/ 06 сентября 2018

Пожалуйста, используйте LatLngBounds с конструктором , а не конструктором , если вы хотите правильно обработать нарушение антимеридиана (долгота +/- 180).

Вот тест, иллюстрирующий проблему:

LatLng mp = midPoint(new LatLng(-43.95139,-176.56111),new LatLng(-36.397816,174.663496));
public static LatLng midPoint (LatLng SW, LatLng NE) {
    LatLngBounds bounds = new LatLngBounds(SW, NE);
    Log.d("BAD!", bounds.toString() + " CENTRE: " + bounds.getCenter().toString());
    bounds = LatLngBounds.builder().include(SW).include(NE).build();
    Log.d("GOOD", bounds.toString() + " CENTRE: " + bounds.getCenter().toString());
    return bounds.getCenter();
}

Фактические результаты:

BAD!: LatLngBounds{southwest=lat/lng: (-43.95139,-176.56111), northeast=lat/lng: (-36.397816,174.663496)} CENTRE: lat/lng: (-40.174603,-0.948807)
GOOD: LatLngBounds{southwest=lat/lng: (-43.95139,174.663496), northeast=lat/lng: (-36.397816,-176.56111)} CENTRE: lat/lng: (-40.174603,179.051193)

Конструктор позволяет получить центральную долготу на 180 градусов!

1 голос
/ 11 января 2011

Вам необходимо также преобразовать значения широт и долгот, используемые в других формулах, в радианы. Вы можете увидеть это в коде ~ 3/5 пути вниз по странице. Подсказка была дана в конце сферического закона формулы косинуса расстояния:

(Обратите внимание, что здесь и во всех последующих фрагментах кода для простоты я не показываю преобразования из градусов в радианы; полные версии приведены ниже).

0 голосов
/ 11 января 2011

Моя последняя работа - создание модуля отслеживания и использование этой формулы для вычисления расстояния между двумя координатами.

//Location lat and lon
double locLat = -23.548333;
double locLon = -46.636111;

//Destination lat and lon
double dstLat = -22.902778;
double dstLon = -43.206667;

double arcoAB = 90 - (dstLat);
double arcoAC = 90 - (locLat);

double difLon = locLon - (dstLon);

double cosA = Math.cos(Math.toRadians(arcoAC)) * Math.cos(Math.toRadians(arcoAB)) + Math.sin(Math.toRadians(arcoAC)) * Math.sin(Math.toRadians(arcoAB)) * Math.cos(Math.toRadians(difLon));
double acosCosA = Math.toDegrees(Math.acos(cosA));

double raio = 2 * Math.PI * 6371;
double distance = (raio * acosCosA) / 360;

return distance; //Distance in KM, convert to anything else (miles, meters..) if you need..

Вы можете получить среднюю точку, разделив расстояние на 2.

Ах, эта другая формула тоже работает:

double dLat = Math.toRadians(dstLat - locLat);
double dLon = Math.toRadians(dstLon - locLon);

double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
           + Math.cos(Math.toRadians(locLat)) * Math.cos(Math.toRadians(dstLat))
           * Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = 6371 * c;

return d; //Distance in KM
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...