Ариадна. Зачем Нам Нужен Еще Один Геокодер Для Osm?

Всем привет! Буквально недавно я закончил делать геокодер для своих целей Ариадна Под катом рассказ о том, почему я это сделал и на что он способен.

В этой статье не будет ни строчки кода Go. Зато будет полное описание работы геокодера и проблем, с которыми я столкнулся.

И вы можете посмотреть код на Github.



Фон

Я работаю в одной из служб такси Бишкек в Кыргызстане.

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

Чего у нас нет:

  • Полная карта Яндекса, Гугла или 2ГИС
  • Доверяйте данным GPS
Что мы имеем:
  • Очень разнообразные входные данные
  • Openstreetmap
  • Собственная накопленная база адресов с координатами


Что могут ввести пользователи?

Пользователи могут вводить адреса в разных форматах:
  • Уличный дом
  • Перекресток
  • Название заведения
  • Имя точки
  • микрорайонный дом
  • микрорайон улица дом
И таких вариантов очень много, например Киевская 28 Киев Советская 5-42 5 мкр Советская 42 ЦУМ кафе у Ашота барьер И так далее

Постановка задачи

Создать геокодер, который сможет принимать любые входные данные и выдавать им координаты.

Язык поиска только русский.



Как вы попали в эту жизнь?

Прежде чем сделать свой велосипед, я решил посмотреть на уже существующие решения.

Были:

Что нам не понравилось в номинации, которую мы получили:
  • Сложно само по себе
  • Сделано на PHP+C (Это не потому, что PHP плохой, а потому, что только для этого инструмента у нас есть Apache и PHP)
  • Сложная логика в хранимых процедурах Postgresql
Что мне понравилось в Пелиасе:
  • Может работать со многими источниками геоданных
  • Поиск организован на ElasticSearch.
В итоге я решил отказаться от всех трёх геокодеров и сделать свой инструмент по нескольким причинам:
  1. Я хочу отсортировать данные в OSM и импортировать только то, что нужно для поиска.

  2. Я могу обрабатывать геоданные перед их индексацией
  3. Яваскрипт и node.js не люблю, отсюда и отсутствие желания делать поиск по Пелиасу


Дизайн

Был заложен следующий алгоритм:
  1. Сначала получаем геометрию для крупных населенных пунктов (городов, столиц, сел, жилых массивов)
  2. Выгружаем все возможные адреса и соотносим их с желаемым жилым районом, городом или другим населенным пунктом, задавая нужное значение
  3. Разгрузка всех дорог
  4. Ищем перекрёсток дорог
  5. Ставим все в индекс
  6. Ищем
Для реализации я выбрал Go, учитывая такие проекты, как pbf2json , голанг-гео и многие другие для обработки геоданных.

Я также хотел улучшить свои навыки в этом.



Выполнение

Кажется, я разобрался, как получать и анализировать данные из OSM. Для жилых районов для фильтрации мы используем теги Place=city,place=village,place=suburb,place=town,place=neighborhood. Чтобы получить адреса, здания: адрес:улица+адрес:номер дома,удобства,магазин,адрес:номер дома Все дороги можно получить с помощью тега шоссе.

Были трудности с поиском англоязычных имен на русском языке.

Как я пытался это решить:

  1. Простая автоматическая транслитерация на русский язык.

    В результате получилось абсурдно и неправильно.

    Пример преобразования данных: Городской Дом -> Городской Дом.

  2. Попробуем конвертировать вот так.

    Получите транскрипцию слова и затем транслитерируйте его.

    Получилось что-то вроде Adrenaline Rush -> Эrdenaline Rush. Сносно, но нужен русский акцент, например Adrenaline Rush.

  3. Такой механизм появился.

    Мы автоматически транслитерируем все данные, используя словарь замены.

    Тем не менее, простая и глупая транслитерация работает вполне сносно.

    Словарь быстро заполнился после нескольких прогонов данных.

К этому моменту мы с этим разобрались и уже получаем данные, которые:
  1. Нормализовали и довели до русского языка
  2. адреса указываются в формате Страна, город, село или поселок, микрорайон или жилой район, улица, дом
Следующая часть квеста — поиск перекрестков дорог.

Я сделал это быстро и получил очень медленную реализацию со сложностью O(n^2).

В качестве временного решения я использую Postgres+postgis для поиска пересечений, пока не найду хороший алгоритм поиска пересечений.

В результате получается хороший парсер данных с osm, который помещает данные в ElasticSearch. Получивший простое название импортер

Автоматизируйте это

Учитывая, что мне вскоре надоело постоянно выкачивать и создавать индексы в ElasticSerch, появился компонент обновления.

Также есть автоматическая конфигурация в формате JSON. Автоматизирован процесс скачивания файла и импорта его в Elastic Search. Плюс появилась возможность обновлять данные в ElasticServch без простоев, благодаря псевдонимам.

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

  1. Программа обновления загружает файл
  2. Узнает текущую версию индекса из конфига
  3. Увеличивает версию и создает новый индекс
  4. Заполняет его данными
  5. Изменяет псевдонимы
  6. Удаляет старый индекс
Благодаря этому я получил следующие преимущества:
  1. Написание конфигурации
  2. Запустите обновление .

    /ariadna

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

Также для удобства я добавил простой веб-интерфейс с картой и функцией поиска.



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

Помимо OSM у нас еще много водителей и операторов, которые оформляют заказы.

Соответственно, у нас есть имя и координаты.

Была сделана следующая схема:

  1. Треки драйверов хранятся в индексе driver_data.
  2. Данные из OSM хранятся в индексе osm_data.
  3. Их объединяет адрес-псевдоним, который используется для поиска адресов.

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



Общий

В результате получается геокодер, который может:
  1. Найдите координаты, используя синонимы.

    например ШВК - ШампанскоеВинКомбинат

  2. Может искать адреса в определенном радиусе (например, для себя делал поиск адресов в 30 км от центра города)
  3. Поиск по названию заведения (кафе у Ашота например)
  4. Поиск пересечений
  5. Поиск адресов в микрорайонах и спальных районах
  6. Выполнить обратное геокодирование
  7. Будет автоматически обновляться новыми данными от водителей.

Состоит из трех компонентов:
  1. Импортер данных
  2. Средство обновления данных
  3. веб интерфейс


Минусы

  1. Протестировано только для Кыргызстана.

  2. Нет демо
  3. Нет поддержки всех схем адресации.

Поэтому надеюсь, что кто-нибудь поможет мне дочитать ее и на хороший поиск в других странах и городах.

Если кому-то проект покажется интересным, то я не против никакой критики, пула запросов, вопросов на Github и отзывов в целом.

Теги: #поиск #геокодирование #обратное геокодирование #osm #OpenStreetMap #OpenStreetMap #Go #Геоинформационные сервисы

Вместе с данным постом часто просматривают: