Scondo / fiosm

Union of FIAS and OSM
29 stars 6 forks source link

Улицы с сокращениями и номерами. #5

Open Scondo opened 11 years ago

Scondo commented 11 years ago

Ряд улиц с номерами не находятся из-за того что в ОСМ пишутся <номер> <статус> <остальное название> Также не находятся улицы с сокращениями. Обе эти проблемы можно решить использованием streetmangler при "поиске кандидатов"

Scondo commented 11 years ago

Частично решено, частично - нет. Возможно дальнейшее решение требует наполнение базы стритмэнглера. Пример для сверки - Новый Берингов проезд, г. Москва

AMDmi3 commented 11 years ago

Да блин же, не нужен тебе streetmangler. Для сопоставления нужно преобразовать название улицы из обеих баз одинаковым образом:

всё, названия можно сравнивать.

По желанию можно добавить всякую мелочь типа удаления окончания числительных ("1-я", "1-ая" -> "1"), пробелов после одной буквы с точкой ("Л. Толстого" -> "Л.Толстого", это только до сортировки слов) и всего прочего, но это даст копейки.

А в списке, к слову, стоит их писать в виде "статусная часть в конце" - так удобнее искать нужное в таблице.

Scondo commented 11 years ago

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

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

AMDmi3 commented 11 years ago

Насчет сортировки по алфавиту - интересная мысль, но для этого опять-таки придется вытягивать все в память

Что? Ничего не надо менять, просто сравнивай названия по-человечески и выбрось streetmangler который тут совершенно не нужен.

И еще придется бороться с задвоением статусных частей.

Что?

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

Такое - только руками.

Scondo commented 11 years ago

Сортировать слова прямо внутри SQL - запроса? У меня база родная из osm2pgsql, в ней сначала по результату стритманглера ищется с условием

WHERE lower(name) = lower(%s) AND ST_Within(way,%s)

Если не найдено выгребается с условием

WHERE lower(name) LIKE lower(%s) AND ST_Within(way,%s)

Из которого потом ищется совпадение с именем без статусной/со статусной в начале/со статусной в конце

Про задвоение статусных: информация хранится в виде отдельно названия, отдельно статуса. Название как правило без статусной части. Но может быть и со статусной. То есть улица Амундсена выглядит как "Амундсена" "ул", а площадь Гагарина может раскладываться также, а может "пл. Гагарина" "пл", что приводит к "площадь пл. Гагарина" я так понимаю и сейчас :( Так что буду в любом случае думать что с этим мраком делать.

AMDmi3 commented 11 years ago

У меня база родная из osm2pgsql, в ней сначала по результату стритманглера ищется с условием

А, так. Понял. Тогда всё плохо, ибо это неправильный подход. В идеале нужен индекс по normalize_name(name) и искать по нему на = normalize_name(%s), где normalize_name - некая функция которая делает то что я говорил. Не знаю можно ли и насколько сложно написать её на sql или или другом языке.

WHERE lower(name) LIKE lower(%s) AND ST_Within(way,%s)

я всё-таки не понял зачем нужен LIKE. Он же даст только ложные срабатывания на названия с добавлениями в начале/в конце, т.е. Ленинская улица совпадёт со всеми 123-ми Новыми Нижними Ленинскими, при этом нормальных случаев не зацепит (улица Толстого vs. улица Л.Толстого, например). Он ещё и full-scan. Кстати, индекс по name-то у тебя, надеюсь, на lower(name)?

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

Это трындец. Но статусные части вырезать легко и это можно сделать на SQL. Вот тут можно сделать два варианта - с вырезанием статусной части и без (потому что в базе есть названия с несколькими ст. частями типа "улица Ленинская набережная")

Scondo commented 11 years ago

LIKE + фильтр на клиентской стороне до точного соответствия оказался быстрее трех запросов на точное соответствие (очевидно по причине меньшего числа геометрических сравнений). В общем решаем задачу по частям. Этот тикет на сокращения, закрыли оффтоп.

AMDmi3 commented 11 years ago

LIKE + фильтр на клиентской стороне до точного соответствия оказался быстрее трех запросов на точное соответствие

Смотри explain. Что-то мне кажется что индексы по name не работают.

CrazyLionHeart commented 10 years ago

LIKE легко ускоряется использованием gin-индексами