fiosm icon indicating copy to clipboard operation
fiosm copied to clipboard

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

Open Scondo opened this issue 11 years ago • 9 comments

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

Scondo avatar Mar 21 '13 04:03 Scondo

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

Scondo avatar May 14 '13 05:05 Scondo

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

  • раскрыть сокращения статусных частей
  • перевести в нижний регистр
  • отсортировать слова по алфавиту

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

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

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

AMDmi3 avatar May 14 '13 18:05 AMDmi3

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

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

Scondo avatar May 15 '13 05:05 Scondo

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

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

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

Что?

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

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

AMDmi3 avatar May 16 '13 08:05 AMDmi3

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

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

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

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

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

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

Scondo avatar May 16 '13 14:05 Scondo

У меня база родная из 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. Вот тут можно сделать два варианта - с вырезанием статусной части и без (потому что в базе есть названия с несколькими ст. частями типа "улица Ленинская набережная")

AMDmi3 avatar May 16 '13 15:05 AMDmi3

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

Scondo avatar May 16 '13 18:05 Scondo

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

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

AMDmi3 avatar May 16 '13 18:05 AMDmi3

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

CrazyLionHeart avatar Mar 22 '14 20:03 CrazyLionHeart