Простые расчеты для работы с широтой / долготой + км расстояния?
Есть ли простой расчет, который я могу сделать, который преобразует km в значение, которое я могу добавить к значению lat или lon, чтобы вычислить ограничивающую рамку для поиска? Это не должно быть полностью точным.
Например: если бы мне дали широту / долготу для Лондона, Англии (51.5001524, -0.1262362), и я хотел бы рассчитать, какой лат будет в 25 км к востоку / западу от этой точки, и какой лон будет в 25 км к северу / югу от этой точки. Точка, что мне нужно сделать, чтобы преобразовать 25 км в десятичную, чтобы добавить к значениям выше?
Я ищу общее правило, например: 1 км == +/- 0.XXX
Редактировать:
Мой первоначальный поиск "lat lon" не дал такого результата:
Как рассчитать ограничивающий прямоугольник для данного местоположения широты / долготы?
Принятый ответ кажется адекватным моим требованиям.
4 ответа
Примерные преобразования:
- Широта: 1 градус = 110,574 км
- Долгота: 1 градус = 111.320*cos(широта) км
Это не совсем корректно для полярного выравнивания Земли - для этого вам, вероятно, понадобится более сложная формула, использующая эталонный эллипсоид WGS84 (модель, используемая для GPS). Но ошибка, вероятно, незначительна для ваших целей.
Источник: http://en.wikipedia.org/wiki/Latitude
Предостережение. Помните, что координаты широтной длины выражены в градусах, а cos
функция в большинстве (всех?) языков обычно принимает радианы, поэтому необходимо преобразование степени в радианы.
Если вы используете Java, Javascript или PHP, то есть библиотека, которая будет точно выполнять эти вычисления, используя забавно сложную (но все же быструю) тригонометрию:
Спасибо Jim Lewis за отличный ответ, и я хотел бы проиллюстрировать это решение своей функцией в Swift:
func getRandomLocation(forLocation location: CLLocation, withOffsetKM offset: Double) -> CLLocation {
let latDistance = (Double(arc4random()) / Double(UInt32.max)) * offset * 2.0 - offset
let longDistanceMax = sqrt(offset * offset - latDistance * latDistance)
let longDistance = (Double(arc4random()) / Double(UInt32.max)) * longDistanceMax * 2.0 - longDistanceMax
let lat: CLLocationDegrees = location.coordinate.latitude + latDistance / 110.574
let lng: CLLocationDegrees = location.coordinate.longitude + longDistance / (111.320 * cos(lat / .pi / 180))
return CLLocation(latitude: lat, longitude: lng)
}
В этой функции для преобразования расстояния я использую следующие формулы:
latDistance / 110.574
longDistance / (111.320 * cos(lat / .pi / 180))
http://www.jstott.me.uk/jcoord/ - используйте эту библиотеку
LatLng lld1 = new LatLng(40.718119, -73.995667);
LatLng lld2 = new LatLng(51.499981, -0.125313);
Double distance = lld1.distance(lld2);
Log.d(TAG, "Distance in kilometers " + distance);
Интересно, что я не увидел упоминания о координатах UTM.
https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system.
По крайней мере, если вы хотите добавить км в ту же зону, это должно быть просто (в Python: https://pypi.org/project/utm/)
utm.from_latlon и utm.to_latlon.
Почему бы не использовать правильно сформулированные геопространственные запросы???
Вот справочная страница SQL-сервера на геопространственной функции STContains:
или если вы не хотите использовать квадратное и радианное преобразование, вы всегда можете использовать функцию расстояния, чтобы найти нужные вам точки:
DECLARE @CurrentLocation geography;
SET @CurrentLocation = geography::Point(12.822222, 80.222222, 4326)
SELECT * , Round (GeoLocation.STDistance(@CurrentLocation ),0) AS Distance FROM [Landmark]
WHERE GeoLocation.STDistance(@CurrentLocation )<= 2000 -- 2 Km
Практически для любой базы данных должна быть аналогичная функциональность.
Если вы правильно внедрили геопространственную индексацию, ваш поиск будет намного быстрее, чем подход, который вы используете