Що ти маєш знати про географічні координати
May 17, 2012 , revised July 15, 2022 in General programmingСтисла шпаргалка для програмістів.
-
Широта, Latitude,
lat
- збільшується з півдня (South, S) на північ (North, N). -
Довгота, Longitude,
lng
- збільшується с заходу (West, W) на схід (East, E). -
Практично завжди координати записуються в порядку “широта, довгота” - Lat, Lng. У Google Maps, у Вікіпедії, і т.д. На відміну від математики, в географії спочатку йде Y, потім X.
-
І широта, і довгота вимірюються в градусах. Градус можна розуміти як геометричний градус, тобто 1/360 земного кола. Інколи їх записують у вигляді дробового числа, з яким все зрозуміло: 12.3456; інколи - у “часовому” вигляді: 12°34'56" - 12 градусів, 34 хвилини, 56 секунд. Такий запис легко перевести у дріб:
deg + min/60.0 + sec/3600.0
-
Довгота приймає значення від -180 до +180; нуль - початковий мерідіан, що проходить через Гринвіч, від’ємні значення - західна півкуля, додатні - східна.
-
Широта приймає значення від -90 до +90. Нуль - екватор, від’ємні значення - південна півкуля, додатні - північна.
-
Довжина одного градусу довготи не є сталою, а залежить від широти, оскільки довгота відкладається по колу, що паралельно до екватора, а довжина цього кола зменшується з наближенням до того чи іншого полюсу. Рахуй довжину градуса довготи за формулою:
def lng_2_km(lat) EARTH_RADIUS*(Math::PI/180)*cos(lat*Math::PI/180) # EARTH_RADIUS = 6371 end
-
Довжина одного градусу широти є майже сталою і дорівнює 111 км.
-
Довжина земного кола (тобто фізичний розмір координатної сітки) дорівнює приблизно 4*10⁸ м. В базовому типі числа з рухомою комою вміщується сім розрядів точності. Це значить, що в змінну або стовпчик типу
single/float
влізуть координати з точністю біля 10 м. А це значить, що для зберігання географічних координат краще використати тип DOUBLE. -
Відстань між двома координатами не можна рахувати за формулою Євклида (
sqrt(x*x+y*y)
), оскільки ця відстань вимірюється на сфері, а не на площині (до речі, саме тому літаки на далекі відстані літають по “кривій” траєкторії - ця крива це проєкція “прямої” дуги). Відстань рахуємо за великим колом. -
Хоча, якщо все, що тобі потрібно - це “знайти довколишні місця”, як це роблять численні додатки, то не потрібно ані тригонометрії, ані географичічних доповнень до бази даних - для довколишніх крапок цілком достатньо Євклидової відстані.
-
А якщо ще спростити нашу модель, то можна взагалі шукати об’єкти, обмежені окремо за кожною з координат:
WHERE lat BETWEEN lat1 AND lat 2 AND lng BETWEEN lng1 AND lng2
. Особливо якщо результати показувати будеш на прямокутній карті (тобто поле зору буде прямокутне). Алгоритм такий:def nearest(lat, lng, radius) lat2km = LAT_DEGREE_KM # 111 lng2km = lng_2_km(lat) # lat2km*dlat = lng2km*dlng = lateral_distance_km # 2*lateral_distance_km^2 = radius^2 # lateral_distance_km = radius / sqrt(2) dlat = radius / (lat2km * Math.sqrt(2)) dlng = radius / (lng2km * Math.sqrt(2)) where(:lat => (lat-dlat)..(lat+dlat), :lng => (lng-dlng)..(lng+dlng)) end
Такі критерії можна легко віддати сервісу повнотекстового пошуку, наприклад, Sphinx Search - саме так працював пошук на моєму колишньому порталі нерухомості Дніпра - Rentfeed.
-
🇺🇦 І, нарешті, координати Дніпра - 48 градусів північної широти, 35 градусів східної довготи.
Liked the post? Treat me to a coffee