Всем привет!
Одна из самых распространённых операций в сфере пространственной обработки и аналитики данных — это геокодирование. Если кратко, это когда вам необходимо по адресу объекта (например: Москва, Красная площадь, 1) или его названию (Государственный исторический музей) получить географические координаты, то есть понять, где находится это место, или же наоборот — получить адрес по координатам.
Если упрощать, то для выполнения данной операции необходимо два компонента: собственная адресная база с координатной привязкой, а также настроенный текстовый поиск. Более подробно об устройстве и способах настройки поиска можно почитать, например, в статье Яндекса.
Несмотря на то, что требование состоит всего из двух пунктов, соблюдение этих пунктов является непростой задачей: необходимо, во-первых, поддерживать адресную базу в актуальном состоянии (что по мере увеличения территориального охвата становится всё более и более трудоёмкой задачей), а во-вторых, настраивать логику поиска совпадений между присланным адресом и адресами в базе строений (здесь сложность увеличивается с ростом количества охватываемых стран и, следовательно, языков).
Поэтому в подавляющем числе случаев геокодирование проводят с помощью специальных сервисов, имеющих возможность поддерживать и развивать оба компонента. Такие сервисы есть у всех крупных игроков картографического рынка, таких как Google, Bing, Yahoo, Яндекс, 2ГИС и другие. Также есть решения, работающие поверх общедоступного и открытого адресного перечня OpenStreetMap (OSM): Nominatim, Photon, OpenCage и т. д. В интернете можно найти не одну и даже не один десяток статей, посвящённых сравнению этих сервисов между собой. Вот некоторые из них:
Прямое и обратное геокодирование – тестирование популярных решений;
Геокодирование. Как привязать 250 тысяч адресов к координатам за 10 минут?;
Проводимые сравнения охватывают разные аспекты сервисов:
возможность использования (в каком объёме, за какую стоимость и на какие страны);
цель и способ использования (прямое или обратное геокодирование, одиночная или пакетная обработка);
детальность возвращаемого результата (адрес, записанный одной строкой или разбитый на компоненты от страны до номера дома, наличие кодов КЛАДР и ОКАТО, информация о типе строения и т. д.);
точность возвращаемых результатов (насколько корректно сервис определил адрес и нашёл его в своей базе).
Все эти аспекты важны, но, исходя из определения геокодирования, наиболее важным определённо является последний — точность возвращаемых результатов. И обширных исследований на эту тему мне найти не удалось. Зачастую проверка делается на небольшом количестве адресов 10–20. Понятно, что при такой выборке полученные результаты не могут претендовать на универсальность во всех случаях.
А даже если мы и определим сервис геокодирования, который в проведённом сравнении даст хороший процент корректных ответов, условно 90%, как при запуске на новых адресах понять, какие объекты были определены корректно, а какие нет? И какая доля корректных относительно всех переданных для геокодирования объектов? Если мы этого не знаем, то мы либо доверяем полученным результатам на 100% и принимаем вероятные риски, либо вручную проходимся по сгеокодированным точкам и сверяем их с картой (надеясь, что она верная). Если решим проверять вручную, то проверка даже 500 адресов превращается в задачу на половину рабочего дня, что уж говорить о бóльших объёмах.
И, честно сказать, это положение вещей меня угнетает. Почему в 2026 году, когда все вокруг стараются внедрить ИИ, в том числе в различные гео-сферы, как аналитику, так и разработку (в том числе и в ядро текстового поиска, как в приведённой ранее статье Яндекса) банально непонятно, с помощью какого сервиса искать адрес и быть уверенным, что полученный результат корректен? Это же такая базовая операция…
В данной статье я постараюсь выяснить, какой из сервисов даёт наиболее точный результат в рамках Москвы на примере 2 000 адресов, а также предложу способ проверки полученных результатов.
Спойлер: вышло чуть меньше — 1 873 адреса.
Исследование будет проведено в рамках Москвы, ибо именно с этой территорией мне чаще всего приходится работать. Отмечу, что для других населённых пунктов страны выводы данного исследования в детальности ранжирования сервисов могут отличаться, ибо меняется качество наполнения адресных баз, используемых сервисами геокодирования. Тем не менее общая закономерность, думается мне, сохранится.
В любом случае при желании и наличии данных вы сможете повторить исследование для интересующей вас территории. А если ещё и поделитесь результатами, будет вовсе прекрасно!
Весь пошаговый процесс исследования вместе с полученными результатами можно посмотреть на GitHub и использовать для исследования других территорий.
Повествование будет разбито на следующие разделы:
Используемые в исследовании сервисы и их актуальные ограничения
Оценка влияния качества передаваемого адреса на результат
2.1 Определение наилучшего варианта написания «домовой» части адреса
2.2 Оценка влияния нормализации «уличной» части адреса
2.3. Рейтинг лучших сервисов геокодирования на Москву
Презентация инструмента проверки достоверности результатов
1. Используемые в исследовании сервисы и их актуальные ограничения
Сперва я хотел ограничить список сервисов геокодирования для данного исследования, опираясь на выводы упомянутых выше статей, опираясь на выводы упомянутых выше статей, а также на собственный опыт использования различных сервисов (в том числе полученного при написании плагина для QGIS — All Geocoders At Once и работай над проектом Где жить в городе именно вам? Персонализированный сервис подбора идеальных домов).
Однако потом что-то пошло не так так и я решил проверить все сервисы, что были доступны в библиотеке GeoPy, а также некоторые другие популярные в нашей стране. Суммарно вышло около 30–35 сервисов.
И это было не зря (спойлер к Here)!
К сожалению не вышло проверить лишь Яндекс и Azure (ex Bing)
К большому сожалению, мне не удалось полноценно включить в сравнение сервис геокодирования от Яндекса…
Ориентируясь на раздел "Стоимость" описания API, я даже оформил подписку на месяц за немалые 20 800 ₽. Однако после успешного оформления, в личном кабинете разработчика я заметил, что тариф у меня всё-таки без возможности сохранения результатов, хотя на приведённой ранее странице было указано «✓ Сохранение и изменение данных». Изучив правила использования в другом описании, было выяснено, что на самом деле возможность сохранения доступна только при годовой подписке и то не по умолчанию, а в качестве опции. Оформлять годовую расширенную подписку для одного человека, сами понимаете, было нерационально. А провести необходимое сравнение без возможности сохранения результатов не вышло бы.
Сервисом воспользоваться я ни разу не успел и поддержка, за что ей спасибо, согласилась вернуть мне затраченные средства и отменить подписку.
Тем не менее я постарался, где это было возможно, включить сервис Яндекса как одного из предполагаемых лидеров, в том числе в таблицу правил использования, в исследование «домовой» части и, возможно, ещё в нескольких местах текста.
Также мне не удалось проверить сервис от Azure. При попытке получить доступ к сервисам Azure с помощью ранее созданного аккаунта Microsoft я столкнулся с верификацией длиной в полгода. Обтекаемый ответ службы поддержки можно интерпретировать как «мутный у вас аккаунт», что, скорее всего, вызвано расхождением получаемых от меня IP-адресов.
Многие сервисы из представленных в GeoPy не поддерживают работу с адресами в России и не в силах найти даже самые простые адреса, например «Москва, Красная площадь, 1». Такие сервисы я не стал добавлять в сравнение, и список сократился до 19 исследуемых.
Забегая вперёд, скажу, что 4 из 19 сервисов не справились даже с 50% адресов. Далее в тексте, в подразделе с результатами, будет картинка со всеми 19, но дабы хоть немного разгрузить основной текст, дальше я буду рассматривать только те, что прошли порог в половину адресов.
Помимо качества результатов один из наиболее важных факторов — это возможность использования сервисов и условия такого использования. В таблице ниже я расписал минимальные требования для взаимодействия с сервисами (помимо того, чтобы зайти на веб-карту, если таковая имеется, вручную ввести адрес или использовать тестовые ключи).
Так, например, Яндекс отнесён к категории «Геокодеры с API-ключом без привязки карты», поскольку у него есть бесплатный тариф. Однако если вам необходимо будет сохранять результаты или выполнять автоматизированную обработку, вам понадобится платная версия, а значит сервис перейдёт в категорию «Геокодеры с API-ключом и полностью платные». Схожие сценарии актуальны и для других сервисов. Поскольку мне неизвестен необходимый вам сценарий использования сервиса — массовое геокодирование, геокодирование на карте или лишь вывод предполагаемых адресов, — я решил указать именно минимальный порог входа.
Название | Стоимость и ограничение по количеству использования | Возможность сохранять и обрабатывать, публиковать полученные данные |
|---|---|---|
Геокодеры без API-ключа | ||
Nominatim | Полностью бесплатный. Максимум 1 запрос в секунду. | ✅✅ |
Photon | Полностью бесплатный. Без конкретных ограничений, просят использовать в разумных пределах. Примем это как 1 запрос в секунду. | ✅✅ |
Esri | Бесплатный лимит равен 20000 запросам в месяц. | ⚠️❌ |
Геокодеры с API-ключом без привязки карты | ||
Яндекс | Бесплатный лимит равен 1000 запросам в сутки с ограничением в 50 запросов в секунду. Больше — тарифные планы | ⚠️❌ |
GraphHopper | В бесплатном тарифе до 1500 запросов в день, при использовании именно их сервиса. Конкретных ограничений по запросам в секунду нет (”The Free Plan does not include any guarantees”), по личному опыту запрос в 2-3 секунды. | ✅✅ |
Geoapify | Бесплатный лимит равен 3000 запросам в сутки с ограничением в 5 запросов в секунду. Больше — тарифные планы | ✅✅ |
LocationIQ | Бесплатный лимит равен 5000 запросам в сутки с ограничением в 1 запрос в секунду. Больше — тарифные планы | ✅⚠️ |
NetToolKit | Бесплатный лимит равен 1000 запросам в сутки. Больше — тарифные планы. | ✅✅ |
OpenCage | Бесплатный лимит равен 2500 запросам в сутки с ограничением в 1 запрос в секунду. Больше — тарифные планы | ✅✅ |
Геокодеры с API-ключом с привязкой карты | ||
В бесплатном тарифе доступно до 10000 запросов в месяц с ограничением в 3000 запросов в минуту (50 запросов в секунду). | ⚠️❌ | |
DaData | Только платное использование: 20 копеек за один запрос или подписка, с ограничением в 20 запросов в секунду. | ✅✅ |
Here | В бесплатном тарифе доступно до 30000 запросов в месяц с ограничением в 5 запросов в секунду. | ⚠️❌ |
Positionstack | В бесплатном тарифе доступно до 100 запросов в месяц. Да, именно 100. | ✅❌ |
Геокодеры с API-ключом и полностью платные | ||
2ГИС | Только использование по платной подписке, минимальный пакет — 10000 запросов в месяц. | ❌❌ Ограничения при использовании программного комплекса Добавить сервис в исследование удалось благодаря партнёрству сервиса с работодателем. |
Pelias (hosted by Geocode Earth) | Только использование по платной подписке, минимальный пакет — 150000 запросов в месяц с ограничением в 10 запросов в секунду. | ✅❌ |
2. Оценка влияния качества передаваемого адреса на результат
Качество возвращаемого геокодером результата зависит не только от его внутренней работы, но и от того, насколько корректный и понятный адрес был передан ему для поиска. В связи с этим было интересно узнать:
а) в каком виде лучше всего передавать адрес;
б) есть ли наиболее универсальный формат адреса для разных геокодеров;
и в процессе исследования также появился третий пункт:
в) с какими задачами стандартизации сервисы геокодирования справляются хорошо сами, а какую часть лучше предобработать на своей стороне.
Стандартизацию (или же нормализацию) адреса я свёл к двум частям: «домовой» и основной «уличной».
2.1 Определение наилучшего варианта написания «домовой» части адреса
Целью этого этапа являлось понять, есть ли разница в том, как передавать часть адреса, которая отвечает за нумерацию строений. Влияет ли формат записи «домовой» части на точность результата и, если да, какой лучше использовать и в каких случаях? Если есть возможность, можно ли выбрать один наиболее универсальный вариант?
Для того чтобы получить ответы на поставленные вопросы, необходимо было отобрать адреса, которые геокодируются корректно при использовании любого из сервисов (среди тех, что в целом имеют хороший показатель точности определения) и имеют разнообразную, в том числе сложную нумерацию строений. Таких адресов было отобрано 9:
Москва, Покровский бульвар, 4/17 с4Б
Москва, Настасьинский переулок, 4 к40
Москва, улица Воронцово Поле, 6-8 с4
Москва, Тессинский переулок, 3А
Москва, улица Варварка, 5 с1
Москва, Космодамианская набережная, 46-50 с1
Москва, Измайловское шоссе, 71 к4Г-Д
Москва, Маленковская улица, 13/12
Москва, Нагатинская улица, 16А с29
Выборка небольшая, однако мне показалось, что для данного теста этого будет вполне достаточно.
Далее каждый адрес прогонялся через геокодер так, что «уличная» часть соответствовала записи этой улицы в этом геокодере, а вот «домовая» часть — нет.
Для данного этапа сравнения я отобрал следующие геокодеры: Nominatim, Яндекс, 2ГИС, Google, ФИАС, Here, Esri. Другие не стал включать, поскольку они либо в целом реже дают верный ответ, либо работают на базе OSM, а значит в своём ядре хранят адрес в том же виде, к которому обращается Nominatim.
Полученные от каждого сервиса ответные адреса я попытался классифицировать по формату написания «домовой» части. Однако среди семи выбранных геокодеров, шесть из них так или иначе отличались друг от друга.
У OSM части строения идут через пробел, у Яндекса слитно, у 2ГИС чаще встречаются строчные литеры корпусов и менее компактные формы сокращений, у Google не используются сокращения, у ФИАС всегда пишется слово «дом», а у Here частично похоже то на один, то на другой. И лишь у Esri в 8 из 9 случаев формат написания точь-в-точь совпадал с форматом, принятым у Яндекса.
Также было замечено, что у всех ранее озвученных сервисов формат «уличной» части был идентичен (с небольшим отличием у Esri), кроме ФИАСа. В ФИАС слова «улица», «шоссе», «набережная» и т. п. всегда стоят в начале адреса. Для соблюдения правила, что каждый сервис должен найти адрес, являющийся на 100% ему привычным (а для DaData привычен ФИАС), было также решено разделить на две категории и «уличную» часть, первая — «под речь» — встречалась у всех, кроме DaData, и вторая — собственно под ФИАС.
Таким образом, для каждого адреса получилось 12 вариантов написаний (2 варианта «уличной» × 6 вариантов «домовой»). Все варианты написания можно посмотреть в репозитории. Ниже приведу пример:
Так для Nominatim передавалось:
Покровский бульвар, 4/17 с4Б (и «уличная» и «домовая» под OSM) — 100% родное написание
Покровский бульвар, 4/17с4Б («уличная» под OSM, «домовая» под Яндекс)
Покровский бульвар, 4/17 ст4Б («уличная» под OSM, «домовая» под 2ГИС)
Покровский бульвар, 4/17 строение 4Б («уличная» под OSM, «домовая» под Google)
Покровский бульвар, дом 4/17 строение 4Б («уличная» под OSM, «домовая» под ФИАС)
Покровский бульвар, 4/17 стр 4Б («уличная» под OSM, «домовая» под Here)
бульвар Покровский, 4/17 с4Б («уличная» под ФИАС, «домовая» под OSM)
бульвар Покровский, 4/17с4Б («уличная» под ФИАС, «домовая» под Яндекс)
…
бульвар Покровский, 4/17 стр 4Б («уличная» под ФИАС, «домовая» под Here)
А для DaData:
Покровский бульвар, 4/17 с4Б (и «уличная» и «домовая» под OSM)
…
бульвар Покровский, дом 4/17 строение 4Б (и «уличная» и «домовая» под ФИАС) — 100% родное написание
…
бульвар Покровский, 4/17 стр 4Б («уличная» под ФИАС, «домовая» под Here)
Для одного из адресов, а именно «Космодамианская набережная, 46–50 с1», иногда точка, пришедшая от геокодера, фактически была верной. Но из-за того, что, по-видимому, сервис возвращает центроид здания, она не пересекалась с заранее отобранными эталонными строениями. В таком случае я всё равно засчитывал это как корректное определение, поскольку в данной части исследования фактор точного попадания в некий слой зданий не является главным.
Результаты получились следующими:
Геокодер / формат адреса | street_speech_house_osm | street_speech_house_yandex | street_speech_house_gis2 | street_speech_house_google | street_speech_house_fias | street_speech_house_here |
|---|---|---|---|---|---|---|
nominatim |
| 8 | 4 | 2 | 0 | 2 |
gis2 | 8 | 8 |
| 7 | 8 | 8 |
7 | 7 | 6 |
| 7 | 7 | |
dadata | 9 | 9 | 9 | 8 | 9 | 9 |
here | 6 | 6 | 6 | 8 | 7 |
|
Cреднее при нечётком геометрическом пересечении | 7,8 | 7,6 | 6,8 | 6,8 | 6,2 | 7 |
Среднее | 7,4 | 7,2 | 6,6 | 6,4 | 6 | 6,4 |
Геокодер / формат адреса | street_ | street_ | street_ | street_ | street_ | street_ |
|---|---|---|---|---|---|---|
nominatim | 7 | 6 | 3 | 1 | 0 | 1 |
gis2 | 8 | 8 | 9 | 7 | 8 | 8 |
7 | 7 | 6 | 8 | 7 | 7 | |
dadata | 9 | 9 | 9 | 8 |
| 9 |
here | 6 | 6 | 6 | 8 | 7 | 7 |
Cреднее | 7,4 | 7,2 | 6,6 | 6,6 | 6,2 | 6,8 |
Среднее | 7 | 6,8 | 6,4 | 6,2 | 6 | 6,2 |
Как можно заметить, когда сервису геокодирования передавалась привычная ему и «уличная» и «домовая» часть, то все 9 из 9 адресов находились.
На самом деле это было не совсем так…
Возможно, эта проблема касается и других сервисов, но при выполнении этой части она попалась мне лишь у двух, у Google и Here.
На самом деле, если вы будете смотреть исходные файлы на GitHub, то сможете заметить, что для сочетания street_speech_house_here у геокодера Here значение будет 7, а не 9, но почему так?
Возможно, стоило исключить такие адреса или найти им замену, но мне, наоборот, показалось интереснее подсветить это момент.
Так, для Here в варианте street_speech_house_here, то есть в родном для сервиса варианте вместо адреса «Покровский бульвар, 4/17 стр 4Б» находится «Покровский бульвар, 4/17 стр 1». При этом, если выполнить обратное геокодирование по координатам строения, то Here найдёт корректный адрес «Покровский бульвар, 4/17 стр 4Б». Такая же история — с адресом «улица Воронцово Поле, 6–8 стр 4-5»




Получается, что у Here есть необходимый адрес в базе и даже координаты соответствуют реальному расположению, но при попытке найти этот адрес в точно такой же формулировке сервис не может его найти. Поэтому и результат получился 7/9.
Такая же история была и с Google, он не может найти «Нагатинская улица, 16А строение 29», вместо этого результатом является «Нагатинская улица, 16А». Но если аналогично сделать обратное геокодирование, то мы увидим необходимый адрес.
Отмечу, что 2ГИС тоже вместо «Нагатинская улица, 16А строение 29» находит «Нагатинская улица, 16а ст20», но на деле это нужное нам здание.
Исходя из полученных результатов, можно уверенно сказать, что то, как будет передана сервису геокодирования «домовая» часть адреса, влияет на точность возвращаемого результата.
Наиболее универсальным оказался вариант OSM. Поэтому при дальнейшем анализе «уличной» части адреса все адреса мы будем передавать с «домовой» частью такого формата.
Без привязки к конкретному сервису получается, что эффективнее всего передавать обозначение корпуса или строения в максимально короткой форме: «к» или «стр» вместо «корп.», «корпус», «стр.», «строение» и др.
2.2 Оценка влияния нормализации «уличной» части адреса
Второй шаг — оценить, насколько влияет нормализация «уличной» части адреса на результат геокодирования.
Но сперва добавлю немного контекста. Как-то раз появилась задача по геокодированию порядка 2 500 адресов. Адреса, как и полагается присланным со стороны данным, были «корявые». Было и по несколько строений и адресов в строке (например: «Новинский бульв. 16А, 16 стр. 2, 16 стр. 4; Трубниковский пер. 11, 13 стр. 1») и просто с «мусорными» для нашей задачи значениями (например: «Дворовая территория по адресу: Варшавское шоссе 154 к. 3, 154 к. 4»). Я с коллегами всё это причесали, сгеокодировали и бо́льшую часть успели проверить руками. Таким образом, у нас получилось 2 000 сгеокодированных точек с адресами, точность которых близка к 100%. Именно на их основе были отобраны строения из OSM и внутреннего рабочего источника, которые мы примем за эталоны для сравнения с повторно сгеокодированными результатами.
Что касается составных значений из нескольких адресов, например «Новинский бульв. 16А, 16 стр. 2, 16 стр. 4; Трубниковский пер. 11, 13 стр. 1», то в большинстве случаев сервисы находили именно первый адрес, однако встречались и иные случаи. В связи с этим для логичности сопоставления количество эталонных строений было увеличено. В данном примере ответ сервиса сравнивался с пятью строениями.
Для оценки влияния нормализации “уличной” части адреса эти 2000 адресов были сформированы в 6 вариантах написания:
Исходный (в том «корявом» виде, что он был прислан нам) например:
«Овчинниковский Б. пер. 26 стр.2, 26 стр.3, 26 стр.5, 26 стр.6; Пятницкая ул. 9/28 стр.1, 9/28 стр.3»)Адреса первой улицы
«Овчинниковский Б. пер. 26 стр.2, 26 стр.3, 26 стр.5, 26 стр.6; Пятницкая ул. 9/28 стр.1, 9/28 стр.3» → «Овчинниковский Б. пер. 26 стр.2, 26 стр.3, 26 стр.5, 26 стр.6»Форматированный
«Овчинниковский Б. пер. 26 стр.2, 26 стр.3, 26 стр.5, 26 стр.6» → «Овчинниковский большой переулок 26 с2, 26 с3, 26 с5, 26 с6»замена сокращений статусных частей названия улиц («ул.» на «улица», «пр.» на «проспект» и т. п.)
стандартизация частей дома («корп.» на «к», «стр.» на «с» и т. п.)
замена кратких форм («боль.» на «больш(ой/ая/ое/ие)», «стар.» на «стар(ый/ая/ое/ые)» и т. п.)
Статусная часть в начале адреса (так принято у ФИАС)
«Овчинниковский большой переулок 26 с2, 26 с3, 26 с5, 26 с6» → «переулок Большой Овчинниковский 26 с2, 26 с3, 26 с5, 26 с6»«Измайловское шоссе» → «шоссе Измайловское»
«Космодамианская набережная» → «набережная Космодамианская»
и т. п.
Название улицы под «речь» (принято у OSM, Яндекс, 2ГИС, Google и большинства других, как было выяснено ранее в подразделе 2.1)
«Овчинниковский большой переулок 26 с2, 26 с3, 26 с5, 26 с6» → «Большой Овчинниковский переулок 26 с2, 26 с3, 26 с5, 26 с6»«переулок Каретный большой» → «Большой Каретный переулок»
«2-я улица Владимирского» → «2-я улица Владимирского»
«улица 2-я Владимирская» → «2-я Владимирская улица»
«Кашира шоссе» → «шоссе Кашира»
и т. п.
Название улицы под «речь» (ибо спойлер чуть более удачное чем под ФИАС), но оставить только первое строение из адреса
«Большой Овчинниковский переулок 26 с2, 26 с3, 26 с5, 26 с6» → «Большой Овчинниковский переулок 26 с2»«Новинский бульвар 16А, 16 с2, 16 с4» → «Новинский бульвар 16А»
«Фурманный переулок 20, 22 с1, 22 с2» → «Фурманный переулок 20»
Также в начале каждого из вариантов добавлялось «Москва, » для улучшения результатов геокодирования.
Что касается варианта № 4, то более корректно было бы сказать, что так принято не у OSM и Яндекса, а законодательно в России, но поскольку рядом есть вариант ФИАС, то во избежание недопонимания и для сохранения контекста исследования про геокодеры, в тексте написано «под речь».
Статья №1 Федерального закона № 152 от 18.12.1997 г.
Нормализация наименования географического объекта — определение написания наименования географического объекта на государственном языке Российской Федерации и наряду с государственным языком Российской Федерации на других языках народов Российской Федерации в соответствии с правилами русской орфографии и орфографии других языков народов Российской Федерации и в соответствии с традициями употребления наименований географических объектов на указанных языках.
Для формирования пяти производных вариантов потребовалось использовать морфологический разбор слов. Это было необходимо как для корректной замены кратких форм, так и для изменения порядка слов в адресе. Для выполнения данного шага были протестированы наиболее популярные библиотеки: Natasha, spaCy (3 разных размера языкового набора), pymorphy2, Stanza, DeepPavlov. В качестве тестовой выборки были использованы 40 топонимических единиц: как сами топонимы, так и их компоненты. Они были обработаны перечисленными библиотеками, после чего оценивалось, насколько корректно библиотекам удалось определить часть речи слова и его падеж.
Итоговый рейтинг, % корректных определений:
spaCy — 91% (веса языковых пакетов: 15 МБ, 42 МБ, 513 МБ)
Stanza — 90% (640 МБ)
DeepPavlov — 87% (1,8 ГБ)
pymorphy2 — 84%
Natasha — 84%
Разница между тремя языковыми пакетами spaCy была незначительной, а в итоговом варианте теста между малым и большим вовсе не было разницы. Поэтому итоговый выбор — spaCy (small). Более подробно со сравнением данных библиотек можно ознакомиться в Jupyter Notebook на GitHub.
После того как выбрали библиотеку для морфологического разбора, необходимо было привести имеющиеся адреса к выбранным ранее пяти (помимо варианта без изменений) вариантам написания. В качестве ориентира по тому, как правильно формировать название, использовалось описание на OSM Wiki.
Теперь, когда адреса сформированы, всё готово к тому, чтобы сгеокодировать все 2 000 адресов в шести различных вариантах через выбранные 19 геокодеров, а затем сравнить результаты с эталонными строениями.
Однако есть нюанс, что как было оговорено ранее, у различных сервисов различные базы адресов и строений, поэтому и возвращаемый от них результат будет отличаться от сервиса к сервису. А даже если они и используют одну базу, например, OSM, у них может быть разная геообработка: один сервис будет выдавать точку в случайной части здания, другой — геометрический центр контура здания, а третий — точку, обязательно попадающую в контур здания. Может также оказаться, что вернувшаяся от одного сервиса точка попала в эталонное здание, а от другого сервиса лежит на метр в стороне. Поэтому для финальной оценки будет использоваться два слоя зданий:
Внутренние рабочие данные о строениях в Москве, которые являются наиболее полными и точными из имеющихся у нас источников.
Данные OSM, как наиболее доступный для всех источник.
При сравнении со строениями результаты будут причисляться к следующим группам:
Результат геокодирования лежит внутри эталонного дома.
Расстояние от результата до эталонного строения меньше 5 метров.
При присоединении точки результата к ближайшему строению она, скорее всего, присоединится к эталонному, но мы не можем утверждать это на 100%: возможно, она попадёт на соседний корпус.Расстояние меньше 100 метров.
Точка оказалась на одном из соседних строений, однако достаточно близко к эталонному, чтобы во время ручной перепроверки её можно было быстро передвинуть вручную на корректное строение, ориентируясь на картографическую подложку.Расстояние больше 100 метров или точка не сгеокодировалась.
Если точка лежит более чем в 100 метрах от нужного строения, найти необходимое строение по подложке будет затруднительно. Значит, нужно будет идти в интернет и искать, где находится этот дом, что соразмерно тому, чтобы сгеокодировать его с нуля.
Ну и теперь ура-ура к результатам!
2.3 Рейтинг лучших геокодеров на Москву
Во время сравнения была обнаружена ошибка нормализации адреса — невозможность достоверно определить, является ли сокращение «пр.» проспектом или проездом, поэтому количество адресов для итогового сравнения было сокращено до 1 873. В репозитории на GitHub вы сможете найти сравнение всех 2 000 адресов. Здесь же только те, которые не подверглись этой ошибке.
Сравнение с внутренним источником зданий

Сравнение с зданиями OSM

Из полученных результатов можно сделать следующие общие выводы:
Наиболее результативным вариантом написания оказался вариант № 6. Это подтверждает суждение, что предварительная нормализация позитивно сказывается на результате.
По большей части самому менять порядок слов в «уличной» части адреса (варианты написания № 4 и № 5 относительно № 3) не имеет смысла: сервисы геокодирования сами успешно справляются с этой задачей.
Идеально справляются: DaData, Esri, 2ГИС, Here, Photon.
Справляются ужасно: NetToolKit.
3. Наиболее влияющий на точность геокодирования этап — замена символов корпусов/литер в «домовой» части адреса и раскрытие сокращений («ул.» → «улица», «боль.» → «большой»), то есть приведение к варианту написания № 3.
Хотя и здесь можно было бы пойти дальше и определить, какой из этих этапов вносит наиболее существенный вклад, а какие лишь увеличивают объём затрачиваемых усилий, при этом давая меньший эффект. Но моих сил на это уже не хватило.
4. Вполне ожидаемо оказалось, что передавать адрес с одним домом на одной улице куда лучше, чем с несколькими домами: «Новинский бульвар 16А, 16 с2, 16 с4» → «Новинский бульвар 16А».
Уже на финишном этапе написания статьи меня осенило, что хорошей парой адрес — здание, могли бы выступить данные с портала ГИС ЖКХ, так как в их атрибутивном составе прописан и адрес, и кадастровый номер. А раз есть кадастровый номер, то результаты геокодирования ГИС ЖКХ можно было бы сравнить с контурами строений из Кадастровой карты. Но, с другой стороны, исследование на случайных адресах, не имеющих столь прямых намёков на расположение, думается мне, выглядит репрезентативнее.
Тут мог бы быть финальный вывод с учётом качества сервисов и их ограничений, но сперва я предлагаю сделать ещё два сравнения. В том числе рассмотреть тематические сценарии использования.
Первое из них родилось у меня посредством личного опыта. Во время одной из рабочих задач мне показалось, что 2ГИС куда хуже справляется с геокодированием снесённых строений. Ну я и решил это проверить. Для анализа были взяты данные с сайта московской программы реновации и отобраны уже снесённые строения. К сожалению, дата сноса в наборе данных не указана, поэтому взял все объекты, которых было 821, отбросил пару «стрёмненьких» с пустыми полями или нестандартными записями, вышло в 800 адресов. Сгеокодировал через топ-14 сервисов без какой-либо нормализации адреса, взял адрес с сайта реновации в исходном виде — и вот что вышло.

Вполне закономерно оказалось, что геокодеры, использующие только OSM, дали нулевой результат, так как удалённые в OSM объекты никто хранить не будет. Но для эксперимента это даже хорошо: всегда есть вероятность, что снесённый дом ещё не успели удалить в OSM и адрес не находится не потому, что его уже нет, а потому, что его не находит сервис. Однако, учитывая, что количество найденных домов стремится к нулю, можно предположить, что их снесли уже достаточно давно и даже OSM успели отредактировать (персонально радуюсь работе сообщества 😊). А раз дома снесены уже достаточно давно, то и результаты теста можно считать корректными. Первичное предположение оказалось верным, 2ГИС не лучший кандидат для решения этой задачи. Лучший результат показал сервис DaData, следом за ним Here и Google.
Однако такой хороший результат как в этом, так и в общем сравнении у ушедшего в 2022 году из России Here вызвал у меня вопрос «А что, если их база просто перестала обновляться?». В случае с Google я могу представить, что сообщество как-то может помогать в обновлении, а вот Here… Помню, в 2021 году они активно набирали студентов (коим я сам тогда являлся) на летние практики в том числе для редактирования карты.
Для проверки гипотезы, что некоторые геокодеры могут быть неактуальны, я отобрал 20 домов, построенных недавно.
Проще всего было найти ЖК, используя сервисы: Узнай про ЖК и Домклик. Отобрал как строения, построенные уже относительно давно, в 2023 году, так и те, что были сданы в эксплуатацию лишь в 2026-м.
Поскольку в проверке этой гипотезы важно было проверить лишь сам факт наличия новых строений, точка, вернувшаяся от геокодера в метре-двух от контура дома, вручную передвигалась внутрь контура.

Строения, снесённые в последние 4 года
Как видно, лучше всех справился 2ГИС, что немудрено: сервис следит за новостройками, порой 3D-модели строений отображаются на карте ещё на этапе строительства первых этажей. Но и OSM уступает чуть-чуть! (снова радуюсь 😊).
Что же касается Here, ради которого всё и затевалось, то кажется каким-то образом данные всё-таки обновляются, но как — неясно. Например, дом по адресу «Москва, 2-й Нагатинский проезд, 2/2 к1», сданный в 2023 году, сервису найти не удалось, зато «Москва, улица Братьев Фонченко, 1 к2», адрес которому присвоили только в январе 2025 года нашёлся.
При этом, как и в случае со снесёнными домами, хорошо, что есть явные аутсайдеры в лице Esri и Google. Это дополнительно подтверждает, что 13 корректных у Here — не случайное стечение обстоятельств.
И вот теперь выводы!
Топ-геокодеров для Москвы
Сухая статистика
№ | Сервис | Всего | Внутри дома | ≤ 5м | ≤ 100м | > 100м или не сгеокодировано | Внутри дома, % | ≤ 5м, % | Внутри дома и ≤ 5м | Внутри дома и ≤ 5м, % |
1 | gis2 | 1873 | 1700 | 130 | 16 | 27 | 90,76 | 6,91 | 1830 | 97,68 |
2 | dadata | 1873 | 1505 | 296 | 54 | 17 | 80,35 | 15,83 | 1802 | 96,18 |
3 | here | 1873 | 1726 | 57 | 26 | 64 | 92,15 | 3,04 | 1783 | 95,19 |
4 | geoapify | 1873 | 1694 | 25 | 22 | 132 | 90,44 | 1,33 | 1719 | 91,78 |
5 | opencage | 1873 | 1680 | 18 | 42 | 134 | 89,7 | 0,93 | 1698 | 90,63 |
6 | nominatim | 1873 | 1648 | 18 | 48 | 160 | 87,96 | 0,96 | 1666 | 88,92 |
7 | photon | 1873 | 1630 | 20 | 59 | 163 | 87,05 | 1,09 | 1651 | 88,15 |
8 | locationiq | 1873 | 1580 | 59 | 110 | 124 | 84,36 | 3,15 | 1639 | 87,51 |
9 | nettoolkit | 1873 | 1518 | 34 | 44 | 277 | 81,05 | 1,84 | 1552 | 82,89 |
10 | graphhopper | 1873 | 1503 | 21 | 55 | 294 | 80,25 | 1,12 | 1524 | 81,37 |
11 | 1873 | 1316 | 182 | 204 | 172 | 70,23 | 9,69 | 1497 | 79,93 | |
12 | pelias | 1873 | 1013 | 458 | 127 | 274 | 54,08 | 24,48 | 1472 | 78,56 |
13 | positionstack | 1873 | 1012 | 442 | 128 | 291 | 54 | 23,6 | 1454 | 77,6 |
14 | esri | 1873 | 1321 | 82 | 165 | 304 | 70,53 | 4,4 | 1404 | 74,93 |
15 | mapbox | 1873 | 938 | 19 | 414 | 502 | 50,08 | 1,01 | 957 | 51,09 |
16 | tomtom | 1873 | 720 | 80 | 545 | 528 | 38,41 | 4,27 | 800 | 42,69 |
17 | maptiler | 1873 | 678 | 75 | 468 | 652 | 36,2 | 4 | 753 | 40,2 |
18 | mapquest | 1873 | 35 | 214 | 1560 | 64 | 1,87 | 11,4 | 248 | 13,27 |
19 | gisgraphy | 1873 | 191 | 29 | 189 | 1464 | 10,2 | 1,55 | 220 | 11,75 |
2ГИС и Here
Первое место делят между собой 2ГИС и Here. Я не смог выделить между ними выбрать однозначного фаворита.
В общем сравнении Here незначительно опережает 2ГИС, если рассматривать только 100% попавшие точки. Если же учитывать в пределах 5 м, то Here уже незначительно уступает.
Для геокодирования снесённых строений Here подходит лучше, а вот для новостроек — хуже.
С одной стороны, доступ к геокодеру 2ГИС получить нетрудно: достаточно оформить аккаунт и подписку (кажется, ещё пару месяцев назад такой возможности не было: нужно было обсуждать детали с менеджером). С другой стороны, результаты всё равно нельзя сохранять и обрабатывать… У Here без индивидуального коммерческого плана сохранять результаты тоже нельзя, зато есть большой бесплатный лимит на количество запросов в месяц и результаты можно кэшировать. Как итог — это хороший выбор для поиска на сайте.
В любом случае с юридической точки зрения для автоматизированной обработки ни один из этих сервисов не подходит.
С технической же стороны…, а в случае с Here, которые вам вряд ли сейчас оформят индивидуальную подписку, — то и юридически… Как говорится: «Что ты мне сделаешь, я в другом городе государстве за мат извени».
2.DaData
Если рассматривать только 100% попадания внутрь дома, то сервис явно не на 2-м месте, а на 9-м. Но с учётом точек, которые попали в пределы 5 метров, он занимает вторую позицию. И, по визуальному анализу, доля тех, что при пространственном присоединении попадёт на некорректный дом, крайне мала.
Иллюстрация разницы в 5 метров

Да и снесённые строения находит хорошо. Новые строения находит средне, но что поделать… Думаю, это связано с привязкой к государственной ФИАС и с тем, что без всех утверждений адрес не добавишь.
DaData очень хорошо справляется с самостоятельной нормализацией адреса, наравне с 2ГИС, а это очень важный фактор в плане экономии времени на самостоятельную обработку!
Цены за геокодирование адекватные: списание идёт за каждую запись, а не по подписке, поэтому ограничений по количеству нет. Ещё и автоматическая обработка с сохранением разрешена! Также у сервиса немалый и полезный набор возвращаемых полей помимо адреса, что несомненно, весомый плюс.
Таким образом, для автоматизированного геокодирования DaData подходит лучше всех.
3. Geoapify, Photon, LocationIQ, OpenCage, Nominatim
Разместить эти сервисы по конкретным местам не вышло, ибо разница между ними незначительна, а итоговое место для вас может зависеть от ряда факторов:
Качество: если сравнивать лишь по 6-му варианту написания, то порядок будет: Geoapify, OpenCage, Nominatim, Photon, LocationIQ. Но если посмотреть как сервисы справляются с нормализацией, то ранжирование будет уже другим: Geoapify, Photon, OpenCage, Nominatim, LocationIQ.
Важным плюсом является то, что Geoapify, LocationIQ старается сохранять снесённые дома. Хотя, возможно, они просто редко обновляют свою базу (если не OSM) на Россию. Photon что-то помнит, что-то нет, а OpenCage и Nominatim о снесённых строениях ничего не помнят.
Количество запросов в день: у Nominatim и Photon нет никаких ограничений, у LocationIQ, Geoapify и OpenCage лимиты есть, но они адекватные: 5 000, 3 000 и 2 500 запросов в день. Плюс ограничений в том, что, поскольку сервисы более закрытые, даже при ограничении в 1 запрос в секунду, как у Nominatim и Photon, оно более надёжное. Исходя из личного опыта при массовом геокодировании Nominatim может начать выкидывать timeout-ошибку. А при очень обильном использовании (кажется, когда-то давно у меня такое было, но могу и соврать) — заблокировать на сутки.
Возможность сохранять результаты есть во всех, но у LocationIQ нельзя ими делиться.
4. GraphHopper, NetToolKit, Google
В данном случае можно было дать детальные места, но мне понравилась идея ранжировать несколько схожих по результатам геокодеров одним местом.
Лучше всех с нормализацией адреса в этой тройке справляется Google, потом GraphHopper, потом с заметным отставанием NetToolKit.
GraphHopper в отличие от NetToolKit каким-то образом сохранил несколько строений, NetToolKit уже нет, а Google просто не обновляется и это странно считать за плюс. GraphHopper также лучше и в новостройках.
Лимиты у Google больше, но чтобы зарегистрироваться на платформе придётся помучаться. У GraphHopper и NetToolKit лимиты очень скромные, а у GraphHopper ещё частота запросов порядка раз в 2–3 секунды (за всё данное исследование он бесил меня этим больше всех).
Из минусов Google помимо трудностей получения ключа и отсутствия обновлений — возможность сохранения результатов без платной подписки.
Другие сервисы я бы использовать не стал ввиду низкой доли корректных результатов. Да и сервисы из топ-4 — тоже: расписал их на крайний случай.
3. Презентация инструмента проверки достоверности результатов
Хорошо, теперь мы знаем лучшие сервисы для геокодирования в рамках Москвы. А возможно и в целом по России, но без дополнительной проверки утверждать это нельзя. Однако часть вопросов из вступления всё ещё остались без ответов.
А даже если мы и определим сервис геокодирования, который в проведённом сравнении даст хороший процент корректных ответов, условно 90%, как при запуске на новых адресах понять, какие объекты были определены корректно, а какие нет? И какая доля корректных относительно всех переданных для геокодирования объектов?
Глядя на иллюстрацию с результатами, я понял, что у нас довольно много геокодеров, которые хорошо справляются со своей задачей: доля верных ответов у них выше 80%, и при различных условиях и ограничениях в целом можно использовать любой из них. Так почему бы не использовать тогда их все для кросс-валидации? Так я и поступил и сделал инструмент, который:
Выполняет базовую нормализацию адреса (вариант написания № 3), поскольку, как выяснилось, с «перетасовыванием» слов сервисы и сами отлично справляются.
Геокодирует нормализованные адреса с помощью нескольких сервисов.
Сравнивает результаты всех сервисов с полигональным слоем строений и на основе количества совпадений формирует четыре выходных файла:
i. Точки, которые, как мы считаем, сгеокодировались корректно и не требуют проверки.
Это значит, что результаты всех выбранных сервисов оказались в одном доме.ii. Точки, которые, скорее всего, определились корректно.
Это значит, что лучший, он же референсный, геокодер нашёл результат и мы ему в целом доверяем, но другие сервисы выдали точку не в том же здании: возможно, улетели на пару метров от дома или на соседний корпус.iii. Точки, которые имеют дубликаты по геометрии.
Это может значить, что одна из них определилась корректно, а вторая — нет, или что ни одна из них не определилась корректно.iv. Точки, которые даже наш лучший геокодер не смог найти.
В данном случае можно было бы взять непустой результат другого геокодера, но логичнее считать, что, если лучший не нашёл, то и другой либо не нашёл, либо нашёл абы что.
Созданный инструмент находится в репозитории в разделе /geocoding_script.
Таким образом, нам необходимо перепроверить вручную только определённую часть адресов, а не все. Это существенно экономит время выполнения рутинной операции. На примере рассматриваемого набора данных из 1 873 адресов количество полностью корректных адресов — 1 521 (81,2%), необходимо перепроверить — 349 (18,6%), необходимо найти вручную — 3 (0,2%).
И это результаты без прилипания точек к ближайшим зданиям (например, тех, что находятся на расстоянии ≤ 5 м).
На мой взгляд, это успех!
Результат выше получен при использовании в качестве эталонного геокодера — 2ГИС, а в качестве валидирующих: Here, Geoapify.
В качестве валидирующего использовать Here можно, если вы удалите полученные результаты в течение 30 дней. Если же использовать его в качестве эталонного, то полученная от сервиса геометрия, я уверен, останется с вами более чем на 30 дней, что уже будет нарушением политики использования. Во всяком случае так я понял правила использования, ссылка на которые была в разделе № 1 в таблице описаний условий сервисов.
Наличие этого сервиса, кстати, очень сильно выручает в случае, если нет доступа к 2ГИС. Ведь в таком случае в качестве эталонного использовался бы DaData, а если бы не было Here, то валидирующими были бы сервисы либо на 100% основанные на OSM, либо, скорее всего, также его использующие. Это приводило бы всю валидацию лишь к проверке относительно OSM. А так у нас есть ещё одна база строений, которая если и использует OSM, то, наверное, не так обильно.
Конец! 🎉🎉🎉
Послесловие
Стоит отметить, что даже 1 873 адреса для Москвы — это весьма небольшая выборка, и есть шанс, что на более обширном адресном перечне результат изменится. Однако у меня больше не было столь масштабных потребностей что-либо геокодировать, чтобы увеличить эту выборку. Так же, как и не было данных для исследования вне Москвы. Если у вас есть наборы данных подобного рода (или вы можете подумать о связке ГИС ЖКХ — ПКК, как я описывал ранее), вы можете самостоятельно повторить исследование, используя наработки с GitHub, и поделиться своим результатом в комментариях — это существенно дополнит данную статью!
