Валідатор назв вулиць

Якщо ви про відношення associatedStreet, то в ньому атрибут name опціональний. Назва вулиці має братися з name мембера ролі street.

optional but recommended… Проблема у тому, що мембери одного відношення часто мають різні name. Ось список:

http://www.openstreetmap.org/browse/relation/416568
http://www.openstreetmap.org/browse/relation/1316746
http://www.openstreetmap.org/browse/relation/1353268
http://www.openstreetmap.org/browse/relation/1353269
http://www.openstreetmap.org/browse/relation/1353271
http://www.openstreetmap.org/browse/relation/1353272
http://www.openstreetmap.org/browse/relation/1353273
http://www.openstreetmap.org/browse/relation/1552690
http://www.openstreetmap.org/browse/relation/1563329
http://www.openstreetmap.org/browse/relation/1612043
http://www.openstreetmap.org/browse/relation/1656289
http://www.openstreetmap.org/browse/relation/1656347
http://www.openstreetmap.org/browse/relation/1656348
http://www.openstreetmap.org/browse/relation/1656349
http://www.openstreetmap.org/browse/relation/1657144
http://www.openstreetmap.org/browse/relation/1666661
http://www.openstreetmap.org/browse/relation/1666663
http://www.openstreetmap.org/browse/relation/1666664
http://www.openstreetmap.org/browse/relation/1666665
http://www.openstreetmap.org/browse/relation/1666666
http://www.openstreetmap.org/browse/relation/1666668
http://www.openstreetmap.org/browse/relation/1666670
http://www.openstreetmap.org/browse/relation/1666671
http://www.openstreetmap.org/browse/relation/1666672
http://www.openstreetmap.org/browse/relation/1667269
http://www.openstreetmap.org/browse/relation/1672414
http://www.openstreetmap.org/browse/relation/1672432
http://www.openstreetmap.org/browse/relation/1679900
http://www.openstreetmap.org/browse/relation/1679901
http://www.openstreetmap.org/browse/relation/1679902
http://www.openstreetmap.org/browse/relation/1685556
http://www.openstreetmap.org/browse/relation/1685557
http://www.openstreetmap.org/browse/relation/1685559
http://www.openstreetmap.org/browse/relation/1685560
http://www.openstreetmap.org/browse/relation/1685561
http://www.openstreetmap.org/browse/relation/1685562
http://www.openstreetmap.org/browse/relation/1693540
http://www.openstreetmap.org/browse/relation/1693541
http://www.openstreetmap.org/browse/relation/1694119
http://www.openstreetmap.org/browse/relation/1694120
http://www.openstreetmap.org/browse/relation/1694469
http://www.openstreetmap.org/browse/relation/1694470
http://www.openstreetmap.org/browse/relation/1694471
http://www.openstreetmap.org/browse/relation/1694472
http://www.openstreetmap.org/browse/relation/1707292
http://www.openstreetmap.org/browse/relation/1707293
http://www.openstreetmap.org/browse/relation/1707294
http://www.openstreetmap.org/browse/relation/1707295
http://www.openstreetmap.org/browse/relation/1707297
http://www.openstreetmap.org/browse/relation/1707298
http://www.openstreetmap.org/browse/relation/1711115
http://www.openstreetmap.org/browse/relation/1711116
http://www.openstreetmap.org/browse/relation/1748426
http://www.openstreetmap.org/browse/relation/1749542
http://www.openstreetmap.org/browse/relation/1832907
http://www.openstreetmap.org/browse/relation/1837642
http://www.openstreetmap.org/browse/relation/1863990
http://www.openstreetmap.org/browse/relation/1914036
http://www.openstreetmap.org/browse/relation/2044196
http://www.openstreetmap.org/browse/relation/2052034
http://www.openstreetmap.org/browse/relation/2054977
http://www.openstreetmap.org/browse/relation/2060065
http://www.openstreetmap.org/browse/relation/2060931
http://www.openstreetmap.org/browse/relation/2060932
http://www.openstreetmap.org/browse/relation/2060933
http://www.openstreetmap.org/browse/relation/2077813
http://www.openstreetmap.org/browse/relation/2082607
http://www.openstreetmap.org/browse/relation/2085774

Валідатор стає все гарнішим, дякую :slight_smile:

трохи повиправляв: один спочатку і десь десять з кінця списку(крім 2060931-206093, там взагалі неправильні звязки).
потім подумав, що дійсно якась дивна вимога вказувати ще й name для relation’a

з вказаних вами звязків, наприклад
http://www.openstreetmap.org/browse/relation/1552690
чому він некоректний? усі вулиці мають одну і ту ж назву

http://www.openstreetmap.org/browse/relation/1694471
у цього взагалі тільки один член з роллю street

помилковими мабуть треба вважати ті лінії, що входять в більш ніж один звязок типу street/associatedStreet
а також ті звязки у яких є лінії з різними назвами, хоча можуть бути виключення: вулиця, що включає міст, який має власну назву, яка прописана в name
можливо ще є виключення

От такі випадки було б непогано виявляти і помічати як помилки.

olehz
Пропав Володимир-Волинський

Поясніть ще раз по тих зв’язках стріт. Питався в російському ірц-каналі - пишуть, що не потрібно використовувати, а ставити кожному будинку addr:street
Тут бачу використовують і type=street, і type=associatedStreet - можливо прийдем до спільного знаменника?

У мене про street і associatedStreet теж колись були аналогічні питання.

З моєї точки зору, addr:street на будинках додає занадто багато ручної роботи. Також дуже легко зробити помилку, тобто, якщо людина з якихось причин написала в name російську назву, а потім з часом поставили правильно український напис, то треба йти по всіх будинках, і змінювати там, бо шукатися вони ну будуть. Ще й буде проблема їх знайти, тобто будинки у містах, особливо у мікрорайонах не стоять уздовж веїв вулиць. “Загубиш дім”, адресний пошук працювати не буде. Те ж саме, коли людина напише “вул. Дорошенка”, яке потім буде згідно угоди перейменоване у “Дорошенка вуліця”.

Також зв’язки дозволяють правильно поставити будинок на дві вулиці, вказавши дрібний номер “1/23”, а не тулити addr2:street, які зараз ніде не підтримуються.

Про те, як ці теґи використовуються, можна дивитися тут: addr:street, 4 мільйони домів, 9 мільйонів нод (очевидно Карлсруе), 20 тисяч відношень. associatedStreet – 57 тисяч, street – 12 тисяч. Слід зауважити, що дуже багато домів було заімпортовано. При імпорті набагато легше вказати addr:street на будинку. Я у своїх імпортах створював відношення окремою програмою у другому проході, після вивантаження домів і вулиць.

Але якщо ви у своєму місті будете ставити addr:street на будинки, це не буде помилкою.

Так є ж узгоджена схема
http://wiki.openstreetmap.org/wiki/Proposed_features/House_numbers/Karlsruhe_Schema#Using_relations_to_associate_house_and_street_.28optional.29
дозволяє писати type=street/associatedStreet
і ролі street/house/address

Київська область теж пропала

у нас було вирішено використовувати зв"язки, в Росії - 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[k
2] = ‘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[k
    2] = ‘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:

http://www.openstreetmap.org/browse/relation/158417
http://www.openstreetmap.org/browse/relation/365784
http://www.openstreetmap.org/browse/relation/417093
http://www.openstreetmap.org/browse/relation/946947
http://www.openstreetmap.org/browse/relation/1353268
http://www.openstreetmap.org/browse/relation/1353269
http://www.openstreetmap.org/browse/relation/1353271
http://www.openstreetmap.org/browse/relation/1353272
http://www.openstreetmap.org/browse/relation/1353273
http://www.openstreetmap.org/browse/relation/1491643
http://www.openstreetmap.org/browse/relation/1492401
http://www.openstreetmap.org/browse/relation/1545755
http://www.openstreetmap.org/browse/relation/1552690
http://www.openstreetmap.org/browse/relation/1559358
http://www.openstreetmap.org/browse/relation/1563329
http://www.openstreetmap.org/browse/relation/1649094
http://www.openstreetmap.org/browse/relation/1656348
http://www.openstreetmap.org/browse/relation/1675727
http://www.openstreetmap.org/browse/relation/1703470
http://www.openstreetmap.org/browse/relation/1710256
http://www.openstreetmap.org/browse/relation/1834767
http://www.openstreetmap.org/browse/relation/1966230
http://www.openstreetmap.org/browse/relation/1977549
http://www.openstreetmap.org/browse/relation/2052036
http://www.openstreetmap.org/browse/relation/2060931
http://www.openstreetmap.org/browse/relation/2060932
http://www.openstreetmap.org/browse/relation/2060933
http://www.openstreetmap.org/browse/relation/2062235
http://www.openstreetmap.org/browse/relation/2072322
http://www.openstreetmap.org/browse/relation/2072323
http://www.openstreetmap.org/browse/relation/2073259
http://www.openstreetmap.org/browse/relation/2076743
http://www.openstreetmap.org/browse/relation/2076744
http://www.openstreetmap.org/browse/relation/2077139
http://www.openstreetmap.org/browse/relation/2077140
http://www.openstreetmap.org/browse/relation/2077141

Зараз оновлю дані на сервері - подивимось, що з того вийде

може ще
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)
чи це сильно сповільнить запит?

які є ідеї щодо розділення вулиць що мають однакову назву в межах одного міста? :slight_smile:

додай будь ласка highway=raceway у виключення типу path/footway
і також “лінія” і “дорога” у регулярку “вулиця|проспект…”

Ой, точно пропустив. Поправлю завтра

Наведений вище запит і так непідйомний. Я створюю додаткові поля і індекси, ну і запит відповідно трохи інший, так що все нормально.

Перше, що приходить в голову, розбивати місто на райони. В Київі, здається, є 4 вулиці Шевченка, але вони всі в різних районах.

hstore(rel.tags)->‘name’ = ‘Назва вулиці’ or hstore(rel.tags)->‘name’ is null and ARRAY && ARRAY)