Викинув зі списку об’єктів, що перевіряються highway=footway і highway=path
Додав підсвітку будинків зв’язаних через relation.
Паралельно виявив ряд проблем:
Присутні 68 відношень, у котрих відсутні атрибут name - такі відношення ігноруються
У відношеннях в якості будинків присутні об’єкти з геометрією LINESTRING (також багато POINT, хоча це і не помилка, здається) - такі об’єкти також ігноруються
Загалом, на поточний момент підсвічується 34477 будинки з 69255 пронумерованих по Україні.
трохи повиправляв: один спочатку і десь десять з кінця списку(крім 2060931-206093, там взагалі неправильні звязки).
потім подумав, що дійсно якась дивна вимога вказувати ще й name для relation’a
помилковими мабуть треба вважати ті лінії, що входять в більш ніж один звязок типу street/associatedStreet
а також ті звязки у яких є лінії з різними назвами, хоча можуть бути виключення: вулиця, що включає міст, який має власну назву, яка прописана в name
можливо ще є виключення
Поясніть ще раз по тих зв’язках стріт. Питався в російському ірц-каналі - пишуть, що не потрібно використовувати, а ставити кожному будинку addr:street
Тут бачу використовують і type=street, і type=associatedStreet - можливо прийдем до спільного знаменника?
З моєї точки зору, addr:street на будинках додає занадто багато ручної роботи. Також дуже легко зробити помилку, тобто, якщо людина з якихось причин написала в name російську назву, а потім з часом поставили правильно український напис, то треба йти по всіх будинках, і змінювати там, бо шукатися вони ну будуть. Ще й буде проблема їх знайти, тобто будинки у містах, особливо у мікрорайонах не стоять уздовж веїв вулиць. “Загубиш дім”, адресний пошук працювати не буде. Те ж саме, коли людина напише “вул. Дорошенка”, яке потім буде згідно угоди перейменоване у “Дорошенка вуліця”.
Також зв’язки дозволяють правильно поставити будинок на дві вулиці, вказавши дрібний номер “1/23”, а не тулити addr2:street, які зараз ніде не підтримуються.
Про те, як ці теґи використовуються, можна дивитися тут: addr:street, 4 мільйони домів, 9 мільйонів нод (очевидно Карлсруе), 20 тисяч відношень. associatedStreet – 57 тисяч, street – 12 тисяч. Слід зауважити, що дуже багато домів було заімпортовано. При імпорті набагато легше вказати addr:street на будинку. Я у своїх імпортах створював відношення окремою програмою у другому проході, після вивантаження домів і вулиць.
Але якщо ви у своєму місті будете ставити addr:street на будинки, це не буде помилкою.
у нас було вирішено використовувати зв"язки, в Росії - addr:street на кожній будівлі. тому на ірц таке радили.
на рахунок кількох номерів на будинку - або вказувати лише по більш головній вулиці (у нас, наприклад, практично всюди примусово познімали номери з кутових будинків, щоб залишався лише один), або другий ставити точкою на лінії будівлі у місці розташування номера.
Дуже багато різних способів адресації, що сильно ускладнює запити до БД. Зараз валідатор обробляє лише будинки, що входять у відношення street, чи associatedStreet і для яких вказаний тег name. Валідатор працює з даними імпортованими за допомогою osm2pgsql з ключами -k -s -G. Для будинків використовується наступний запит:
SELECT
osm_id,
ASTEXT(ST_MakePolygon(ST_ExteriorRing(way))) AS the_geom,
X(CENTROID(way)) AS x,
Y(CENTROID(way)) AS y,
“addr:housenumber” AS num
FROM planet_osm_rels rel, planet_osm_polygon
WHERE
ST_Within(way, ST_PolygonFromText(‘Геометрія межі міста’)) AND
GEOMETRYTYPE(way) = ‘POLYGON’ AND
hstore(rel.tags)->‘name’ = ‘Назва вулиці’ AND
(hstore(rel.tags)->‘type’ = ‘associatedStreet’ OR hstore(rel.tags)->‘type’ = ‘street’) AND
osm_id=ANY(ARRAY(
SELECT
CAST(replace(replace(members[k2-1], ‘w’, ‘’),‘r’,‘-’) AS int)
FROM (SELECT generate_subscripts(parts, 1) AS k, id, parts, members
FROM planet_osm_rels
WHERE id = rel.id
) sub
WHERE members[k2] = ‘house’ AND
(substring(members[k2-1], 1, 1) = ‘w’ OR substring(members[k2-1], 1, 1) = ‘r’)
))
ORDER BY
CAST(substring(“addr:housenumber” FROM ‘^\d+’) AS int),
LENGTH(“addr:housenumber”),
“addr:housenumber”
Будуть пропозиції щодо вдосконалення такої вибірки, аби враховувались усі наведені вище варіанти адресації?
викинути hstore(rel.tags)->‘name’ = ‘Назва вулиці’ AND
замінити osm_id=ANY(ARRAY( на ‘ID лінії’=ANY(ARRAY(
замінити members[k2] = ‘house’ на members[k2] in (‘house’,‘address’)
(hstore(rel.tags)->‘type’ = ‘associatedStreet’ OR hstore(rel.tags)->‘type’ = ‘street’) перемістити в середину ARRAY(…) і викинути зовнішній planet_osm_rels rel
?
трохи невірно зрозумів початковий запит…
мабуть краще так:
викинути hstore(rel.tags)->‘name’ = ‘Назва вулиці’ AND
додати
AND
‘ID лінії’=ANY(ARRAY(
SELECT
CAST(replace(members[k2-1], ‘w’, ‘’) AS int)
FROM (SELECT generate_subscripts(parts, 1) AS k, id, parts, members
FROM planet_osm_rels
WHERE id = rel.id
) sub
WHERE members[k2] = ‘street’ AND
(substring(members[k*2-1], 1, 1) = ‘w’)
))
замінити members[k2] = ‘house’ на members[k2] in (‘house’,‘address’)
Зауважую, що я спочатку групую усі сегменти дорожнього графу міста за назвами. А потім для кожної групи імен шукаю relation. Тому було б непогано всеж проставити name в проблемних relations. Благо їх зовсім небато.
Я не зовсім розумію ідею. Якщо маєш можливість наведи, будь-ласка, повний текст запита
Це запросто. До речі, а чим відрізняються ролі ‘house’,‘address’?
бази не маю, тому важко написати запит, ідея така:
серед усіх ліній(не тільки полігонів), що знаходяться в межах міста вибираємо ті лінії для яких:
addr:street=‘Назва вулиці’
або
для яких існує street-relation що містить
а) містить саму лінію з роллю house/address (ці ролі нічим не відрізняються)
і
б) хоча б одну лінію з роллю street яка має name=‘Назва вулиці’
Ну у такого підходу також є мінус. Оновив базу кілька хвили тому, ось що маємо на поточний момент:
SELECT COUNT(*) FROM planet_osm_rels
WHERE NOT ('street' = ANY(members)) AND
(hstore(tags)->'type' = 'associatedStreet' OR hstore(tags)->'type' = 'street')
=36
Тобто 36 рілейшинів взагалі не містять вулиць
З іншої сторони
SELECT COUNT(*) FROM planet_osm_rels
WHERE NOT (hstore(tags) ? 'name') AND
(hstore(tags)->'type' = 'associatedStreet' OR hstore(tags)->'type' = 'street')
=53 рілейшина не мають назви
В будь-якому випадку треба підправляти. Або додати name у 53 рілейшини, або додати вулиці у 36 рілейшинів.
тоді замість
б) хоча б одну лінію з роллю street яка має name=‘Назва вулиці’
таке
б) хоча б одну лінію з роллю street яка має name=‘Назва вулиці’
або
б’) relation-name=‘Назва вулиці’
(
SELECT
osm_id,
ASTEXT(ST_MakePolygon(ST_ExteriorRing(way))) AS the_geom,
X(CENTROID(way)) AS x,
Y(CENTROID(way)) AS y,
"addr:housenumber" AS num,
CAST(substring("addr:housenumber" FROM '^\d+') AS int) AS num_base,
LENGTH("addr:housenumber") AS num_len
FROM planet_osm_polygon
INNER JOIN planet_osm_rels rel ON
(hstore(rel.tags)->'type' = 'associatedStreet' OR hstore(rel.tags)->'type' = 'street') AND
ARRAY[Список ID доріг згрупованих по назві в межах одного міста] && ARRAY(
SELECT CAST(replace(members[k*2-1], 'w', '') AS int)
FROM (SELECT generate_subscripts(parts, 1) AS k, id, parts, members) sub
WHERE members[k*2] = 'street' AND
(substring(members[k*2-1], 1, 1) = 'w')
)
WHERE
ST_Within(way, (SELECT way FROM planet_osm_polygon WHERE osm_id = ID межі міста)) AND
GEOMETRYTYPE(way) = 'POLYGON' AND
osm_id=ANY(ARRAY(
SELECT CAST(replace(replace(members[k*2-1], 'w', ''),'r','-') AS int)
FROM (SELECT generate_subscripts(parts, 1) AS k, id, parts, members) sub
WHERE members[k*2] IN ('house', 'address') AND
(substring(members[k*2-1], 1, 1) = 'w' OR substring(members[k*2-1], 1, 1) = 'r')
))
) UNION (
SELECT
osm_id,
ASTEXT(ST_MakePolygon(ST_ExteriorRing(way))) AS the_geom,
X(CENTROID(way)) AS x,
Y(CENTROID(way)) AS y,
"addr:housenumber" AS num,
CAST(substring("addr:housenumber" FROM '^\d+') AS int) AS num_base,
LENGTH("addr:housenumber") AS num_len
FROM planet_osm_polygon
WHERE
building IS NOT NULL AND
\"addr:housenumber\" IS NOT NULL AND
"addr:street" = 'Назва вулиці' AND
ST_Within(way, (SELECT way FROM planet_osm_polygon WHERE osm_id = ID межі міста)) AND
GEOMETRYTYPE(way) = 'POLYGON'
)
ORDER BY
num_base,
num_len,
num
Відповідно з чим необхідно підправити наступні відношення, включивши до них ролі street:
може ще
INNER JOIN planet_osm_rels rel ON
(hstore(rel.tags)->‘type’ = ‘associatedStreet’ OR hstore(rel.tags)->‘type’ = ‘street’) AND
ARRAY && ARRAY
замінити на
INNER JOIN planet_osm_rels rel ON
(hstore(rel.tags)->‘type’ = ‘associatedStreet’ OR hstore(rel.tags)->‘type’ = ‘street’) AND
(hstore(rel.tags)->‘name’ = ‘Назва вулиці’ or ARRAY && ARRAY)
чи це сильно сповільнить запит?
які є ідеї щодо розділення вулиць що мають однакову назву в межах одного міста?
додай будь ласка highway=raceway у виключення типу path/footway
і також “лінія” і “дорога” у регулярку “вулиця|проспект…”