Как метод distanceTo() класса Location работает внутри?
Я пытался использовать distanceTo()
между двумя Location
объекты, но AFAIK не возвращает правильные значения во всех ситуациях. Вместо этого я написал собственный метод, который возвращает правильные значения.
float distanceBetween(Location l1, Location l2)
{
float lat1= (float)l1.getLatitude();
float lon1=(float)l1.getLongitude();
float lat2=(float)l2.getLatitude();
float lon2=(float)l2.getLongitude();
float R = 6371; // km
float dLat = (float)((lat2-lat1)*Math.PI/180);
float dLon = (float)((lon2-lon1)*Math.PI/180);
lat1 = (float)(lat1*Math.PI/180);
lat2 = (float)(lat2*Math.PI/180);
float a = (float)(Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2));
float c = (float)(2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)));
float d = R * c * 1000;
return d;
}
Может ли кто-нибудь сказать мне, в чем разница между моей реализацией и что distanceTo()
возвращается?
2 ответа
Я уверен, что Location.distanceTo()
правильно разработан. Он использует подход WGS84, который является очень точным и точным. Я недавно использовал Location.distanceTo()
для ряда тестовых случаев, и это никогда не было неправильно.
Вы не объяснили, почему вы думаете, что метод не работает должным образом. Возможно, вы получаете неправильные значения, потому что вы не установили правильные значения широты и долготы для Location
объект. Кроме того, вы можете настроить исходный код Android в вашей IDE и проверить метод самостоятельно. Это абсолютно правильно.
РЕДАКТИРОВАТЬ:
На той ссылке, которую вы разместили, есть ответ, который кратко резюмирует проблему:
distanceTo()
работает правильно. Ошибка на вашей стороне, наиболее вероятная алгоритмическая, например, если нет доступного GPS-решения, и телефон занимает местоположение на основе соты GSM, это, конечно, может быть отключено на 1000 м.Для вашего приложения, которое, вероятно, хочет подвести итог пройденного расстояния, используйте только GPS-исправления, не используйте другого LocationProvider, чем GPS!
Поэтому мораль этой истории - убедиться, что вы используете только GPS-провайдера для расчета расстояния.
РЕДАКТИРОВАТЬ 2:
Google рекомендует использовать API определения местоположения сервисов Google Play через android.location
API. Новый API должен быть более точным.
Рекомендации:
Как объяснено выше со ссылкой на старый ответ от меня, distanceTo() работает правильно. Я понимаю преимущество для самостоятельно реализованного метода distanceTo. Это делает ваш код независимым от библиотек, лучше переносимым и всегда дает одинаковое расстояние на разных платформах. (например, при использовании тестовых случаев)
Но тогда я рекомендовал использовать другую формулу:
В вашем коде радиус Земли недостаточно точен, вы должны взять радиус Земли WGS84 (в метрах), то есть радиус Земли, который GPS-приемник использует в своей модели Земли. Вы легко можете найти радиус Земли WGS84 с помощью поиска в Интернете.
Тогда вам следует воспользоваться формулой haversine: известно, что она хорошо работает и на небольших расстояниях.