Ответ 1
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);
Я хочу сделать приложения, которые проверяют, какое ближайшее место находится от пользователя. Я могу легко получить местоположение пользователя, и у меня есть список мест с широтой и долготой.
Что было бы лучшим способом узнать ближайшее место списка против текущей позиции.
Я не нашел ничего в API Google.
Я беспокоюсь, что мне нужно прибегнуть к моему вычислению и сделать математику, чтобы вычислить ее.
Что вы, ребята, думаете?
Приветствия и благодарности за чтение или ответ.
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 или distanceBetween. Вы можете создать объект Location из широты и долготы:
Location location = new Location("");
location.setLatitude(lat);
location.setLongitude(lon);
Аппроксимированное решение (основанное на равноугольной проекции), намного быстрее (для этого требуется только 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;
Вы можете оптимизировать следующий:
Подробнее см.: http://www.movable-type.co.uk/scripts/latlong.html
Существует хорошая ссылочная реализация формулы Хаверсина на нескольких языках по адресу: http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe
Есть несколько способов, которые вы могли бы использовать, но чтобы определить, какой из них лучше всего нам нужно знать, если вы знаете о высоте пользователя, а также о высоте других точек?
В зависимости от уровня точности, который вам нужен, вы можете изучить формулы Хаверсина или Винченти...
Эти страницы подробно описывают формулы, а для менее математически наклонного также дают объяснение, как их реализовать в script!
Формула Хаверсина: http://www.movable-type.co.uk/scripts/latlong.html
Формула Vincenty: http://www.movable-type.co.uk/scripts/latlong-vincenty.html
Если у вас есть какие-либо проблемы с любым из значений в формулах, просто комментируйте, и я сделаю все возможное, чтобы ответить на них:)
Есть два способа получить расстояние между LatLng.
public static void distanceBetween (double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)
и второй
public float distanceTo (Location dest)
, как ответил praveen.
Просто используйте следующий метод, передайте его 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;
}