Geopy.distance.distance: примеры (PYTHON)

Использование функции distance из библиотеки Geopy для расчета расстояний
Раздел: Геокодирование, Расстояния
geopy.distance.distance(*args: Any, **kwargs: Any): geopy.distance.Distance

Основная информация о функции

Функция geopy.distance.distance является центральным инструментом библиотеки Geopy для вычисления расстояний между географическими точками на поверхности Земли. Она используется в задачах геокодирования, логистики, анализа географических данных и построения карт.

Функция создает объект расстояния, который может быть рассчитан между двумя точками. Конструктор принимает аргументы для определения этих точек.

Аргументы:

  • coordinates: Может принимать несколько форматов:
    • Последовательность двух чисел (широта, долгота).
    • Два аргумента, каждый из которых может быть последовательностью (широта, долгота) или строкой, или объектом geopy.Point.
    • Объект geopy.distance.Distance (для копирования).
  • ellipsoid (необязательный): Строка с именем эллипсоида (например, 'WGS-84', 'GRS-80') или кортеж с двумя значениями (большая полуось, сжатие). По умолчанию 'WGS-84'. Определяет модель Земли для точных геодезических расчетов.

Возвращаемое значение:

Функция возвращает объект geopy.distance.Distance. Сам по себе этот объект не является числом. Чтобы получить числовое значение расстояния, необходимо вызвать один из его атрибутов, соответствующих единицам измерения (например, .km, .miles, .meters, .feet). Объект также поддерживает арифметические операции (сложение, вычитание) с другими объектами Distance.

Короткие примеры использования

Базовый расчет расстояния между двумя координатными парами:

from geopy import distance

# Координаты Москвы и Санкт-Петербурга
coords_1 = (55.7558, 37.6173)
coords_2 = (59.9343, 30.3351)

dist = distance.distance(coords_1, coords_2)
print(f"Расстояние: {dist.km:.2f} км")
print(f"Расстояние: {dist.miles:.2f} миль")
Расстояние: 634.91 км
Расстояние: 394.52 миль

Использование разных форматов ввода и эллипсоида:

from geopy import distance
from geopy.point import Point

# Разные форматы точек
p1 = Point(55.7558, 37.6173)
p2 = "59.9343, 30.3351"  # Строка

dist = distance.distance(p1, p2, ellipsoid='GRS-80')
print(f"Расстояние (GRS-80): {dist.meters:.0f} метров")
Расстояние (GRS-80): 634913 метров

Похожие функции в Python

В модуле geopy.distance также присутствуют две специализированные функции:

  • geodesic: Вычисляет геодезическое расстояние (кратчайший путь по поверхности эллипсоида). Является реализацией метода Винсенти и используется по умолчанию в функции distance(). Отличается высокой точностью для любых расстояний.
  • great_circle: Вычисляет расстояние по большому кругу (ортодромия), предполагая, что Земля - идеальная сфера. Расчеты выполняются быстрее, но точность немного ниже, особенно для больших расстояний или в высоких широтах. Подходит для быстрых приближенных оценок.

Функцию distance() обычно предпочитают использовать, так как она по умолчанию применяет точный геодезический метод (geodesic). Явный выбор great_circle возможен при необходимости повышения скорости в ущерб минимальной погрешности.

Альтернативы в других языках

JavaScript (библиотека geographiclib):

// Установка: npm install geographiclib
const GeographicLib = require("geographiclib");
const geod = GeographicLib.Geodesic.WGS84;

let result = geod.Inverse(55.7558, 37.6173, 59.9343, 30.3351);
console.log(`Расстояние: ${result.s12 / 1000} км`);
Расстояние: 634.913 км

PHP (библиотека phpgeo):

// Установка: composer require mjaschen/phpgeo
use \Location\Coordinate;
use \Location\Distance\Vincenty;

$coord1 = new Coordinate(55.7558, 37.6173);
$coord2 = new Coordinate(59.9343, 30.3351);
$calc = new Vincenty();
$distance = $calc->getDistance($coord1, $coord2);

echo "Расстояние: " . $distance / 1000 . " км\n";
Расстояние: 634.913 км

SQL (PostgreSQL с PostGIS):

SELECT ST_Distance(
    ST_GeogFromText('POINT(37.6173 55.7558)'),
    ST_GeogFromText('POINT(30.3351 59.9343)')
) / 1000 AS distance_km;
 distance_km
-------------
   634.912998

Основное отличие от Geopy заключается в необходимости явно использовать специализированные библиотеки или расширения БД. В Geopy функциональность инкапсулирована в простом интерфейсе distance().

Типичные ошибки

1. Неправильный порядок координат (долгота, широта). Функция ожидает (широта, долгота).

from geopy import distance
# ОШИБКА: Перепутаны широта и долгота
dist = distance.distance((37.6173, 55.7558), (30.3351, 59.9343))
print(dist.km)
414.161  # Получено неверное расстояние

2. Попытка использовать объект Distance как число.

from geopy import distance
dist_obj = distance.distance((55.7558, 37.6173), (59.9343, 30.3351))
try:
    total = dist_obj * 2  # Ошибка
except TypeError as e:
    print(f"Ошибка: {e}")
Ошибка: unsupported operand type(s) for *: 'Distance' and 'int'

3. Передача строки координат в неправильном формате.

from geopy import distance
try:
    dist = distance.distance("55.7558, 37.6173", "59.9343; 30.3351") # Разные разделители
    print(dist.km)
except ValueError as e:
    print(f"Ошибка разбора: {e}")
Ошибка разбора: Failed to parse ...

Изменения в последних версиях

В Geopy 2.0.0 (2020) произошли значительные изменения в API. Функция geopy.distance.distance стала основным фасадом, объединяющим geodesic и great_circle. Ранее для вычислений необходимо было напрямую создавать экземпляры этих классов.

До версии 2.0:

from geopy.distance import geodesic
dist = geodesic((55.7558, 37.6173), (59.9343, 30.3351)).km

После версии 2.0 (предпочтительный способ):

from geopy import distance
dist = distance.distance((55.7558, 37.6173), (59.9343, 30.3351)).km

Это изменение сделало API более последовательным и упрощенным. Также были улучшены обработка ошибок и производительность внутренних расчетов.

Расширенные примеры

Вычисление расстояния между несколькими точками в цикле:

Пример python
from geopy import distance

cities = {
    "Москва": (55.7558, 37.6173),
    "Санкт-Петербург": (59.9343, 30.3351),
    "Казань": (55.7964, 49.1089),
    "Екатеринбург": (56.8389, 60.6057)
}

names = list(cities.keys())
coords = list(cities.values())

for i in range(len(cities)):
    for j in range(i + 1, len(cities)):
        d = distance.distance(coords[i], coords[j]).km
        print(f"{names[i]} – {names[j]}: {d:.1f} км")
Москва – Санкт-Петербург: 634.9 км
Москва – Казань: 717.9 км
Москва – Екатеринбург: 1416.8 км
Санкт-Петербург – Казань: 1267.8 км
Санкт-Петербург – Екатеринбург: 1806.2 км
Казань – Екатеринбург: 717.2 км

Использование пользовательской функции для расчета расстояния по большому кругу:

Пример python
from geopy import distance
# Явное использование метода большого круга
coord_spb = (59.9343, 30.3351)
coord_helsinki = (60.1699, 24.9384)

dist_gc = distance.great_circle(coord_spb, coord_helsinki)
dist_geod = distance.distance(coord_spb, coord_helsinki) # По умолчанию geodesic

print(f"Большой круг: {dist_gc.km:.3f} км")
print(f"Геодезическое: {dist_geod.km:.3f} км")
print(f"Разница: {abs(dist_gc.km - dist_geod.km):.3f} км")
Большой круг: 298.526 км
Геодезическое: 298.434 км
Разница: 0.092 км

Расчет общего пути (сумма отрезков):

Пример python
from geopy import distance

route = [
    (55.7558, 37.6173),  # Москва
    (55.7964, 49.1089),  # Казань
    (56.8389, 60.6057)   # Екатеринбург
]

total = distance.distance(0, 0)  # Нулевое расстояние
for i in range(len(route)-1):
    segment = distance.distance(route[i], route[i+1])
    total += segment  # Объекты Distance поддерживают сложение
    print(f"Участок {i+1}: {segment.km:.1f} км")

print(f"\nОбщее расстояние: {total.km:.1f} км")
Участок 1: 717.9 км
Участок 2: 717.2 км

Общее расстояние: 1435.1 км

питон geopy.distance.distance function comments

En
Geopy.distance.distance Compute distance between two points