M.C.P.C.

―むり・くり―プラスコミュニケーション


« 2010年10月 | トップページ | 2010年12月 »

2010.11.30

Firefox 3.6.3だとGeocodingでWi-Fiがないとエラーになるので困る

Firefoxってけっこうすぐバージョンアップしちゃうので見逃しがちなんですけれども、Firefox 3.6.3あたりだと、Geocodingで現在の場所を取得しようとした時、Wi-Fiがつながっていないと、エラーが出るみたい。Firebugでのエラーログは、

location is undefined
file:///C:/Program%20Files/Mozilla%20Firefox/components/NetworkGeolocationProvider.js
Line 91

となってしまう。よって、3.6.3のときだけGeocodingしないような処理が必要かもしれません。

現行バージョンの3.6.12では、Wi-Fiがない端末では、IP Geocodingで取得するようになっているので大丈夫みたいです。

[GoogleMaps] | 固定リンク | コメント (0) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

2010.11.29

Adobe Creative Suite 出力対応店一覧をGoogle Mapsで表示させる(17)

アドビのCS5対応プリントショップのリストのページから、Google Mapsに表示させるやつの17回目。

前回は、Google Maps APIのジオコーディングでうまく出なかった3つの住所を、どうにかしてジオコーディングを通すため、「辞書」を作って、なんとかすべての住所に対するジオコーディングができる、というところまでやりました。

今回は、当初の予定では、JSONファイルを書き出す、というのをやるつもりでしたが、予定を変更して、アドビさんが、間違っている住所を直してくれた、ということをお知らせします。


今日のお昼、たまたまセミナーがありまして、そこにアドビシステムズのいわもとさん(http://blogs.adobe.com/iwamoto/)が講師にいらっしゃるということで、お会いして、かくかくしかじかと、大阪の印刷会社さんの住所が[×西城区 ○西成区]なんですよ、Google Maps APIに問い合わせるとエラー出よるんですよ、と申し上げたところ、本日夜にメールがきまして、直してくださいました!

Adobe Creative Suite 出力対応店一覧 (2010-11-29修正済み) [www.adobe.com]

スピーディーな対応をしていただきました!

いわもとさんはセミナー後東京に戻られてから対応をされたことと思われますので、お疲れのところ大変だったと思います。ありがとうございました。

というわけで、前回作った住所読み変え用辞書のうち、1つの項目は要らなくなりましたとさ。

つまり辞書の部分がこうなる。

修正前:

my $dict = (
  '岐阜県岐阜市長良福田町1丁目30番地'
    => '岐阜県岐阜市福田町1丁目30',
  '大阪府大阪市西城区南津守7-15-16'
    => '大阪府大阪市西成区南津守7-15-16',
  '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F'
    => '京都府京都市下京区五条烏丸町407-2',
);

修正後:

my $dict = (
  '岐阜県岐阜市長良福田町1丁目30番地'
    => '岐阜県岐阜市福田町1丁目30',
  '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F'
    => '京都府京都市下京区五条烏丸町407-2',
);

次回は、当初はJSONを書き出してしまう話をしようかと思っていましたが、辞書が出てきたついでに、Google Maps APIのジオコーディング結果を辞書にしてしまうことをやってみたいと思います。つまり、辞書を逐次追加していくものになります。

[GoogleMaps] | 固定リンク | コメント (0) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

2010.11.28

Google Maps API V3ってAPIキーいらないのか

いまGoogle Maps APIをいじっているんですが、僕が昔いろいろ作ったやつはGoogle Maps API V2で作っていたんです。

たとえば: M.C.P.C.: Google Maps APIを使って住所リストからGoogle Mapsに表示するまで

んで、今回またいじり始めたら、いつの間にかGoogle Maps API V3になっていました。

V2では申請制だったAPIキー取得が、V3ではいらなくなっています。

他にもいろいろ変っている部分もありますが、せっかくなので今勉強中です。例のAdobe Creative Suite 対応印刷屋さんの一覧も、すでにV3で表示ができていて、iPadでもちゃんと表示できている状態。

http://labo.dtpwiki.jp/printshop/20101128.html

もう少ししたら出せると思います。

[パソコン・インターネット] | 固定リンク | コメント (0) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

2010.11.27

Adobe Creative Suite 出力対応店一覧をGoogle Mapsで表示させる(16)

アドビのCS5対応プリントショップのリストのページから、Google Mapsに表示させるやつの16回目。

前回は、京都市専用のジオコーダ「ジオどす」を使ってみたのですが、今回の住所ではあまり結果が良くないっぽいので、やめた、っというところまでやりました。

今回は、Google Maps APIのジオコーディングでうまく出なかった3つの住所を、どうにかしてジオコーディングを通すため、「辞書」を作る、というのをやってみたいと思います。


さて、前々回と、前回で、Google Maps APIのジオコーダでうまく出ない3つの住所と、それを修正してうまく出る住所、というのが判明しています。

×岐阜県岐阜市長良福田町1丁目30番地
○岐阜県岐阜市福田町1丁目30

×大阪府大阪市西城区南津守7-15-16
○大阪府大阪市西成区南津守7-15-16

×京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F
○京都府京都市下京区五条烏丸町407-2

「×」のほうが、アドビのページから取得できる住所で、これをそのままジオコーダに突っ込んでもだめです。「○」のほうは、ジオコーダで座標が取得できる住所です。

つまり、「×」の住所が取得された時、「○」の住所に差し替えてしまえばよいわけです。

プログラムとしては、こんな感じになります。

Filename: test16.pl

use strict;
use warnings;
use utf8;
use Encode;
 
my $dict = (
  '岐阜県岐阜市長良福田町1丁目30番地'
    => '岐阜県岐阜市福田町1丁目30',
  '大阪府大阪市西城区南津守7-15-16'
    => '大阪府大阪市西成区南津守7-15-16',
  '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F'
    => '京都府京都市下京区五条烏丸町407-2',
);
 
my $input = '岐阜県岐阜市長良福田町1丁目30番地';
#my $input = '大阪府大阪市西城区南津守7-15-16';
#my $input = '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F';
 
print "input: $input\n";
print 'output: '.encode_utf8($dict{$input})."\n";
 
exit;
 
__END__

実行してみる

$ perl test16.pl
input: 岐阜県岐阜市長良福田町1丁目30番地
output: 岐阜県岐阜市福田町1丁目30
$

このように、連想配列を使うと、ある文字列に対応した文字列を用意できます。なので、「辞書」と呼ぶこともあります。

いまのプログラムのままだと、辞書が引けない文字列があった場合は、何も出力されないことになりますので、辞書が引けなかった場合は、辞書を引こうとした文字列をそのまま出力するようにします。

Filename: test17.pl

use strict;
use warnings;
use utf8;
use Encode;
 
my $dict = (
  '岐阜県岐阜市長良福田町1丁目30番地'
    => '岐阜県岐阜市福田町1丁目30',
  '大阪府大阪市西城区南津守7-15-16'
    => '大阪府大阪市西成区南津守7-15-16',
  '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F'
    => '京都府京都市下京区五条烏丸町407-2',
);
 
#my $input = '岐阜県岐阜市長良福田町1丁目30番地';
#my $input = '大阪府大阪市西城区南津守7-15-16';
#my $input = '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F';
my $input = '北海道札幌市西区二十四軒2条6丁目1番8号';
 
print "input: $input\n";
print 'output: '.encode_utf8($dict{$input} or $input)."\n";
 
exit;
 
__END__

($dict{$input} or $input)

の様に書きますと、連想配列のキーに対する値がある場合は $dict{$input} の値が使われ、ない場合は $dict{$input} が undef になりますので、or 以降の $input が採用されます。

この辞書を、12回目のスクレイピングスクリプトとくっつけます。

Filename: test18.pl

#!/usr/bin/perl
 
use strict;
use warnings;
use utf8;
use Web::Scraper;
use YAML;
use Encode;
use WebService::Simple;
 
my %dict = (
  '岐阜県岐阜市長良福田町1丁目30番地'
    => '岐阜県岐阜市福田町1丁目30',
  '大阪府大阪市西城区南津守7-15-16'
    => '大阪府大阪市西成区南津守7-15-16',
  '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F'
    => '京都府京都市下京区五条烏丸町407-2',
);
 
my $geo = WebService::Simple->new(
    response_parser => 'JSON',
    base_url => 'http://maps.google.com/maps/api/geocode/',
    param    => {
      region   => 'jp',
      language => 'ja',
      sensor   => 'false',
    },
);
 
open my $fh, '<', 'printshop.html';
my $html = decode_utf8(do { local $/; <$fh> });
close $fh;
 
my $s = scraper {
    process '//div[@class="tabcontent"][1]//table[@class="data-bordered max"]/tbody/tr', 'codes[]' => scraper {
        process '//td[1]', pref    => [ 'TEXT', sub { s/\s//g; } ];
        process '//td[2]', company => [ 'TEXT', sub { s/\s//g; } ];
        process '//td[3]', address => [ 'TEXT', sub { s/\s//g; s/TEL:.+$//i; return $_; } ];
        process '//td[3]', phone   => [ 'TEXT', sub { s/\s//g; if(m/TEL:([\d-]+)/i){return $1;};}];
        process '//td[3]', fax     => [ 'TEXT', sub { s/\s//g; s/:/:/g; if(m/FAX:([\d-]+)/i){return $1;};undef;}];
        process '//td[4]', illustratorcs5 => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[5]', indesigncs5    => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[6]', pdfx1a         => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[7]', pdfx4          => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
    };
};
 
my $scraped = $s->scrape($html);
 
foreach my $item ( @{$scraped->{codes}} ) {
  my $address = $item->{address};
  my $res = $geo->get( 'json', { address => ( $dict{$address} or $address ) } );
  my $val = $res->parse_response();
  print Dump( $val );
  sleep 1;
}
 
exit;
 
__END__

こんな感じで実行

$ perl test18.pl > results18.txt
$ grep -e 'status' resutls18.txt
status: OK
status: OK
status: OK
...
status: OK
status: OK
status: OK
$

これで、すべての住所がGoogle Maps APIでジオコーディングできるようになりました。

本当は、こうやって辞書を用意するのではなく、サイトに上がっているデータが正規化されているほうがいいんですけれども。ともかく、大阪の印刷会社さんの住所の件は、近々アドビさんがセミナーで来たときに直してくれるようお願いしてみようかなと思っています。(←迷惑かもな)

次回は、すべての住所から座標がとれましたので、いよいよGoogle Maps上で表示できるよう、JSON形式のデータを吐き出せるようにしたいと思います。


(2010-11-29 21:32追記)

2010-11-29 21:00の時点で、大阪の企業様の住所は、アドビ様から修正をしていただきました(アドビシステムズの岩本様からご連絡をいただきました)。

[GoogleMaps] | 固定リンク | コメント (0) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

2010.11.26

Adobe Creative Suite 出力対応店一覧をGoogle Mapsで表示させる(15)

アドビのCS5対応プリントショップのリストのページから、Google Mapsに表示させるやつの15回目。

前回は、Google Maps APIでうまくジオコーディングできない住所を特定し、それぞれどのようになっているか解析してみました。

今回は、京都市専用のジオコーダ「ジオどす」を使ってみて、京都市の住所のジオコーディングをやってみたいと思います。


まず、「ジオどす」(http://http://geodosu.com/)に行きます。

Geodosu01

右側の「APIキー取得」を選択します。

Geodosu02s

所定の入力をして規約読んでチェックつけて「APIキー発行」ボタンを選択します。

Geodosu03

これで、APIキーが書かれた電子メールが届きますので、APIキーを確認して、下記の様なプログラムを書いてみます。

Filename: test15.pl

#!/usr/bin/perl
 
use strict;
use warnings;
use utf8;
use YAML;
use Encode;
use WebService::Simple;
 
my $geo = WebService::Simple->new(
    response_parser => 'JSON',
    base_url => 'http://api.geodosu.com/v2/geodosu2?',
    param    => {
      apikey     => '●●',
      output     => 'json',
      preprocess => 'true',
    },
);
 
my $address = '京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F';
my $res = $geo->get( 'json', { address => $address } );
my $val = $res->parse_response();
print Dump( $val );
 
exit;
 
__END__

実行してみると……

$ perl test15.pl
---
result:
  addresses:
    detected:
      kana: まつばらどおり からすま  さがる 
      kanji: 松原通烏丸下ル
      roman: matsubara-dori karasuma sagaru
    input: 京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F
    pre_processed: 京都市下京区烏丸町4
  coordinates:
    datum: {}
    estrange:
      lat:
        - 34.997674
        - 34.997674
        - 34.998886
        - 34.998886
        - 34.997674
      lon:
        - 135.759294
        - 135.760002
        - 135.760002
        - 135.759294
        - 135.759294
    estrange_ne:
      lat: 34.998886
      lon: 135.760002
    estrange_sw:
      lat: 34.997674
      lon: 135.759294
    point:
      lat: 34.99828
      lon: 135.759703
  copyright: ジオどすⅡ京都通り名ジオコーダー copyright 2009 All rights reserved by ジオどす・プロジェクト
  geocoded: 1
  geocoder: geodosu2
$

これの、

    point:
      lat: 34.99828
      lon: 135.759703

が「ジオどす」でジオコーディングされた座標です。

あとは、このプログラムを今までのスクリプトに組み込めばいいのですが、その前に得られた座標の妥当性を確認しましょう。

得られた座標を「34.99828,135.759703」の様にコンマでつないで、Google Mapsの入力欄に入れてみます。

Geodosu04s
▲ちょっと遠いよね

ちなみに、Google Mapsで、「京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F」から、通り名とビル名を取り去った「京都府京都市下京区五条烏丸町407-2」で検索したらこんな感じ。

Geodosu05s
▲ドンピシャ

……ジオどすのほうが正確じゃないってことで、ジオどすを使わない方向でいきたいと思います。

次回は、座標が取得できない住所が3か所も出ちゃったので、これをどのようにごまかすか、それには、辞書を用意しよう! ていうことをやってみたいと思います。

[GoogleMaps] | 固定リンク | コメント (2) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

2010.11.25

G Dataアンチウイルス2011のせいで女性声優のグラビアがとんでもないことに……!

G Data アンチウイルス 2011が3年分3台で5980円と非常に安すぎたので購入して、とりあえず1か月体験版を使っているんですけれども(←使う順番がまちがっているだろ)、ウェブ保護機能がなんだが微妙。

Firefoxで表示

Gdatatorichigae01
▲ごりっぱ

Operaで表示

Gdatatorichigae02
▲なんてことでしょう

僕メインブラウザがOperaなんですけれども、G Data アンチウイルス 2011を入れた後ウェブ保護機能のせいで画像をはめる位置が取り違えることがある。これってある意味器用だよね。

田中理恵さんに悪いので直してくれーwww

[パソコン・インターネット] | 固定リンク | コメント (0) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

2010.11.24

iPadのiOS4.2アップデートでkikeruインターネットラジオアプリがバックグラウンド再生GJしかしkikeruが2010/12/24終了で俺涙目

昨日、iPadのOSであるところのiOSを4.2にアップデートしてみました。

目玉機能としてマルチタスクがあるのですが、kikeruというインターネットラジオアプリを流しながら他のことができないのが今まで不満だったので、試してみました。

kikeruを起動してから、他のアプリを起動するためホームボタンを押すと、いままではkikeruが終了していましたが、アップデート後は、音声が流れたままで、左上に再生表示がされたままホーム画面に戻ります。そのまま、他のアプリが使えます。

アプリが動いているときに、バックに控えているアプリ一覧を表示するには、ホームボタンをダブルクリックします。

Ios4201
▲もしドラの挿絵を見ながら今動いているアプリを表示

最下段の部分が割り込んできていますが、ここを右になぞると、音声再生中のアプリの制御や、画面の明るさの制御ができますよ。

Ios4202
▲もしドラの挿絵眺めるだけじゃなくて本文読めってば

ところがですね、kikeruラジオって2010年12月24日でサービス終了してしまうんだって! なんてこったい! ちょっと残念ではありますね……

[パソコン・インターネット] | 固定リンク | コメント (0) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

2010.11.23

Adobe Creative Suite 出力対応店一覧をGoogle Mapsで表示させる(14)

アドビのCS5対応プリントショップのリストのページから、Google Mapsに表示させるやつの14回目。

前回は、Google Maps APIから取得する箇所で「OVER_QUERY_LIMIT」というステータスが出ている個所の原因が、取得間隔が短すぎることにあると思い、sleep 1; を入れて1秒WAITを入れることで、見事「OVER_QUERY_LIMIT」を消すことができました。しかしまだ「ZERO_RESULTS」というステータスが出る箇所が残っている、というところまでやりました。

今回は、「ZERO_RESULTS」と出る箇所をどのように解消すればいいか、ということを考えてみます。


まず、ZERO_RESULTS、というのは、答えがない、ていうことですので、Google Maps APIで見つからないっていうことだと思います。ということで、どのような問い合わせ(クエリー)をしたら、答えがない、といわれたか、ということを見てみました。

プログラムを以下のように変えます。変えた内容は、statusで「ZERO_RESULTS」が得られたときに、クエリー内容と、返却された値を出力します。

Filename: test13.pl

#!/usr/bin/perl
 
use strict;
use warnings;
use utf8;
use Web::Scraper;
use YAML;
use Encode;
use WebService::Simple;
 
my $geo = WebService::Simple->new(
    response_parser => 'JSON',
    base_url => 'http://maps.google.com/maps/api/geocode/',
    param    => {
      region   => 'jp',
      language => 'ja',
      sensor   => 'false',
    },
);
 
open my $fh, '<', 'printshop.html';
my $html = decode_utf8(do { local $/; <$fh> });
close $fh;
 
my $s = scraper {
    process '//div[@class="tabcontent"][1]//table[@class="data-bordered max"]/tbody/tr', 'codes[]' => scraper {
        process '//td[1]', pref    => [ 'TEXT', sub { s/\s//g; } ];
        process '//td[2]', company => [ 'TEXT', sub { s/\s//g; } ];
        process '//td[3]', address => [ 'TEXT', sub { s/\s//g; s/TEL:.+$//i; return $_; } ];
        process '//td[3]', phone   => [ 'TEXT', sub { s/\s//g; if(m/TEL:([\d-]+)/i){return $1;};}];
        process '//td[3]', fax     => [ 'TEXT', sub { s/\s//g; s/:/:/g; if(m/FAX:([\d-]+)/i){return $1;};undef;}];
        process '//td[4]', illustratorcs5 => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[5]', indesigncs5    => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[6]', pdfx1a         => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[7]', pdfx4          => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
    };
};
 
my $scraped = $s->scrape($html);
#print Dump($scraped->{codes});
 
foreach my $item ( @{$scraped->{codes}} ) {
  my $address = $item->{address};
  #print "$address\n";
  my $res = $geo->get( 'json', { address => $address } );
  my $val = $res->parse_response();
  next if $val->{status} ne 'ZERO_RESULTS';
  print encode_utf8("\nQuery: $address\n");
  print Dump( $val );
  sleep 1;
}
 
exit;
 
__END__

これを実行する。

$ perl test13.pl > results13.txt
$ less results13.txt

Query: 岐阜県岐阜市長良福田町1丁目30番地
---
results: []
status: ZERO_RESULTS
 
Query: 京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F
---
results: []
status: ZERO_RESULTS
 
Query: 大阪府大阪市西城区南津守7-15-16
---
results: []
status: ZERO_RESULTS

どうやら、この3つの住所がGoogle Maps APIのジオコーディングでは出ないみたいです。
さっそく調べてみましょう。



岐阜県岐阜市長良福田町1丁目30番地

については、アドビのページに掲載されているこの住所に建っている会社さん(岐阜製版さん)のウェブサイトで調べても住所は相違ないんですが、Google Mapsでその会社さんの名前で検索して、その場所の緯度・経度から逆ジオコーディングをしてみます。

Google Mapsで「岐阜製版」で検索し、その場所を拡大して右クリックし、表示されたメニューの中から、「ここを地図の中心とする」を選択したあと、「リンク」をクリックして表示されたアドレスのなかかから、「このリンクをメールに貼り付けて地図を共有できます」の欄に表示されたアドレスは、

http://maps.google.co.jp/maps?f=q&source=s_q&hl=ja&geocode=&q=%E5%B2%90%E9%98%9C%E8%A3%BD%E7%89%88&sll=35.449484,136.773863&sspn=0.007481,0.021136&brcurrent=3,0x6003abc442c1690f:0x6a5eedbaac598cab,0&ie=UTF8&hq=%E5%B2%90%E9%98%9C%E8%A3%BD%E7%89%88&hnear=&ll=35.448821,136.773844&spn=0.000935,0.002642&z=19&iwloc=A

このURLのllっていうところが、緯度・経度となります。

ll=35.448821,136.773844

Googlemapcenter01s

Googlemapcenter02s

Googlemapcenter03

これを、逆ジオコーディングしてみます。

緯度・経度から、住所を求める逆ジオコーディングスクリプトは、次の通りです。

Filename: test14.pl

#!/usr/bin/perl
 
use strict;
use warnings;
use utf8;
use Web::Scraper;
use YAML;
use Encode;
use WebService::Simple;
use Data::Dumper;
 
my $geo = WebService::Simple->new(
    response_parser => 'JSON',
    base_url => 'http://maps.google.com/maps/api/geocode/',
    param    => {
      region   => 'jp',
      language => 'ja',
      sensor   => 'false',
    },
);
 
my $ll = '35.448821,136.773844';
my $res = $geo->get( 'json', { latlng => $ll } );
my $val = $res->parse_response();
#print encode_utf8("\nQuery: $address\n");
print Dump( $val );
 
exit;
 
__END__

実行結果:

---
results:
  - address_components:
      - long_name: 30
        short_name: 30
        types:
          - sublocality_level_4
          - sublocality
          - political
      - long_name: 1丁目
        short_name: 1丁目
        types:
          - sublocality_level_2
          - sublocality
          - political
      - long_name: 福田町
        short_name: 福田町
        types:
          - sublocality_level_1
          - sublocality
          - political
      - long_name: 岐阜市
        short_name: 岐阜市
        types:
          - locality
          - political
      - long_name: 岐阜県
        short_name: 岐阜県
        types:
          - administrative_area_level_1
          - political
      - long_name: 日本
        short_name: JP
        types:
          - country
          - political
    formatted_address: '日本, 岐阜県岐阜市福田町1丁目30'
    geometry:
      location:
        lat: 35.4488088
        lng: 136.7738601
      location_type: APPROXIMATE
      viewport:
        northeast:
          lat: 35.4519564
          lng: 136.7770077
        southwest:
          lat: 35.4456612
          lng: 136.7707125
    types:
      - sublocality_level_4
      - sublocality
      - political
...

というわけで、この経度・緯度に対応した住所は、Google Mapsによる逆ジオコーディングでは、「日本, 岐阜県岐阜市福田町1丁目30」というわけです。

×岐阜県岐阜市長良福田町1丁目30番地
○岐阜県岐阜市福田町1丁目30

住所の表記の仕方はいくつもあったりしますよね。しょうがないと思います。


大阪府大阪市西城区南津守7-15-16

については、大阪市の人なら気づくのかもしれませんが、間違い探しです。

×大阪府大阪市西城区南津守7-15-16
○大阪府大阪市西成区南津守7-15-16

アドビさっさと直せよ!(申請書類の書き間違いかもしれんけど)


京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F

これについては、住所の入力業務を行っている人はわかると思いますが、京都の住所って、上ル下ル入ルは道案内のサジェスチョンであって、なくても住所表記として成り立ちます。よって、

×京都府京都市下京区烏丸松原下ル五条烏丸町407-2烏丸KT第2ビル2F
○京都府京都市下京区五条烏丸町407-2

でGoogle Mapsでは表示される、というわけです。


次回は、京都市内の表記に対応した、「ジオどす」というサービスを使って、京都の住所表記からジオコーディングしてみたいと思います。

[GoogleMaps] | 固定リンク | コメント (0) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

2010.11.22

Adobe Creative Suite 出力対応店一覧をGoogle Mapsで表示させる(13)

アドビのCS5対応プリントショップのリストのページから、Google Mapsに表示させるやつの13回目。

前回は、アドビのサイトのHTMLをスクレイピングするスクリプト、Google Geocoding APIを使い、住所から緯度/経度を取得するスクリプトをくっつけて、それぞれの印刷会社の住所を取得してみましたが、何やらサーバから取得失敗しているんじゃね、的な不穏なエラーメッセージが混ざっていました。

今回は、エラーメッセージの出方を解析し、さらにエラーメッセージが出ないように取得してみたいと思います。


前回取得したテキストファイル results11.txt には、

...
---
results:
  - address_components:
      - long_name: 22
        short_name: 22
        types:
          - sublocality_level_5
          - sublocality
          - political
      - long_name: 3
        short_name: 3
        types:
          - sublocality_level_4
          - sublocality
          - political
      - long_name: りんくう南浜
        short_name: りんくう南浜
        types:
          - sublocality_level_1
          - sublocality
          - political
      - long_name: 泉南市
        short_name: 泉南市
        types:
          - locality
          - political
      - long_name: 大阪府
        short_name: 大阪府
        types:
          - administrative_area_level_1
          - political
      - long_name: 日本
        short_name: JP
        types:
          - country
          - political
    formatted_address: '日本, 大阪府泉南市りんくう南浜3−22'
    geometry:
      location:
        lat: 34.3778781
        lng: 135.2629286
      location_type: APPROXIMATE
      viewport:
        northeast:
          lat: 34.3810257
          lng: 135.2660762
        southwest:
          lat: 34.3747305
          lng: 135.259781
    types:
      - sublocality_level_5
      - sublocality
      - political
status: OK
---
results: []
status: OVER_QUERY_LIMIT
---
results: []
status: OVER_QUERY_LIMIT
---
results: []
status: OVER_QUERY_LIMIT
---
results: []
status: OVER_QUERY_LIMIT
---
results: []
status: OVER_QUERY_LIMIT
---
results: []
status: OVER_QUERY_LIMIT
---
results: []
status: OVER_QUERY_LIMIT
---
results: []
status: OVER_QUERY_LIMIT
---
results: []
status: OVER_QUERY_LIMIT
---
results: []
status: 	OVER_QUERY_LIMIT

と、statusにOVER_QUERY_LIMITとかでていました。他の個所には、ZERO_RESULTSとか入ってきていました。

そこで、得られたテキストの全体から、エラーメッセージがどういうタイミングで出ているのか、確認したいと思います。

どのように調べるかというと、grepを使います。

もうみんな忘れているかもしれないけれども、今回の制作物はLinux環境で作っていますので、こんな感じで入力するとよいです。

$ grep -e 'status' results11.txt > status.txt

結果はこんなかんじです。

Filename: status.txt

status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OK
status: OK
status: OK
status: OK
status: ZERO_RESULTS
status: ZERO_RESULTS
status: OK
status: OK
status: OK
status: OK
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT
status: OVER_QUERY_LIMIT

前回のスクリプトでは、Google Maps APIというネットワーク上のアクセスポイントに問い合わせをしていましたが、どうやら、問い合わせの制限があるところを超えてしまった、ということみたいです。

ということは、Google Maps APIへの問い合わせを行うタイミングをゆっくりにすればいいのかな? ということで、前回のプログラムをちょっと変えてみて、ゆっくり問い合わせするようにしてみます。具体的には、ウェイト(待ち時間)を付けてみます。

Filename: test12.pl

#!/usr/bin/perl
 
use strict;
use warnings;
use utf8;
use Web::Scraper;
use YAML;
use Encode;
use WebService::Simple;
 
my $geo = WebService::Simple->new(
    response_parser => 'JSON',
    base_url => 'http://maps.google.com/maps/api/geocode/',
    param    => {
      region   => 'jp',
      language => 'ja',
      sensor   => 'false',
    },
);
 
open my $fh, '<', 'printshop.html';
my $html = decode_utf8(do { local $/; <$fh> });
close $fh;
 
my $s = scraper {
    process '//div[@class="tabcontent"][1]//table[@class="data-bordered max"]/tbody/tr', 'codes[]' => scraper {
        process '//td[1]', pref    => [ 'TEXT', sub { s/\s//g; } ];
        process '//td[2]', company => [ 'TEXT', sub { s/\s//g; } ];
        process '//td[3]', address => [ 'TEXT', sub { s/\s//g; s/TEL:.+$//i; return $_; } ];
        process '//td[3]', phone   => [ 'TEXT', sub { s/\s//g; if(m/TEL:([\d-]+)/i){return $1;};}];
        process '//td[3]', fax     => [ 'TEXT', sub { s/\s//g; s/:/:/g; if(m/FAX:([\d-]+)/i){return $1;};undef;}];
        process '//td[4]', illustratorcs5 => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[5]', indesigncs5    => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[6]', pdfx1a         => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
        process '//td[7]', pdfx4          => [ 'TEXT',  sub { return $_ =~m|yes|i ? 1 : undef; } ];
    };
};
 
my $scraped = $s->scrape($html);
#print Dump($scraped->{codes});
 
foreach my $item ( @{$scraped->{codes}} ) {
  my $address = $item->{address};
  #print "$address\n";
  my $res = $geo->get( 'json', { address => $address } );
  my $val = $res->parse_response();
  print Dump( $val );
  sleep 1;
}
 
exit;
 
__END__

sleep 1; ていうので、プログラムが1秒止まりますので、Google Maps APIへの問い合わせも、1秒ごとになります。

$ perl test12.pl > results12.txt
$ grep -e 'status' results12.txt > status12.txt
$ less status12.txt

status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: ZERO_RESULTS
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: ZERO_RESULTS
status: ZERO_RESULTS
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK
status: OK

どうやら、sleep 1; がうまく効いて、OVER_QUERY_LIMIT が解消しました。

ZERO_RESULTSっていうエラーが残っていますが、これに関しては、次回調べてみますね。

[GoogleMaps] | 固定リンク | コメント (0) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

2010.11.21

とても使いにくいiPad/iPhone用タッチペン、水商売のねーちゃんにくれたら喜ばれたぞ。

この前iPhone4のアクティベーションを手伝ってきたんですけれども、持主は夜のお店のおねーさんで、付け爪が邪魔でせっかく買ったiPhone4がうまくいじれないようだったので、iPadを操作しようと思っていつぞや買ったんだけど使いにくくてほっぽって置いていたiPad/iPhone用スタイラスペンを貸してやったらすげえ好評だったので、くれてやった。

これでわらしべ長者的なことになるかと思ってたけれども、何もなかった。

[日記・コラム・つぶやき] | 固定リンク | コメント (0) | トラックバック (0) | このエントリーをはてなブックマークへ追加 livedoor Clipでこのサイトを登録している人数livedoor Clipでこの記事をクリップ!

< 最後 « これより前10ä»¶ | 全件