perl + .osm

Правильно, и не должно работать. В $_[0] там уже всё и так раскодировано.

По дороге откуда куда?

Может какие-то тесты написать?

Прога пока вот такая:


#!/usr/bin/perl

# use Encode;
# use utf8;
use Geo::Parse::OSM;

# binmode STDOUT, ':utf8';

my $ru; my $cs; my $csname;
my %hash = ();
my $addname = sub {
        $csname = $_[0]->{tag}->{'name'};
        # $csname = decode( 'utf8', $_[0]->{tag}->{'name'});
        if ( $hash{$csname} ne '' && $_[0]->{tag}->{'name:ru'} eq '') {
                $_[0]->{action} = 'modify';
                $_[0]->{tag}->{'name:ru'} = $hash{$csname};
                print Geo::Parse::OSM->to_xml( $_[0] );
                # print decode( 'utf8', Geo::Parse::OSM->to_xml( $_[0] ) );
        }
};

open(MYINPUTFILE, "<ru_cs_towns.txt");
while(<MYINPUTFILE>) {
        chomp;
        ($ru, $cs) = split /:/;
        $hash{$cs} = $ru;
        print "$cs --> $hash{$cs}\n";
}


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

Результат такой:


...
Cheb --> Хеб
Chrudim --> Хрудим
Česká Lípa --> Ческа-Липа
České Budějovice --> Ческе-Будеёвице
...
  <node action="modify" id="86964510" version="4" timestamp="2008-11-04T13:10:12Z" uid="308" user="MichaelCollinson" changeset="676656" lat="48.9474349" lon="16.3134502" visible="true">
    <tag k="is_in" v="Czech Republic, Europe"/>
    <tag k="is_in:continent" v="Europe"/>
    <tag k="is_in:country_code" v="cz"/>
    <tag k="name" v="Miroslav"/>
    <tag k="name:ru" v="ÐиÑоÑлав"/>
    <tag k="place" v="town"/>
    <tag k="source" v="geonames.org,cs.wikipedia.org,nga.mil"/>
  </node>
  <node action="modify" id="86965801" version="3" timestamp="2008-11-04T13:09:50Z" uid="308" user="MichaelCollinson" changeset="676656" lat="50.5607811" lon="15.9128796" visible="true">
    <tag k="is_in" v="Czech Republic, Europe"/>
    <tag k="is_in:continent" v="Europe"/>
    <tag k="is_in:country_code" v="cz"/>
    <tag k="name" v="Trutnov"/>
    <tag k="name:ru" v="ТÑÑÑнов"/>
    <tag k="place" v="town"/>
    <tag k="source" v="geonames.org,cs.wikipedia.org,nga.mil"/>
  </node>

[ilis@altus osm_perl]$ cat ru_cs_towns.txt | wc -l
93
[ilis@altus osm_perl]$ ./make_osm_cz.pl | grep ‘“name”’ | wc -l
25

Cheb, Chrudim – обрабатываются
Česká Lípa, České Budějovice – нет

open MYINPUTFILE, ‘<:utf8’, “ru_cs_towns.txt”;

Нда… модуль заработал, обычные принты разломались.

С модулем википедии таких проблем не было. И вообще раньше с моим перлом таких проблем не было. Думаю, дело всё-таки в модуле.

Может какие-то тесты на эту тему подготовить и найти багу?

Нет там багов, есть недопонимание работы с кодировками.
Для начала почитать http://perldoc.perl.org/perlunicode.html

Ну а про то, что to_xml выдаёт готовый utf8 вместо внутренней кодировки, я уже говорил.

Да что ж такое то! Теперь йосм не хочет файл открывать!

Ага, надо вместо обязательно

Ну и вот результат трудов: http://www.openstreetmap.org/browse/changeset/6150621

До сих пор не пойму, что меня торкнуло этим заняться! :slight_smile:

Там много и не по-русски.

Можно как-то по-простому, как сделать чтобы и обычные принты работали, и модуль всё понимал?

Дык я ж говорил как: все промежуточные файлы писать и читать с фильтром :utf8, а результат to_xml писать БЕЗ фильтра.

У меня уже мозг засыпает, пойду и я посплю…

Хотелось бы верить, что все эти проблемы действительно объективные, и иначе как танцем с бубном над работающим в остальных 99 % случаев перлом нормально с этим модулем работать невозможно.

Объективные, объективные :smiley:

Кодировки - это примерно такая же вещь, как указатели в C/C++. Некоторые люди понимают концепцию сразу и без проблем, а до других доходит с большим трудом. Уж насколько в Java простая схема, и то постоянно вызывает проблемы у начинающих… :slight_smile:

Я посмотрел changeset и хочу заметить (совершенно в отрыве от темы), что набор значений тэга принято разделять точками с запятой, а не запятыми :slight_smile:

Не будь эти проблемы объективными, мы бы вообще не знали никаких проблем с кодировками :wink:

Кстати, никто не сравнивал вариант работы с xml через модули Perl с вариантом вызова из perl xmlstarlet ? Что быстрее?

Если ты про source, то к этот конкретный ченжсет его не трогал.

Скажите тогда как мне после чтения из файла через фильтр потом печатать можно было по-русски?

open MYINPUTFILE, ‘<:utf8’, “ru_cs_towns.txt”;
while() {
chomp;
($ru, $cs) = split /:/;
$hash{$cs} = $ru;
print “$cs → $hash{$cs}\n”;
}

Ну в четвёртом же посте написано :slight_smile:

Ещё пачку залил: http://www.openstreetmap.org/browse/changeset/6153635

Так ведь блин одновременно не работает всё равно!

Šumperk → Шумперк
Jaroměř → Яромерж








Чтобы одновременно работало - 23-й пост
http://forum.openstreetmap.org/viewtopic.php?pid=112812#p112812

Можно просто отключить фильтр перед выводом xml-а:
binmode STDOUT;