Простые расчеты для работы с широтой / долгом и расстоянием в км?

119

Могу ли я сделать простой расчет, который преобразует км в значение, которое я могу добавить к поплавку широты или долготы, чтобы вычислить ограничивающую рамку для поиска? Это не обязательно должно быть полностью точным.

Например: если бы мне дали широту / долготу для Лондона, Англия (51,5001524, -0,1262362), и я хотел бы вычислить, какой шир будет в 25 км к востоку / западу от этой точки, и какой долг будет в 25 км к северу / югу от этой точки. точка, что мне нужно сделать, чтобы преобразовать 25 км в десятичное число, чтобы добавить к значениям выше?

Я ищу общее практическое правило, например: 1 км == +/- 0.XXX

Редактировать:

Мой первоначальный поиск по запросу "lat lon" не дал такого результата:

Как рассчитать ограничивающую рамку для заданного местоположения широты / долготы?

Принятый ответ мне кажется адекватным.

Филлип Б. Олдхэм
источник

Ответы:

221

Примерные преобразования:

  • Широта: 1 градус = 110,574 км
  • Долгота: 1 градус = 111,320 * cos (широта) км

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

Источник: http://en.wikipedia.org/wiki/Latitude

Внимание : имейте в виду, что координаты широты и долготы выражаются в градусах, в то время как cosфункция на большинстве (всех?) Языках обычно принимает радианы, поэтому необходимо преобразование градуса в радианы .

Джим Льюис
источник
Вы имеете в виду cos (долготу) во второй формуле?
Odys
1
Как вы к этому пришли? Я что-то упускаю, не могли бы вы уточнить расчет долготы? Ty
Odys
5
@Odys: Если вы сравниваете две точки, которые лежат на одной линии долготы (север / юг), они лежат на большом круге, а коэффициент преобразования - это просто полярная окружность Земли, разделенная на 360 градусов. Но для измерений восток-запад все по-другому, потому что (за исключением экватора) вы измеряете не по «большому кругу», поэтому «окружность» на заданной широте меньше. А поправочный коэффициент оказывается косинусом широты.
Джим Льюис
17
Мое объяснение: cos(0°) = 1=> Следовательно, при вычислении на экваторе поправочный коэффициент не применяется. Долготы там самые широкие. cos(90°) = 0=> На полюсах долготы сходятся в одной точке. Расстояние для расчета не существует.
Дженни О'Рейли
4
@Stijn: вам нужно преобразовать градусы в радианы перед вызовом Math.cos ().
Джим Льюис,
5

Если вы используете Java, Javascript или PHP, то есть библиотека, которая точно выполнит эти вычисления, используя забавно сложную (но все же быструю) тригонометрию:

http://www.jstott.me.uk/jcoord/

skaffman
источник
На сайте появилась библиотека.
midfield99
2
Ссылка не работает!
chatzich
Для PHP вы можете использовать эту вилку: github.com/dvdoug/PHPCoord
dearsina
1

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);
Нихил Динеш
источник
1

Интересно, что упоминания о координатах UTM я не увидел.

https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system .

По крайней мере, если вы хотите добавить км в ту же зону, это должно быть просто (в Python: https://pypi.org/project/utm/ )

utm.from_latlon и utm.to_latlon.

Мирча
источник
Спасибо за ссылку на utm. Шокирует то, что у него вообще нет документации.
Westworld
1

Спасибо Джиму Льюису за отличный ответ, и я хотел бы проиллюстрировать это решение своей функцией в 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))
Серж Культенко
источник
Я думаю, это должно быть "лат * пи / 180"
magamig
1

Почему бы не использовать правильно сформулированные геопространственные запросы ???

Вот справочная страница SQL-сервера на геопространственной функции STContains:

https://docs.microsoft.com/en-us/sql/t-sql/spatial-geography/stcontains-geography-data-type?view=sql-server-ver15

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

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

Аналогичные функции должны быть практически для любой базы данных.

Если вы правильно реализовали геопространственное индексирование, ваш поиск будет намного быстрее, чем используемый вами подход.

Георгий Карадов
источник
1
Найдите минутку, чтобы прочитать справку по редактированию в Справочном центре . Форматирование на Stack Overflow отличается от других сайтов.
Дхарман