Руководства

Расчёт расстояния между двумя геокодированными точками

API геокодирования не возвращает расстояние между двумя адресами напрямую, поскольку для расчёта расстояния нужны только координаты, а их прямой эндпоинт уже выдаёт для любого отправленного адреса.

Получение координат обоих адресов

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

POST /v1/forward
Content-Type: application/json

["221B Baker Street, London", "10 Downing Street, London"]
{
  "status": "ok",
  "results": [
    {"formatted": "221B Baker Street, London, UK", "lat": 51.5237, "lon": -0.1585, "type": "address", "precision": "house", "confidence": 0.95, "place_id": "abc123", "components": {}},
    {"formatted": "10 Downing Street, London, UK", "lat": 51.5033, "lon": -0.1276, "type": "address", "precision": "house", "confidence": 0.96, "place_id": "op678", "components": {}}
  ]
}

Расчёт расстояния

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

distance_km = haversine(51.5237, -0.1585, 51.5033, -0.1276)

Распространённая ошибка, которой стоит избегать

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

Второй пример: общая длина маршрута с несколькими остановками

Тот же расчёт естественно распространяется на больше чем две точки. Геокодируйте все остановки маршрута одним пакетным запросом, затем сложите расстояния по формуле гаверсинусов между каждой парой соседних координат, чтобы получить примерную общую длину маршрута. Это удобно для быстрой оценки маршрута доставки ещё до того, как у вас появится настоящая пошаговая маршрутизация.

total_km = haversine(a, b) + haversine(b, c) + haversine(c, d)

Расстояние по прямой и расстояние в пути

Расчёт по формуле гаверсинусов даёт расстояние по прямой, а не расстояние на машине или пешком по реальным дорогам. Для большинства задач, например сортировки ближайших точек или приблизительной оценки близости, расстояния по прямой достаточно, и для него не нужно ничего, кроме уже имеющихся координат. Если вам нужно именно расстояние по маршруту, это отдельный вид расчёта, который выходит за рамки того, что даёт геокодирование.

Пограничный случай, о котором стоит знать

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

Стоимость запросов

Геокодирование двух адресов стоит два запроса, независимо от того, отправлены они отдельными вызовами или одним пакетным. Сам расчёт расстояния, когда у вас уже есть обе пары координат, целиком выполняется в вашем коде и больше ничего не списывает с вашей квоты.

Повторное использование уже имеющихся координат

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

Для любого адреса, который вы ещё не преобразовали в координаты, расчёт расстояния отделяет всего один запрос геокодирования. Полная структура ответа описана в документации по прямому геокодированию.