Pull to refresh

Comments 14

Вообще-то по моему опыту задача определения, является ли строка адресом в реальности гораздо сложнее, чем кажется. В свое время когда я работал над Yahoo! Geoplanet, мы решали эту задачу, и при ее решении есть великое количество подводных камней. Если есть возможность, нужно использовать существующее решение:


В конечном счете (при реализации) это упирается в построение достаточного умного классификатора, который выдает вероятность того, что строка или адрес, или обозначает какое-то географическое место.
Определение является ли строка адресом — согласен, более сложная задача, в моем же случае строка 100% является адресом, и надо определить, что вводит пользователь, название места, город, улицу или улицу с домом, при чем определить по базе (да, я знаю, что у меня есть вот это:
нет, не выходим, ведь вполне возможно, что улицы еще нет в базе

но это просто «тычка» на будущее)
Мне не тягаться с Yahoo, мне только адрес подсказать.
А Ваша система знает об адресах без улиц? А то вот у нас тут г.Москва, г.Зеленоград, корп.1610, например — это нормальный полный адрес (дважды город, нет улицы и вместо номера дома — корпус). 95% систем это не может обработать.
С городами и корпусом справится, в вот без улицы тяжко, хотя, у нас пользователь редко город вводит, в основном он тянется из координат, спасибо за мысль об отсутствии улицы, на днях буду дорабатывать
Всегда пожалуйста, а то грустно нам тут в Зеленограде, вот Спутник запустили — и опять про Зеленоград забыли, адреса на находятся. И так почти всегда — вроде Москва а вроде и не Москва — даже в заточенных под одну Москву сервисах адрес часто не проходит.
Ну, я Вас тоже расстрою, не думаю, что сервис, под который писалась система, маленькую часть которой я тут представил, скоро доберется до России
Ну, есть призрачная надежда, что кто-то прочтёт Ваш пост, мой комментарий и в его российской системе будет на одни грабли меньше :)
И на одни костыли больше :P
Попробуйте dadata, без проблем спарсит любой адрес Зеленограда.
Применительно к OSM, не забывайте об addr:place — туда вместо addr:street пишутся адреса не привязанные к линейным объектам (улицам), т.е., например, деревни и районы. Таких адресов в России довольно много. Так-же, по-хорошему, должны обозначаться адреса в Зеленограде.

если не получилось (нет пробела) — то к чертям все это не улица с домом

«Ленина,11»

if LastSpace < (len([]rune(str)) — 6) {

«11стр123»

case char_count > int_count: { result -= MARK_STEP }

«2корп2»

ILIKE $1 ", "%"+name+"%"

Это будет очень плохо работать — в OSM названия улиц приведены к одному полному виду («улица Ленина»), пользователь же может ввести статусную часть с другой стороны или с сокращением (Ленина улица, ул.Ленина) и в addr:street это не найдётся. Также всё сломается если пользователь допустит пробел в номере дома («11 корп 2» — «11 корп» будет отнесено к улице и также не найдётся ILIKE'ом).

\«addr:housenumber\» ILIKE $2"

А это, в случае когда в номере дома есть корпус/строение — ещё хуже. Пользователь может ввести «1Ас1», «1АС1», «1А стр1», «1А стр. 1», в OSM же будет только что-то одно (принято 1Ас1, но за этим никто особо не следит, так что возможны варианты).

ИМХО, алгоритм состоит из слабо обоснованной эвристики и в целом имеет низкую эффективность. Я, к сожалению, с разбором адресов пока не сталкивался, но руководствовался бы следующими соображениями:

1) Номер дома состоит из ограниченного набора токенов (\d+[: русская буква:]?, /, с\.?, к\.?, стр\.?, корп\.? и ещё немного редких), и, скорее всего, выделяется не слишком монструозной регуляркой (особенно если мы ожидаем его в фиксированной позиции — в конце строки).
2) Улицу можно выделить по словарю — у вас так и делается, но не учитывается всё богатство вариаций.

Я меня есть проект который как раз используется для приведения названий улиц в OSM к единому стилю (Ленина ул -> улица Ленина) (про который я обещал написать пост, но руки никак не дойдут). Его работа основана на приведении названий улиц к виду, инвариантному относительно встречающихся изменений в написании (сюда входит различное написание статусной части как-то «переулок», «пер.», «пер-к», регистр и порядок слов), таким образом и «пер-к. Ульянова» и «УЛЬЯНОВА ПЕРЕУЛОК» и «пер ульянова» будут приведены к одной и той же строке («переулок ульянова») по которой можно понять что это одно название и найти для него в словаре полное и правильное написание, причём за O(1) (а также определить что в названии отсутствует статусная часть и даже найти название с заданным количеством опечаток используя нечёткий поиск).

Проект тут, если интересно.

Но для вашего случая можно всё сильно упростить: просто взять все названия из OSM, разбить по словам, привести к нижнему регистру, добавить того чего нет в OSM но может ввести пользователь (сокращения статусных частей, «им.», «имени»), запихнуть в словарь (даже база для этого не нужна, он будет занимать единицы мегабайт), и искать в нём каждое слово из запроса.

Итого, выкусываем регуляркой как можно более длинный номер дома справа, то что осталось разбиваем по словам и ищем каждое в словаре — при достаточном совпадении считаем улицей и всё вместе — адресом. Если хочется дополнительно проверить его на существование в OSM, то и его и OSM нужно будет приводить к одному виду как описано выше. Номер дома, как было сказано, тоже.
>Стартовая вероятность 100, разбиваем строку по последнему пробелу, если не получилось (нет пробела) — то к чертям все это не улица с домом.
Как быть с «Ленина,3» или «Кирова-7-21»
с последним пробелом все тоже несколько сложнее, например, «Ульянова 27/12 корп 3»
Сами улицы пользователи могут писать с большим разнообразием: проспект Сахарова, улица Сахарова, улица им. академика Сахарова, улица имени Сахарова, пр-т ак. Сахарова — будет ли это работать при сравнении с эталонной базой улиц?

>Мне не тягаться с Yahoo, мне только адрес подсказать.
Если только адрес подсказать, почему не хотите воспользоваться одним из существующих решений по автокомплиту адресов, например, dadata.ru/suggestions/?
Комментарии как всегда интересней статьи. :) К слову — наверное по этой причине до сих пор в OSM нет нормального поисковика по адресам, чего к слову очень не хватает.
Кстати да, в OSM я тоже не могу найти Зеленоградский адрес приходящими мне в голову способами (находит только сам город при том, что город отлично отрисован в плане объектов), Гугл-карты в этом плане чуть лучше — хоть что-то пытаются угадать, правда мимо, и только Яндекс справляется на отлично. Вот ещё предложенный выше сервис dadata вняв моим мольбам тоже умеет обрабатывать Зеленоград :)
Лет 10 назад я такие задачи решал путем поиска похожих хешей, например «олгогра енински прсп 1 234», затем из менее десятка пхжх адресов уже спокойно распарсивал под кладр.
Sign up to leave a comment.

Articles