в вики по поводу отношения street/associatedStreet про обязательность name: optional but recommended
в общем, имя должно браться из улиц, а не самого отношения. а если где-то ни одна улица не именована, или есть улицы с левым именем - это ошибка.
собственно поэтому я сразу предлагал брать имя из релейшена…
Но тогда надо в каждом релейшене вручную копировать названия улиц с тегов самих улиц. По моему, глупо дублировать информацию вручную, если её можно взять автоматически.
Кстати, поясните мне, идиоту, как работает строка
my $street_name = name_from_list( 'street', $reltag->{$relation_id} );
Я так понял, что здесь объявляется локальная текстовая переменная $street_name
Потом ей присваивается значение. Но как работает name_from_list я так и не понял. И почему там ‘street’, а не ‘name’?
И вообще, почему это всё написано на Perl, в котором я не соображаю?
UPD:
Щойно закінчив конвертацію Харківської обл. з пропатченим конвертором. Воно працює!!!
Але не зовсім так як хотілося.
Я вказую --namelist label=name:ru,name --namelist place=name:ru,name --namelist street=name:ru,name
Ті будинки, у яких нема addr:street, але вони включені до релейшену, отримали в адресі назву вулиці російською мовою. А ті будинки, які мали addr:street, отримали назву вулиці українською мовою, бо в addr:street прописано українською. Не зважаючи на те, що вони були включені до релейшену.
Наприклад, у Харкові, будинки по вулиці Єлізарова, №4 та №6 включені у один релейшен вулиці Єлізарова. При цьому будинок №4 має тег addr:street, а будинок №6 не має.
В результаті маємо адреси:
“Харьков, Елизарова улица, 4” та “Харьков, Єлізарова вулиця, 6”
Я пригадую, що нібито liosha десь писав, що коли будинок має addr:street, то його конвертор шукає поблизу вулицю з таким самим значенням тегу name, бере з нього локалізовану назву name:ru (або іншу, вказану у конфігах) та приписує цю локалізовану назву в addr:street на будинку. Але чомусь ця функція не працює.
Larry0ua, а нащо треба вводити нову змінну $s_name ?
А ще чомусь конвертор повідомляє про меншу кількість адресованих будинків
З оригінальним конвертором
Processing relations...
95 turn restrictions
56382 houses with associated street
0 transport stops
З пропатченим конвертором
Processing relations...
95 turn restrictions
37629 houses with associated street
0 transport stops
Це що, помилка у конверторі, чи в нас так багато будинків (18753) у недороблених релейшенах у Харкові?
Ті будинки, у яких нема addr:street, але вони включені до релейшену, отримали в адресі назву вулиці російською мовою. А ті будинки, які мали addr:street, отримали назву вулиці українською мовою, бо в addr:street прописано українською. Не зважаючи на те, що вони були включені до релейшену.
Це цілком правильна поведінка, і мова тут ні при чому. Теґи на об’єкті мають перевагу над теґами з відношення. Тобто, їх можна використовувати для уточнення “успадкованого” значення. Власне, addr:street потрібно видалити з окремих будинків.
Це цілком правильна поведінка, і мова тут ні при чому. Теґи на об'єкті мають перевагу над теґами з відношення.
Так, поведінка правильна.
Але я мав на увазі, що не працює старий “механізм” вибору локалізованих назв вулиць у адресах.
Коли є addr:street якоюсь мовою, а у “польському форматі” треба отримати StreetDesc= іншою мовою.
Larry0ua, а нащо треба вводити нову змінну $s_name ?
А ще чомусь конвертор повідомляє про меншу кількість адресованих будинків
З оригінальним конвертором
Processing relations... 95 turn restrictions 56382 houses with associated street 0 transport stops
З пропатченим конвертором
Processing relations... 95 turn restrictions 37629 houses with associated street 0 transport stops
Це що, помилка у конверторі, чи в нас так багато будинків (18753) у недороблених релейшенах у Харкові?
нова змінна, щоб зробити next якщо вона порожня. можна зробити без неї, звичайно, присвоювати зразу в street_name
name_from_list читає заданий список для street він заданий був name:ru,name, і з відповідного об"єкту бере підходящу назву.
а проблему з addr:street я не чіпав, значить, воно і до мене не працювало.
на рахунок меншої кількості - можете додати перед next if !$street_name; стрічку $street_name = name_from_list( ‘street’, $reltag->{$relation_id} ) if !$street_name; - хай в крайньому випадку заповнює з назви відношення.
нова змінна, щоб зробити next якщо вона порожня. можна зробити без неї, звичайно, присвоювати зразу в street_name
Спробую прибрати. Я не профі-програміст, але вважаю, що зайва операція присвоювання у циклі - то не є добре.
name_from_list читає заданий список для street він заданий був name:ru,name, і з відповідного об"єкту бере підходящу назву.
О, дякую. Тепер починаю трошки розуміти
а проблему з addr:street я не чіпав, значить, воно і до мене не працювало.
я й не звинувачую. В оригінальній версії така сама проблема.
на рахунок меншої кількості - можете додати перед next if !$street_name; стрічку $street_name = name_from_list( ‘street’, $reltag->{$relation_id} ) if !$street_name; - хай в крайньому випадку заповнює з назви відношення.
IMHO, відсутність членів типу street у релейшені - це помилка. І відсутність назв у тих членів - теж помилка. І ці помилки треба виправляти в базі OSM, а не у конверторі. Наявність тисячі таких релейшенів у Харкові - це результат незавершеного імпорту даних dima_ua.
“Причешемо” імпортовані дані - таких помилок не стане.
Однак рядок $street_name = name_from_list( ‘street’, $reltag->{$relation_id} ) if !$street_name; я додам. Нехай буде.
Гм. Щось я нахомутав у скрипті…
Рядок street_name = name_from_list( ‘street’, $reltag->{$relation_id} ) if !$street_name; схоже, не працює, бо кількість будинків така сама, що й без нього.
if ( $flags->{street_relations} ) {
for my $type ( qw{ street associatedStreet } ) {
my $list = $relations->{$type};
next if !$list;
while ( my ($relation_id, $members) = each %$list ) {
my $street_name;
for my $member ( @$members ) {
next if !( $member->{role} eq 'street' );
next if !( $member->{type} eq 'way' );
$street_name = name_from_list( 'street', $waytag->{$member->{ref}} );
$street_name = name_from_list( 'street', $reltag->{$relation_id} ) if !$street_name;
next if !$street_name;
last;
}
next if !$street_name;
for my $member ( @$members ) {
next if !( $member->{role} ~~ [ 'house', 'address' ] );
$street{"$member->{type}:$member->{ref}"} = $street_name;
}
}
}
printf STDERR " %d houses with associated street\n", scalar keys %street;
}
я мав на увазі перед іншим next if !$street_name; той, який перед for my $member
Переробив. Тепер працює правильно. А я потроху починаю розуміти логіку роботи програми
if ( $flags->{street_relations} ) {
for my $type ( qw{ street associatedStreet } ) {
my $list = $relations->{$type};
next if !$list;
while ( my ($relation_id, $members) = each %$list ) {
my $street_name; - створюємо змінну
for my $member ( @$members ) { перебираємо у циклі всіх членів релейшена
next if !( $member->{role} eq 'street' ); переходимо до наступного члена, якщо роль не street
next if !( $member->{type} eq 'way' ); переходимо до наступного члена, якщо тип не way
$street_name = name_from_list( 'street', $waytag->{$member->{ref}} ); беремо назву вулиці з тегів члена релейшена. Тут, чесно кажучи, я ще не зовсім зрозумів синтаксис. Ну нехай.
next if !$street_name; переходимо до іншого члена, якщо назву вулиці не чомусь отримали.
last; Закінчуємо цикл, бо назва вулиці вже знайдена.
}
$street_name = name_from_list( 'street', $reltag->{$relation_id} ) if !$street_name; якщо серед членів релейшена не знайшли того, кто має роль sreet, тип way та має в тегах назву вулиці, то беремо назву вулиці з тегів релейшена.
next if !$street_name; якщо й в тегах релейшена не знайшли назву вулиці, то це не релейшен, а якась недороблена гидота. Переходимо до іншого релейшена
for my $member ( @$members ) { знову перебираємо членів релейшена (якщо вже знаємо назву вулиці)
next if !( $member->{role} ~~ [ 'house', 'address' ] ); переходимо до іншого члена, якщо роль не house або address
$street{"$member->{type}:$member->{ref}"} = $street_name; записуємо в теги члена релейшена назву вулиці
}
}
}
printf STDERR " %d houses with associated street\n", scalar keys %street;
}
Сконвертував карту Харківської області з пропатченим конвертором. Відкрив у GPSmapEdit. Перевірив адреси. Патч працює правильно.
Думаю, вже можна турбувати liosha щодо включення цього патчу в офіційну версію.
…а польский формат может хранить адрес только на одном языке?
По моему, да. Нужный язык выбирается перед конвертированием из OSM в польский формат. (но я могу и ошибаться)
Замість того, щоб вмовляти реалізовувати зміни в конверторі можна спробувати трохи інакший шлях - звести osm-файл до того вигляду, що очікує liosha.
Це можна зробити написавши(на Java) плагін для Osmosis’а або просто незалежну утілітку, який переноситиме в name/addr:street об’єктів значення з потрібних name:**.
Так само можна генерувати addr:district, addr:region базуючись на геометричних включеннях одними полігонами інших.
Приклади плагінів тут: http://svn.openstreetmap.org/applications/utils/osmosis/plugins/
ну, препроцесінг це хороший варіант
проблема в тому, що тепер постало питання - а чи справді варто на hw ставити всі можливі name:xx чи може їх перенести в відношення? імхо, ця ідея має сенс, в добре відмаплених можна зняти теги name:xx з купи поділених відрізків (яких може бути і 2, і 20) і внести у відношення. Нема дублювання - менше проблем з невірними назвами і необхідністю вносити name:xx на всі можливі відрізки. А в погано відмаплених містах нема таких проблем з кількістю відрізків і іменами на них
Якщо така ідея прийнятна, буде потрібно якийсь пропозал написати, чи що…
Особисто мені така ідея зрозуміла і прийнятна, але все ж таки досить багато конверторів і рендерів використовують саме name:** на лініях
Видалення name:** в лініях буде розцінюватися як вандалізм
Хлопці, є ще такий нюанс стосовно релейшенів.
Я натрапив на ситуацію, коли для однієї вулиці було два релейшена (перший релейшен хтось зробив вручну, другий виник після імпортування даних dima_ua)
Перший релейшен мав тег type=associatedStreet, інший мав тег type=street. При цьому частина будинків та лінія вулиці були в першому релейшені, а інша частина будинків - у другому. А оскільки релейшени були різних типів, то у переліку релейшенів вони розташувалися не поруч. Якби ДЖОСМ при наборі не підкинув автоматом назву вулиці та якби я не тицнув на один з будиночків, я б навіть не дізнався, що є дублікат релейшена.
Давайте вже якось дійдемо згоди щодо використання street або associatedStreet
“Плюси” street
- коротше писати (однак це не досить вагомий аргумент, оскільки при набиранні ass… автоматично підкидається associatedStreet
“Плюси” associatedStreet
- цей тип є рекомендованим у пропозалі схеми Карлсруе (а про street написано лише “дозволяється використання”)
- JOSM (з relation toolbox) більше любить associatedStreet. Навіть вміє (однією кнопкою) розтавляти ролі street, house. А також автоматично прописує в тег релейшена name з відрізків вулиці.
Очевидно що плюсів в associatedStreet більше і вони вагоміші.
Використовую саме його, тому що так само прочитав в документації.
І будуть ще люди, які спочатку читають документацію, а потім вже діють. Не всі одразу занурюються в Potlatch з думкою “о, зараз я все перероблю, тут і так все зрозуміло, нащо ті інструкції”
Ну, тоді може треба буде пройтися роботом по релейшенах та замінити street на assosiatedStreet. Тільки спочатку імпорт по Харкову закінчемо.