You are not logged in.

Announcement

*** NOTICE: forum.openstreetmap.org is being retired. Please request a category for your community in the new ones as soon as possible using this process, which will allow you to propose your community moderators.
Please create new topics on the new site at community.openstreetmap.org. We expect the migration of data will take a few weeks, you can follow its progress here.***

#1 2010-10-23 09:27:11

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

perl + .osm

Есть .osm-файл со списком городов.

Есть perl с perl-XML-Parser

Как на выходе получить список названий городов и их статусов?

Дайте, плиз, пример такого скриптика, потому что ни разу с хмл-ем не работал, я его покручу и буду дальше усложнять.

Offline

#2 2010-10-23 09:42:05

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

use Geo::Parse::OSM;

Geo::Parse::OSM->parse_file( 'file.osm', sub { print "$_[0]->{tag}->{place} $_[0]->{tag}->{name}\n" if $_[0]->{tag}->{place} eq 'town' } );

Offline

#3 2010-10-23 10:14:33

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Так, вроде даже получилось модуль установить и запустить smile

А чой-то он ругается на юникод, как это побороть?

Wide character in print at ./test_osm.pl line 5, <GEN0> line 5524.
town Vrbno pod Pradědem
town Lomnice nad Popelkou
Wide character in print at ./test_osm.pl line 5, <GEN0> line 5538.
town Meziboří

Offline

#4 2010-10-23 10:16:06

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

установи выходную кодировку.
binmode STDOUT, ':utf8';
или
binmode STDOUT, ':encoding(cp866)';

Offline

#5 2010-10-23 10:26:38

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Ну, вроде заработало!

Будем дальше думать что с этим делать smile

Offline

#6 2010-10-23 13:31:24

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Хочу из википедии вытащить статью про город, но получаю ошибку от википедии о неправильном названии статьи (недопустимые символы)

#!/usr/bin/perl

use WWW::Wikipedia;

my $wikientry = "Яблонец-над-Нисоу";
my $wiki = WWW::Wikipedia->new(language => 'ru');
my $entry = $wiki->search( $wikientry );
my $entry_ru = $entry->language( 'ru' );
print $entry_ru->raw();

Как превратить "Яблонец-над-Нисоу" в "%D0%AF%D0%B1%D0%BB%D0%BE%D0%BD%D0%B5%D1%86-%D0%BD%D0%B0%D0%B4-%D0%9D%D0%B8%D1%81%D0%BE%D1%83"? Мне кажется именно в этом проблема, потому что статью "Perl" нормально обрабатывает.

Offline

#7 2010-10-23 13:57:29

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

use utf8;

и сохранить исходник в этом utf8

Offline

#8 2010-10-23 14:29:56

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Чота всё равно не работает.

#!/usr/bin/perl

use utf8;
use URI::Escape;
use WWW::Wikipedia;

# binmode STDOUT, ':utf8';

my $wikientry = "Яблонец-над-Нисоу";
my $wikientry_safe = uri_escape_utf8($wikientry)."\n";
my $wiki = WWW::Wikipedia->new(language => 'ru');
my $entry = $wiki->search( $wikientry_safe );
# print $entry->text();

# print "\n\n===\n\n";

my $entry_ru = $entry->language( 'ru' );
print $entry_ru->raw();

Вместо сырого текста статьи возвращает хтмл-страницу с ошибкой.

Исходник у меня и так в утф-8

Offline

#9 2010-10-23 14:42:49

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

Тогда писать багрепорт на WWW:Wikipedia, а пока заурленкодить руками. Но надо понять, что именно ему не нравится

Offline

#10 2010-10-23 14:51:34

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

liosha, а ты можешь проверить, так же оно ошибку выдаёт?

Offline

#11 2010-10-23 15:19:12

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

Доберусь до дома - посмотрю
Кстати, совершенно не понял, зачем там uri_escape, да ещё и с \n. Всё должно работать без него.

Offline

#12 2010-10-23 15:35:15

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Похоже я что-то перемудрил там smile

Сделал тотальный рефакторинг, всё заработало...

#!/usr/bin/perl

use WWW::Wikipedia;

my $wikientry = "Яблонец-над-Нисоу";
my $wiki = WWW::Wikipedia->new( language => 'ru');
my $entry = $wiki->search( $wikientry );
print $entry->raw();

Offline

#13 2010-10-23 15:49:13

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Можно ещё глупый вопрос?

В $entry->raw(); получаем одним куском текст с переносами строк. Как этот кусок обработать построчно?

Offline

#14 2010-10-23 15:54:08

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

split "\r\n", $entry->raw()

Offline

#15 2010-10-23 16:08:44

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Лучше я сразу скажу что хочу получить smile

Я получаю сырой текст статьи, в котором есть в конце строки типа:

...
{{нет иллюстраций}}
{{cz-geo-stub}}
[[Категория:Яблонец-над-Нисоу|*]]


[[cs:Jablonec nad Nisou]]
[[de:Jablonec nad Nisou]]
[[dsb:Jablonec nad Nisou]]
[[en:Jablonec nad Nisou]]
[[eo:Jablonec nad Nisou]]
[[es:Jablonec nad Nisou]]
[[fr:Jablonec nad Nisou]]
...

Мне надо из строки по коду
[[cs:.+]]
Получить
Jablonec nad Nisou

Может регексп можно на весь текст напустить, но я пока не соображу как.

...
my $rawtext = $entry->raw()."\n";
$rawtext =~ s/[[cs:(.+)]]/\1/m;
print $rawtext;

Возвращает весь текст целиком.

После недолгого перерыва в общении с перлом все навыки выветриваются, и похоже я туплю smile

Offline

#16 2010-10-23 16:18:59

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

my ($cs) = $rawtext =~ /\[cs:([^\[]+)\]/;

Offline

#17 2010-10-23 16:26:28

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Во! Спасибо, работает!

А то я чота типа такого намалевал: $rawtext =~ s/.*\[\[cs:(\w+)\]\].*/\1/s;

Разные вариации либо весь текст оставляют, либо от нужного места до конца, либо вообще всё съедается. smile

Offline

#18 2010-10-23 17:37:02

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Так, теперь у меня есть осм-файл с более 600 чешских городов, плюс список соответствия чешских и русских названий чуть более сотни городов, взятый из википедии:

Прага:Praha
Брно:Brno
Острава:Ostrava
Пльзень:Plzeň
Либерец:Liberec
Оломоуц:Olomouc
Усти-над-Лабем:Ústí nad Labem
Градец-Кралове:Hradec Králové
Ческе-Будеёвице:České Budějovice
Пардубице:Pardubice
Гавиржов:Havířov
Злин:Zlín
Кладно:Kladno
Мост (город):
Карвина:Karviná
Фридек-Мистек:Frýdek-Místek
Опава:Opava
Карлови-Вари:
Теплице:Teplice
Дечин:Děčín
Йиглава:Jihlava
Хомутов (город):
Пршеров:Přerov
Яблонец-над-Нисоу:Jablonec nad Nisou
Простеёв:Prostějov
Млада-Болеслав:Mladá Boleslav
Ческа-Липа:Česká Lípa
Тршебич:Třebíč
Тршинец:Třinec
Табор (город):Tábor
Абертамы:
Адамов (район Бланско):Adamov (okres Blansko)
Аш:Aš
Бенешов:Benešov
Бероун:Beroun
Брно:Brno
Всетин:Vsetín
Вишков:Vyškov
Гавиржов:Havířov
Гавличкув-Брод:Havlíčkův Brod
Глучин:Hlučín
Годонин:Hodonín
Градец-Кралове:Hradec Králové
Двур-Кралове:
Дечин:Děčín
Дивишов:Divišov
Домажлице:Domažlice
Есеник:Jeseník
Жатец:Žatec
Железна-Руда:Železná Ruda
Злин:Zlín
Зноймо:Znojmo
Йиглава:Jihlava
Йиндржихув-Градец:Jindřichův Hradec
Йичин:Jičín
Карвина:Karviná
Карловы Вары:Karlovy Vary
Кашперске-Гори:Kašperské Hory
Кинжварт:
Кладно:Kladno
Клатови:Klatovy
Колин:Kolín
Коуржим:Kouřim
Кралупи:
Крнов:Krnov
Кутна-Гора:Kutná Hora
Лазне-Богданеч:Lázně Bohdaneč
Ланшкроун:Lanškroun
Летоград:Letohrad
Либерец:Liberec
Либице:
Литомержице:Litoměřice
Литомышль:
Лоуни:Louny
Лугачовице:Luhačovice
Марианске-Лазне:Mariánské Lázně
Мельник (город):Mělník
Миловице:Milovice
Мирослав (город):Miroslav (okres Znojmo)
Млада-Болеслав:Mladá Boleslav
Мнихово-Градиште:Mnichovo Hradiště
Мост (город):
Мшено:Mšeno
Нимбурк:Nymburk
Нови-Йичин:Nový Jičín
Оломоуц:Olomouc
Опава:Opava
Острава:Ostrava
Пардубице:Pardubice
Писек:Písek (město)
Пльзень:Plzeň
Подебради:Poděbrady
Прага:Praha
Пршебуз:Přebuz
Пршибислав:Přibyslav
Пршибор:Příbor (okres Nový Jičín)
Пршибрам:Příbram
Рожмберк-над-Влтавоу:Rožmberk nad Vltavou
Раковник:Rakovník
Рокицани:Rokycany
Роуднице-над-Лабем:Roudnice nad Labem
Свитави:Svitavy
Седлец-Прчице:Sedlec-Prčice
Славков-у-Брна:Slavkov u Brna
Соколов (город):
Страконице:Strakonice
Табор (город):Tábor
Тахов:Tachov
Телч:
Теплице:Teplice
Терезин:Terezín
Трутнов:Trutnov
Тршебич:Třebíč
Тршебонь:Třeboň
Тршинец:Třinec
Усти-над-Лабем:Ústí nad Labem
Усти-над-Орлици:Ústí nad Orlicí
Франтишкови-Лазне:Františkovy Lázně
Фридек-Мистек:Frýdek-Místek
Фридлант:Frýdlant
Фульнек:Fulnek
Хеб:Cheb
Хомутов (город):
Хрудим:Chrudim
Ческа Липа:
Ческе-Будеёвице:České Budějovice
Чески-Крумлов:Český Krumlov
Чески-Тешин:Český Těšín
Шлукнов:Šluknov
Шумперк:Šumperk
Яблонец-над-Нисоу:Jablonec nad Nisou

Как теперь это всё залить в name:ru ?

Offline

#19 2010-10-23 17:45:20

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

Что-то типа

use Geo::Parse::OSM;

my $addname = sub {
    if ( ... ) {
        $_[0]->{action} = 'modify';
        $_[0]->{tag}->{'name:ru'} = ...;
        print Geo::Parse::OSM->to_xml( $_[0] );
    } 
};

print "<osm>\n";
Geo::Parse::OSM->parse_file( 'file.osm', $addname );
print "</osm>\n";

Offline

#20 2010-10-23 18:03:31

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Хм... Выглядит вроде несложно smile

А что будет если попытаться добавить существующий тег с точно таким же значением?

Offline

#21 2010-10-23 18:05:01

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

Поменяет

Offline

#22 2010-10-23 19:18:01

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

Написал вроде. Остался косяк с юникодом.

Если я не делаю binmode STDOUT, ':utf8'; , то получается
    <tag k="name" v="Opava"/>
    <tag k="name:ru" v="Ðпава"/>

Если делаю, то
    <tag k="name" v="Opava"/>
    <tag k="name:ru" v="ÃÂÿðòð"/>

Без binmode нормально работают обычные принты в стдаут, но не работает
print Geo::Parse::OSM->to_xml( $_[0] );

С binmode портится что-то другое.

Что делать-то?

Консоль у меня юникодная
[ilis@altus osm_perl]$ locale
LANG=ru_RU.UTF-8

ЗЫ. И сравнение не работает если в чешском нейме есть гачеки (умляуты их).

        $csname = $_[0]->{tag}->{'name'};
        if ( $hash{$csname} ne '' && $_[0]->{tag}->{'name:ru'} eq '') {

Last edited by Ilis (2010-10-23 19:23:13)

Offline

#23 2010-10-23 19:24:44

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

to_xml отдаёт уже готовый utf8, дополнительный фильтр не требуется.
Пиши его в отдельный файл.
Или если нужно именно с фильтром, то print decode( 'utf8', Geo::Parse::OSM->to_xml( $_[0] ) );

Offline

#24 2010-10-23 19:28:33

Ilis
Member
From: Екатеринбург
Registered: 2009-05-24
Posts: 5,970

Re: perl + .osm

liosha wrote:

to_xml отдаёт уже готовый utf8, дополнительный фильтр не требуется.
Пиши его в отдельный файл.
Или если нужно именно с фильтром, то print decode( 'utf8', Geo::Parse::OSM->to_xml( $_[0] ) );

Может он его там два раза отдаёт?

И что делать со сравнением? Из сотни городов только полтора десятка отбираются.

Offline

#25 2010-10-23 19:31:13

liosha
Member
From: Moscow
Registered: 2008-03-04
Posts: 8,447
Website

Re: perl + .osm

Где-то теряешь кодировку. Где именно, вслепую угадать сложно  smile

Offline

Board footer

Powered by FluxBB