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

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



Содержание статьи:


Что такое прямое и обратное геокодирование?
Какие существуют сервисы для решения этой задачи
Тарифы и особенности сервисов
Примеры данных, которые дают разные сервисы
Примеры обратного геокодирования
Сравнительное тестирование качества прямого и обратного геокодирования
Итоговая таблица с оценками качества
Выводы

Что такое прямое и обратное геокодирование?


В начале статьи я уже немного об этом сказал, теперь дам более строгое определение.
Прямое геокодирование – это задача получения координат географической точки по её адресу, написанному на понятном человеческом языке. Например, пользователь указывает адрес «Москва, Красная площадь д. 3», или «Москва, ГУМ» — нам, чтобы отобразить эту точку на карте, необходимо узнать координаты этого адреса.

Обратное геокодирование, соответственно, решает обратную задачу – по точке, указанной пользователем, получить её адрес или название расположенного там объекта.
И та, и другая задача очень часто встречаются в различных сервисах, работающих с геоданными пользователей, например, если вы разрабатываете интернет-магазин и хотите показать ближайший к адресу пользователя пункт выдачи заказов – вам не обойтись без определения точных координат местоположения пользователя. Если вы делаете сервис заказа такси или курьерской доставки – пользователю может быть удобно указать точку на карте, а вам для вашего курьера всё равно будет удобнее показать помимо точки на карте еще и адрес пользователя в виде текста.

Какие существуют сервисы для решения этой задачи?


Вообще, сервисы подразделяются на 2 основных категории – это оффлайн- и онлайн-сервисы. Оффлайн-сервис подразумевает, что вы скачиваете на свой локальный компьютер некую базу данных (добавляете её в своё приложение) и получаете информацию из неё. Онлайн-сервис представляет из себя API, к которому вы формируете запрос в соответствии с документацией, и он возвращает вам ответ с интересующей вас информацией.

В большинстве случаев онлайн-сервисы предлагают более высокую точность ответов, поскольку обновляются более часто, а также более удобны в использовании – потому что вам нет необходимости поддерживать отдельную машину под оффлайн-сервис или зашивать базу данных (достаточно объемную) и обслуживающий её код в ваше приложение. Поэтому в рамках этой статьи я буду рассматривать только онлайн-сервисы для решения задач прямого и обратного геокодирования.

Тарифы и особенности сервисов


В процессе изучения рынка сервисов геокодирования я выделил для себя следующие основные решения:
Название Тариф Комментарий

Геокодер Яндекс.карт


tech.yandex.ru/maps/geocoder
Бесплатно до 25 000 запросов/сутки
Если больше – коммерческие тарифы от 120 000 рублей в год за 1000 запросов в сутки
Кроме количества запросов также ограничен лицензионным соглашением — результаты кодирования нельзя сохранять и использовать без карты (но можно кешировать), их нужно отображать только на картах Яндекса и только в рамках общедоступных сервисов (доступных всем или с открытой бесплатной регистрацией).

«Подсказки» от Дадата


dadata.ru/api/suggest/address
Бесплатно 10 000 запросов в сутки.
Платные тарифы от 5000 рублей в год за 50 тысяч запросов в сутки.
Оферта не позволяет его использовать полностью в автоматическом режиме — подсказки — только для уточнения данных, которые вводятся пользователем, прямо в форме где они вводятся. Обрабатывать собранные ранее массивы адресов в автоматическом режиме подсказками нельзя.

Если не использовать автоматический режим, то этот сервис самый дешевый на рынке.
На платных тарифах даёт массу полезной информации – цены на недвижимость, ближайшие станции метро, коды ФИАС и КЛАДР и тд

Google Maps Geocoding API


developers.google.com/maps/documentation/geocoding/intro
5$ за тысячу запросов, бесплатного лимита нет.
Полностью платный сервис, поэтому я в своей работе его практически не использовал. Зато есть клиенты для Java, Python, Go и Node.js

GraphHopper


www.graphhopper.com/developers
Стоимость основана на использовании кредитов. Бесплатно вам дается 500 кредитов в день, что эквивалентно примерно 1666 запросам.
Коммерческие тарифы от 48 евро в месяц за 5000 кредитов (16 666 запросов) в сутки
У сервиса много других интересных функций помимо геокодирования:
Routing API и Route Optimization API — автоматическое построение и оптимизация маршрутов
Matrix API — построение логистической матрицы с учетом загруженности дорог
Isochrone API — сервис, позволяющий построить зону, в которую можно доехать из заданной точки за фиксированное время.
Map Matching API — сервис, который привязывает GPS-треки к дорогам, чтобы можно было построить историю передвижения.

MapBox


docs.mapbox.com/api/search
Бесплатно до 100 000 запросов в месяц. Свыше 100 000 – 0,75$ за каждую 1000 запросов
Удобный сервис, потому что имеет огромное количество официальных модулей для Swift, JS, Java, Python, Ruby. Плохо работает с Россией

OpenStreetMaps Nominatim


nominatim.org/release-docs/develop/api/Overview
OpenSource-решение, которое вы можете развернуть на своей машине бесплатно.
Если вас не устраивает бесплатная возможность, которая на самом деле условно бесплатная — ведь вам нужно поддерживать работоспособность сервиса на собственной машине, обслуживать её и пр. – вы можете воспользоваться одним из платных провайдеров API. Список можно найти тут:
https://wiki.openstreetmap.org/wiki/Nominatim#Alternatives_.2F_Third-party_providers


Примеры данных, которые дают разные сервисы


Чтобы показать примеры данных, которые предоставляют нам разные сервисы, я использовал адрес в самом центре Москвы — Красная площадь, д. 3.

Ответы сервисов я собрал в один gist, где можно посмотреть их в том виде, в котором сервис их вернул: https://gist.github.com/iskander-g/6c2bb24065708730c76993da4afea9d0

Больше всего сведений об адресе дают Дадата и OSM. При этом у OSM доступный плейграунд для тестирования возвращает сразу отформатированную HTML-страницу с данными — получить в сыром виде ответ сервиса у меня не получилось, но на странице можно оценить все сведения, которые имеются у сервиса об адресе.

Сравнительная таблица сведений, которые были предоставлены сервисами в виде структурированных данных:
Яндекс
Дадата
Google
Graphhopper
MapBox
OSM
Координаты
+
+
+
+
+
+
Адрес в нормализованном виде
Россия, Москва, Красная площадь, 3
г Москва, пл Красная, д 3
Красная пл., 3, Москва, Россия, 101000
Россия, Город Москва, Москва, округ Тверской, 109012, Красная Площадь 3
3, Красная площадь, Китай-город, Тверской район, Центральный административный округ, Москва, Центральный федеральный округ, Россия
Страна
+
+
+
+
+
+
Федеральный округ
+
+
+
Регион
+
+
+
+
+
Город
+
+
+
+
+
+
Административный округ в городе
+
+
+
Район
+
+
+
+
Улица
+
+
+
+
+
+
Номер дома
+
+
+
+
+
Ближайшие станции метро
+
Почтовый индекс
+
+
+
+
+
Коды ФИАС, КЛАДР, ОКАТО, налоговой
+
Информация о типе и стоимости недвижимости
+
Информация о размещенных по адресу магазинах и других POI
+
Название места на других языках
+


API тестировался в официальных примерах/плейграундах, там, где это есть. Яндекс и Гугл потребовал получить API-ключ, чтобы протестировать сервис. У Гугла также пришлось оформить платежный аккаунт. Адреса, где можно протестировать сервисы:

Yandex (требуется ключ)
https://geocode-maps.yandex.ru/1.x/?apikey=&geocode=

Дадата
https://dadata.ru/suggestions/

Google (требуется ключ)
https://maps.googleapis.com/maps/api/geocode/json?address=&key=

GraphHopper
https://graphhopper.com/api/1/examples/#geocoding

MapBox
https://docs.mapbox.com/search-playground/

OSM
https://nominatim.openstreetmap.org/

Примеры обратного геокодирования


Чтобы понять, как сервисы справляются с обратным геокодированием, т.е. получением адреса по координатам, я попробовал по указанным выше адресам вместо адреса подставить координаты того же третьего дома на Красной площади: 37.62159949999999, 55.7546025

Результаты:
Яндекс
Россия, Москва, Красная площадь, 3
Дадата
г Москва, Красная пл, д 3
Google
Красная площадь 3, ТД ГУМ, Москва, Россия, 109012
GraphHopper
3, Red Square, 109012, Tverskoy District, Russia
MapBox
Кофемания, ГУМ, Москва, Город Москва 109012, Russia
OSM
Государственный универсальный магазин (ГУМ), Красная площадь, Китай-город, Тверской район, Центральный административный округ, Москва, Центральный федеральный округ, 109012, Россия

Интересно, что GraphHopper, если кликать мышью по разным частям ГУМа, возвращает разные названия магазинов. Дадата и Яндекс возвращают только адреса, остальные сервисы стараются предложить также POI, расположенные по этому адресу. Формат ответа и набор данных у всех сервисов аналогичен данным, которые возвращаются при прямом геокодировании.

Сравнительное тестирование качества геокодирования


Для сравнительного тестирования качества прямого геокодирования я выбрал набор из 15 адресов:
Страна
Город
Адрес
1
Россия
Москва
Красная площадь д. 3
2
Россия
Москва
2-й Карачаровский проезд, 2
3
Россия
Казань
Фатыха Амирхана 13
4
Россия
Казань
2я Центральная, 172А
5
Россия
Чистополь
Лобачевского, 57
6
Россия
Новокузнецк
Ермака 16
7
Россия
Улан-Удэ
Столбовая, 68
8
Казахстан
Нурсултан
Кокжазык, 14
9
Казахстан
Жезказган
Космонавтов, 10
10
Беларусь
Минск
Переулок Стебенёва, 6
11
Беларусь
Мозырь
Рыжкова, 4
12
Украина
Киев
Суздальська вулиця 9
13
Украина
Бучач
Богдана Хмельницького вулиця 6
14
Венгрия
Budapest
Homokdomb 7
15
США
CO, Fort Collins
East Oak Street, 411

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

По итогам тестирования я составил сводную таблицу с результатами всех сервисов. Координаты точек, которые вернул мне сервис, я накладывал на статическую карту Яндекса, и смотрел, насколько точно попадает тот или иной сервис в загаданный дом. За попадание в черту дома давал 3 балла, за попадание в соседние дома – 2, если указало на улицу, на которой находится дом – 1 балл. За промах, соответственно, 0.

Каждому сервису я присвоил свой цвет метки — Яндекс — оранжевый, Дадата — синий, Google — зеленый, GraphHopper — желтый, MapBox — красный и OSM — фиолетовый.

Россия, Москва, Красная площадь д. 3




GraphHopper – мимо. MapBox и OSM получают по 2 балла, Яндекс, Дадата и Google – по 3 балла.

Россия, Москва, 2-й Карачаровский проезд, 2




С этим адресом все претенденты справились лучше. Интересно, что OSM, Дадата и Яндекс показывают на примерный центр дома, а Google – на угол, который ближе к дороге. GraphHopper и MapBox указали на улицу, но от искомого дома далековато.

Россия, Казань, Фатыха Амирхана 13




MapBox не нашел ничего, GraphHopper и OSM указали на конец улицы, Яндекс попал в центр дома, Дадата максимально близко к центру, а Google снова показывает на конец дома, который ближе к дороге.

Россия, Казань, 2я Центральная, 172А




MapBox и GraphHopper – мимо, OSM не нашел ничего. Из оставшейся тройки Google указал на улицу, Яндекс на дом, а Дадата – на соседний дом.

Россия, Чистополь, Лобачевского, 57




MapBox нашел примерно центр населенного пункта, но это незачет. GraphHopper и OSM указали на улицу, на которой расположен дом, а Яндекс, Дадата и Google опять попали в дом. Гугл, как обычно, не в центр дома, а в какой-то угол, в этот раз не самый ближний к дороге.

Россия, Новокузнецк, Ермака 16




C этим адресом не справился только MapBox. OSM и GraphHopper показали одинаковый результат, Яндекс предсказуемо поставил свою метку на номер дома, Google возле второго подъезда, а Дадата – между подъездами.

Россия, Улан-Удэ, Столбовая, 68




Последний российский адрес в списке. MapBox опять в стороне. OSM и GraphHopper ближе к цели, но тоже далековато. Дадата смогла указать улицу, но не дом. Яндекс поставил метку на соседний, 66 дом, и только Google в данном случае смог поставить точную отметку.

Промежуточный итог по тестированию российских адресов


Яндекс набрал 20 баллов из 21 возможного, не справившись только с последним. На втором месте Google с одной ошибкой в частном секторе Казани с 19 баллами. Третье место – Дадата, которая ошиблась и в Казани, и в Улан-Удэ.

На заграничных адресах Дадата выпадает из конкурса и дальнейшее сравнение уже пойдет между 5 оставшимися участниками.

Казахстан, Нурсултан, Кокжазык, 14




MapBox и GraphHopper опять промахнулись, Google указал на улицу, а Яндекс и OSM поставили две очень близкие метки на искомом доме.

Казахстан, Жезказган, Космонавтов, 10




С этим адресом сервисы справились лучше – все попали в город, но MapBox и Google далеко от искомого адреса. Яндекс и OSM опять поставили метки в одну точку, GraphHopper нашел начало улицы.

Беларусь, Минск, Переулок Стебенёва, 6




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

Беларусь, Мозырь, Рыжкова, 4




С частным сектором в Беларуси тоже у всех сервисов есть проблемы, но по крайней мере все они указали на улицу. Google и GraphHopper оказались довольно далеко от искомого дома, а Яндекс, OSM и MapBox разместит метки точно, с небольшим разбросом.

Украина, Киев, Суздальська вулиця 9




В Киеве MapBox поставил метку на центр города, GraphHopper – на улицу, а Яндекс, Google и OSM попали в дом. При этом тут метки совпали уже у Google и OSM.

Украина, Бучач, Богдана Хмельницького вулиця 6




GraphHopper опять мимо, Яндекс и Google смогли указать на улицу, MapBox отметил дом через дорогу от искомого, а OSM поставил точную отметку.

Венгрия, Budapest, Homokdomb 7




По этому адресу MapBox нашел город, Яндекс — улицу, OSM и GraphHopper поставили отметку на дом, а Google – на угол дома.

США, CO, Fort Collins, East Oak Street, 411




В Форте Коллинс Яндекс нашел метку на улицу, все остальные сервисы указали на дом с минимальным разбросом.

Итоги рейтинга по заграничным адресам:


  • По СНГ лидирует OSM, на втором месте – Яндекс, на третьем – Google.
  • В Европе и США с задачей геокодирования лучше всего справляются OSM, GraphHopper и Google.


Итоговая таблица:




Выводы


Перед тем, как начать использовать в своей работе какой-либо сервис геокодирования, его обязательно надо протестировать на базе адресов ваших пользователей. Потому что я, например, очень большие надежды возлагал на MapBox – ведь у этого сервиса очень большая база различных модулей, и видно, что они уделяют большое внимание удобству работы с их сервисом. К сожалению, качество геокодирования у этого сервиса оказалось самым низким. GraphHopper похож на MapBox — и по разнообразию предлагаемых сервисов, и по качеству работы геокодера.

OSM показывает хорошие результаты за рубежом, и достаточно посредственные – в России.
Вообще, если говорить именно о российской базе, с которой лично я в основном работаю, то тут лидеры — Яндекс, Google и Дадата. Яндекс показывает лучшие результаты в России, и достаточно посредственные – за рубежом. Google в целом работает хорошо везде, и везде, бывает, промахивается. И при этом самый дорогой. Дадата хорошо работает с российскими адресами, недорогая, предлагает много дополнительных сервисов, но становится бесполезна при пересечении границы.

В целом все эти три сервиса показали очень достойный результат, и если ваши клиенты в основном указывают адреса не из частных секторов, то я бы для работы выбрал Дадату, по ряду причин:

  • Более низкие тарифы, чем у Яндекса и Гугла
  • Меньше заморочек с лицензией
  • Больше дополнительных сервисов, доступных прямо из подсказок – индекс, станции метро, часовой пояс и пр.

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

Еще интересное наблюдение по итогам тестирования — наиболее высокое качество у всех сервисов геокодирования – в Беларуси.