Найти тему
Mad Devs

Ariadna. Open Source геокодер для данных

Оглавление
карта Бишкека
карта Бишкека

Процесс создания геокодера на основе ElasticSearch, который ищет координаты по синонимам и по названиям заведений, ищет перекрестки и адреса в определенном радиусе, а также умеет делать реверс геокодинга и автоматически пополняется новыми данными от водителей. Репозиторий доступен по ссылке.

-2

Предыстория

Когда мы проектировали геокодер для нужд Namba-Taxi мы столкнулись с недостатком важных данных.

Чего у нас не было:

  • Полной карты от Яндекса, Google или 2GIS
  • Доверия к GPS данным

Что у нас было:

  • Очень разношерстные данные на входе
  • Мы кое-где использовали Openstreetmap
  • Своя накопленная база адресов с координатами

Что операторы могли вводить?

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

  • Улица дом;
  • Перекресток;
  • Название заведения;
  • Название точки;
  • Микрорайон дом;
  • Микрорайон улица дом.

И таких вариантов очень много, например:

  • Киевская 28
  • Киевская Советская
  • 5–42
  • 5 микрорайон советская 42
  • ЦУМ
  • кафе у Ашота
  • шлагбаум

Проектирование

Был заложен следующий алгоритм:

  • Сначала получаем геометрию по крупным населенным пунктам(города, столицы, деревни, жилые массивы);
  • Выгружаем все возможные адреса и соотносим их к нужному жилому массиву, городу и другому населенному пункту, выставляя нужное значение;
  • Выгружаем все дороги;
  • Ищем пересечение дорог;
  • Кладем все в индекс;
  • Ищем.

Реализация

Учитывая то, что основной источник данных у нас это OSM, то фильтры для того, чтобы получить данные у нас такие:

  • place=city,place=village,place=suburb,place=town,place=neighbourhood — для получения всех микрорайоны
  • addr:street+addr:housenumber,amenity,shop,addr:housenumber — для получения адресов и названий заведений
  • highway — для получения всех дорог

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

  • Простая автоматическая транслитерация в русский. В итоге получалось абсурдной и не корректной. Пример конвертации данных был таким: City House -> Цити Хоусе
  • Получение транскрипции слова и уже ее транслитерация. Получилось что-то вроде Adrenaline rush -> Эрденалин Рэш. Сносно, но нужен русский акцент, типа адреналин раш. Не подходит.
  • Автоматическая транслитерация всех данных, с применением словаря замен. Подошел именно такой механизм. Все-таки простая транслитерация работает сносно. В итоге словарь наполнился в принципе быстро через несколько прогонов на данных.

С этим разобрались к этому моменту мы уже получаем данные, которые:

  • Нормализированы и приведены к русскому языку;
  • Адреса приведены к формату — страна, город, село или поселок, микрорайон или жилой массив, улица, дом

Следующая часть квеста — найти пересечения дорог. Сделали ее по-быстрому и получили очень медленную реализацию, сложностью O(n²). Как временный выход использовал Postgres+postgis для нахождения пересечений, пока не нашел хорошего алгоритма для поиска пересечений.

В итоге получился хороший парсер данных с OSM, который кладет данные в ElasticSearch. Который получил простое название importer.

Автоматизация

Учитывая то, что постоянно выкачивать и создавать индексы в ElasticSearch в скоре надоело, появился компонент updater. Появилась также автоматическая конфигурация в JSON формате.

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

Как это работает:

  • Updater качает файл;
  • Узнает текущую версию индекса с конфига;
  • Инкрементит версию и создает новый индекс;
  • Заполняет его данными;
  • Меняет алиасы;
  • Удаляет старый индекс.

Получил такие бенефиты от этого:

  • Пишем конфиг;
  • Запускаем ./ariadna update;
  • Идем пить кофе;
  • Получаем готовый настроенный индекс.

Также для удобства прикрутил простой вебинтерфейс с картой и возможностью поиска.

Автоматическое пополнение данными

Помимо ОСМ у нас еще есть много водителей и операторы, которые забивают заказы. Соотвественно у нас есть имя и координаты Сделана такая схема:

  • Треки водителей хранятся в индексе drivers_data;
  • Данные с ОСМ хранятся в индексе osm_data;
  • Объединены они через алиас addresses по которому и происходит поиск адресов.

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

Заключение

Что умеет геокодер Ariadna?

  • Искать координаты по синонимам. например ШВК — ШампанВинКомбинат;
  • Умеет искать адреса в определенном радиусе (например для себя с сделал поиск адресов в 30 км от центра города);
  • Искать по названию заведений (кафе у Ашота например);
  • Искать перекрестки;
  • Искать адреса в микрорайонах и жил массивах;
  • Делать реверс геокодинг;
  • Автоматически пополнятся новыми данными от водителей;
  • Реверс геокодинга.
поиск по адресу
поиск по адресу
реверс геокодинга
реверс геокодинга

Из каких компонентов состоит геокодер:

  • Импортер данных;
  • Апдейтер данных;
  • Веб интерфейс.

Минусы

  • Протестирован только для Кыргызстана;
  • Нет демки (Хотя работу его можете увидеть в приложении Namba-Taxi, когда мы определяем ваш адрес по местоположению);
  • Нет поддержки всех схем адресации.

Поэтому будем рады, если кто-нибудь поможет его допилить и для хорошего поиска по другим странам и городам.

Если кому-то проект показался интересным, то мы не против любой критики, пул реквестов, issues на гитхабе и фидбека в целом.

Ранее статья была опубликована тут.