Улицы vs Дороги

Всем привет!

Занимаюсь разработкой картографического сервиса.

Перед сервисом стоит ряд задач:

  • показывать на карте Страны/Области/Города/Районы
  • в виде вложенного дерева Страны/Области/Города/Районы
  • получать адрес в виде списка из тегов страна+область+город+район по точке, имея lon, lat и обратно

С помощью osm2pgsql сконвертировал pbf файлы в postgis таблицы. Успешно решаю поставленные задачи с помощью мультиполигонов. Стала задача уточнить схему адреса с помощью улиц: Страны/Области/Города/Районы/Улица/Площади/Переулки, etc.

Начались проблемы:

  • дорога (road) - это набор ломаных линий, не (мульти)полигон
  • ближайшие к дороге точки (как и полигоны зданий) могут иметь tags->‘addr:street’ отличный от имени дороги
  • часть зданий обозначены точками, а часть полигонами
  • не все здания вдоль дороги имеют то же название улицы, что и улица дороги
  • разброс зданий с одним и тем же названием улицы по разные стороны от дороги может быть существенным, поэтому нельзя просто построить мульти-полигон, базируясь на мульти-линии дороги, расширив линию с помощью ST_Buffer
  • одно и то же здание может принадлежать разным улицам и быть ближе только к одной из соседних/пересекающихся/параллельных дорог либо на одинаковом расстоянии от них

В целом ясно, что улица и дорога - не одно и то же. Сервис должен работать в масштабах мировой карты. Традиции пометки зданий полигонами или точками отличается от страны к стране.

Это называется геокодирование, прямое и обратное.
Для этого обычно делают специализированные сервисы, например Nominatim.
Написать адекватный геокодер - это задача сложная, в том числе и из-за озвученных вами проблем.
Тут уже пытались написать поисковик более приспособленный к российским реалиям, можете посмотреть его исходники - https://forum.openstreetmap.org/viewtopic.php?id=14295
Но в рамках всей карты он может и не заработать, потому как в разных странах часто используется разная схема адресации и все эти особенности нужно учитывать.

Спасибо за ваш ответ. Знаю как это называется, описал подробно, потому что номера домов мне не требуются, от распространенных нотаций записи адреса это отличается. Nominatim - о нем мне то же известно, но он с этой задачей справляется плохо, как, впрочем, и google maps, mapbox, etc.

Раз уж речь зашла об использовании данных сервисов геокодирования: у них есть серьезные проблемы в адресах с разными названиями для одних и тех же географических объектов и привязке к именам объектов и др. произвольным идентификаторам как то google place id, а не к их физическим характеристикам i.e. координатам. Несколько лучше обстоит дело с mapbox-id, но, насколько мне известно, он привязан к lon,lat + ISO-3166-1 коду страны.

В своем сервисе я эту задачу решил вычислением 8-значного geohash для каждого мультиполигона (что дает достаточную точность, исключая необходимость геокодирования отдельных зданий/участков). geohash является уникальным идентификатором региона на карте. К нему уже привязывается название/перевод/транслитерация для всех поддерживаемых локалей.
Также есть траблица отношений parent-children. Потомков вначале искал рукурсивным поиском полного вхождения геометрий, затем заменил полное вхождение на 3 sigma overlapping, чтобы нивелировать искажение на границах.

Топик создавался скорее для обсуждения проблем использования улиц в геокодировании, чем для поиска готовых решений (хотя буду благодарен, если кто-то скажет, что такие есть).

Сейчас в качестве одного из решений я вижу использование мултистрок дорог: (highway=*) с нахождением ВСЕХ ломаных дорог, пересекающих круг с центром в искомой точке и радиусом r, выбранным эмпирически и превышающем предел погрешности. i.e. точке на карте соответствует конечное множество нескольких равнозназначных по смыслу идентификаторов дорог, проложенных поблизости. Можем рассматривать эти дороги/улицы не как элементы адреса, а как доступные объекты инфраструктуры, которыми они по сути и являются. Осуществляя прямое геокодирование, пользователь может указать любую из соседних с точкой дорог. При обратном геокодировании можно перечислить список соседних дорог/улиц и пр. ориентиров вместо привычного всем адреса. Это даст возможность искать объекты рядом с нужной улицей, что и должен решать сервис.

Насколько это будет удобно для большинства людей? С радостью приму вашу критику.

Ihor Nahuliak

Непонятно, о чем тема или что критиковать.

В третьем посте темы указан какой-то алгоритм, но неясно, что за практическую задачу он решает.

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

Похожим занимались поетгисовцы, автоматизируя привязку домов к улицам. Некий пространственный (топологический) анализатор искал поблизости подходящую улицу и ставил на домик cladrcode

Задача не имеет решения.

Задача имеет не единственное решение.

Я бы не называл это задачей. По крайней мере той задачей, которую должен в конечном счёте решать софт. То есть той конечной задачей, которую решает для себя пользователь софта.

Любую задачу, которую способен решить человек, способен решить и софт. Ссылку на работу postgis-овцев, дадите?

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

Чем сердце успокоилось: https://forum.openstreetmap.org/viewtopic.php?id=21491

(Вторая тема поначалу называлась типа: “cladr:code для зданий”)

Кроме валидации по КЛАДРу населенных пунктов и улиц была проведена расстановка КЛАДР кодов улиц на домики.
Последнее было сделано для удобства конвертора данных в карту Покетгиса. Например через этот механизм решалась проблема одноименных улиц в городе.

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

Делали KekcuHa и Ezhick

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

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

При этом если есть несколько разных улиц с одинаковым названием в разных городах, то нужно показывать их как разные страницы.

Если использовать полный путь адреса точки, который возвращают движки геокодирования (nominatim, mapbox, googlemaps, etc.), то имеем проблему: один и тот же географический объект (облатсь, район, город, городской район, улица) может иметь разные названия/написания/ошибки написания от точки к точке, поэтому группировать по названию объекта практически нельзя.

Решение должно заключаться в использовании какого-то стороннего идентификатора улиц, не привязанного к названию, не имеющeго проблем с написанием на разных языках, переименованием улиц, etc.

Вы уж сразу не забудьте про случай, когда улиц в адресе нету.
Это или маленькая деревня, или большая, типа Зеленограда. :slight_smile:

Они также смогут иметь и ошибки стороннего идентификатора.

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

Тут проблем нет - находим мульти-полигон с наименьшей площадью, который содержит точку. Нет улицы - значит нет.

Была улица такая:
|
|

|
|
|
потом государство решило прилепить еще кусок

Теперь она вот такая

|
|

|
|
|

Думаю, что геометрически всё поменялось очень сильно, а название осталось.

Беда в том, что улица-то на местности-то может и есть, может даже и не далеко, а в адресе ее нет вообще, да и о том, что есть улица могут не все знать.
А в зеленоградском адресе обычно ничего нет. Город+дом. Люди, правда, группируют всё-таки дома по микрорайонам, но это не формальный адрес, а группировка.

Тут вы правы. После обновления карты придется заново пересчитывать списки из ид-улиц, рядом с которыми находятся точки. Сложность O(n2): n*m, где n - кол-во точек, m - кол-во улиц. URL страницы тоже поменяется, если будет содержать идентификатор вместо имени. Есть идеи как этого можно избежать?

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

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

Думаю чаще бывает ситуация, когда знают название улицы, а название района - нет. Опять же, улица может проходить через несколько районов.