Комментарии 23
ArcGIS судя по всему просто использует модуль PostGIS, т.е. можно было бы просто загнать данные карт в локальный постгрес и потом выбирать напрямую из него по координатам с помощью ST_Intersects, ST_CoveredBy, ST_Within и тд. Эта схема относительно легко масштабируется.
Но вообще вариант взять координаты из базы ArcGIS рассматривался, и был отброшен, потому что наша база не обновляется — денег не заплатили.
Не совсем понял, что мешает залить в базу тот же OpenStreetMap, придется конечно немного поразбиратся, куда без этого. Сейчас многие БД предоставляют возможности работать с гео данными, даже SQLite можно поднять в памяти с соотв. расширением. Вопрос сводится к следующему, будет ли реализация реверс геокодинга на хадупе/спарке, быстрее/проще/лучше, чем аналогичная (и уже готовая) реализация в одной из таких БД? Причем сама БД статическая, скопировал на вторую машину запустил и получил гарантированный х2 перформанс.
Сможете назвать парочку готовых?
>Причем сама БД статическая
Вообще-то нет. База адресов и POI вовсе не статическая, и процесс ее периодического обновления далеко не такая простая вещь, как может показаться. Особенно если вы берете данные из OSM — в этом случае очень желательно свои данные туда же и возвращать.
>быстрее/проще/лучше, чем аналогичная
Описывал я это все вовсе не как готовое решение, которое проще или лучше (хотя оно и сильно быстрее многих), а как подход, позволяющий быстро реализовать такое самостоятельно. Цели сделать лучше не ставилось, и далеко не очевидно, что именно тут считать лучшим.
Развертывание нескольких машин с Postgres вполне возможно, но мне не кажется решением без недостатков. Основной из которых в том, что если задачи геокодирования это лишь малая часть задач кластера (а у нас именно так), то отдельный Postgres — это отдельная немаленькая морока по администрированию. Он либо работает постоянно, потребляя ресурсы когда не нужен, либо надо как-то организовать его запуск по требованию. А так да, вполне себе решение. У нас были планы развертывания ArcGIS с его базой внутри кластера, для этих целей — и в частности по этим же причинам они не реализованы (там еще и лицензии примешиваются).
>Не совсем понял, что мешает залить в базу тот же OpenStreetMap, придется конечно немного поразбиратся, куда без этого.
Ничего не мешает. Про это — следующий пост, который уже ждет своей очереди.
В смысле, я пока рассказал идею, как это сделать вручную самому, в 400 строк своего кода на Spark. Про то, что есть другие инструменты, в том числе пригодные для применения в кластере — возможно расскажу в следующий постах.
С Lucene заранее например индексируем точки городов мира отсюда, а потом загружаем на каждом Executor в Spark и опрашиваем.
Поиск в радиусе на индексе из ~3 млн точек и точности в ~1 метр берет окоро 2 мс на запрос. А вот поиск топ ближайших городов работает значительно медленнее 700-1000 мс на запрос, т.к. индекс по всей видимости не используется.
В том, чтобы сделать обратный геокодер в виде примерно 400 строк кода. Я никого не убеждаю, что надо делать именно так, это просто был пример проблем, которые приносит с собой масштаб, и как их можно быстро решить.
Что до точек — то в моем понимании с точками все сильно проще. Расчет расстояния между точками — это константное время, ну может чуть-чуть сложнее, чем на плоскости. Уже для улиц это не так. Ваш пример вполне применим для домов, например, если считать их точками (в реальности в OSM далеко не все дома точки, но построить некий центр для дома вполне можно заранее).
Мы реально смотрели в сторону Solr, но скорее для задачи прямого геокодирования, там это нужнее.
Собственно, главный вывод из этой истории состоял в том, что нужно попытаться построить spatial индекс в том или ином виде, а иначе будет плохо. Ну и как бы GeoSpark это умеет. В целом же нам GeoMesa чуть больше понравилась, хотя порог входа наверное чуть выше.
И да, геохеш на самом деле я зря не упомянул, потому что это по сути одна из альтернатив quad tree.
Довольно здорово дела упрощает ещё алгоритмическая сетка — заказчик был из Токио, там у них есть такая Japan Mesh. Она иерархическая, зависит только от координат, и её можно использовать сразу как индекс. В будущем планируем заюзать что-то такое же, только для всего мира.
А во-вторых, что важнее, там слишком много вариаций записи, и если обратное геокодирование делается достаточно примитивно, то прямое — это уже ужас-ужас.
Или дата аналитик как-то сам подготавливает портянку аутлайнов в geojson с метаданными по адресам, или ячейками грида, или чем-то другим, что нужно для текущей карты. Откуда он их берёт, кроме OSM, я, если честно, не интересовался.
Ваша задача звучит посложнее.
Ну, у нас есть похожий проект в другом департаменте, связанный с оценкой стоимости недвижимости, если его совсем просто описать. При этом резонно считается, что стоимость объекта очень сильно зависит от локации, и эта локация — примерно квартал. Ну и что вы думаете — сидят люди, и руками эти самые кварталы рисуют, потому что нигде их нет, ни на одной карте. Теоретически можно попытаться построить их по улицам, например, но эта задачка как минимум уровня построения маршрутов, и я пока слабо себе представляю, как ее решать.
А наша задачка — она не то что сложнее, она просто другая. Прямое геокодирование, если его делать по уму, включает приличный объем NLP. И это совсем не геометрия.
Как геокодировать миллион точек на Spark по-быстрому?