マッシュアップ日記(3) フロムエーの結果をGoogleMapsにプロット
大井宏友です。
マッシュアップ日記の3回目です。いよいよリクルートのWEBサービスと地図をMash Upしてみようと思います。
たたみラボではじゃらんWEBサービスでたくさん遊んできたので、今回は緯度経度を返すもう一つのWEBサービス、 フロムエーを使いたいと思います。
サンプルサイト
こちらをご覧ください。
http://tatamilab.jp/~ooi1/GoogleSample3.html
このサンプルは、ページが開くと同時にフロムエーWEBサービスを実行して、 その結果をGoogle Mapsに表示します。
フロムエーWEBサービスはいろんな細かい軸で検索をすることが可能なのですが、このサンプルでは、
- リゾート版で、
- 全ての中エリアを検索
- 各エリアごとに最大20件ずつ結果を取得
- 複数の地点が登録されている求人の場合、データの一つ目の地点だけ
という条件で取得したものをプロットしています(サンプルということでかなり手を抜いちゃってます…)。
では、プログラムの解説です。
まず、APIキーを取得
フロムエーWEBサービスを利用するためにはサイトごとのAPIキーの取得が必要です。 Mash Up Awardに参加登録すると発行手続きが書かれたメールが届きますので、 それを参考に取得してください。
サーバ側の処理
サーバー側では、
- フロムエーWEBサービスを実行する
- XMLをJSONで返す
ということをしています。
また、フロムエーWEBサービスが返すXMLはShift-JIS(!)だったりするので、世のWEBサービスに合わせて、 またXMLパーサがちゃんと解釈できるようにUTF-8に変換をしています。
さらに、前述の通りフロムエーWEBサービスが返す緯度経度の形式とGoogle Mapsで使用する形式が違うので、変換が必要です。この形式変換を実装中に分かった、あらたな注意点を二つほど明記しておきます。
- フロムエーWEBサービスの緯度経度の精度は細かくない
Location::GeoToolモジュールが認識できる形式は、 度.分.秒.nnnという、秒よりもさらに細かい単位が必要なのですが、フロムエーの緯度経度は度.分.秒までですので、 モジュールに渡す前に後ろに".000"という文字列を追加しておきます。
また、 フロムエーの緯度経度には頭にN,Eという方角をあらわす記号がついていますが、 Location::GeoToolでは認識できませんので削除しておきます。
- フロムエーの緯度経度は旧日本測地系でした
地図にプロットしてみて分かったのですが、 フロムエーの緯度経度は旧日本測地系でした。Googleは世界測地系ですから、 Location::GeoToolで形式の変換に加えて測地系の変換も行ってください。
Perl CGIソース
#!/usr/bin/perl
#
#フロムエーWebサービスを利用して、リゾート版で募集中の求人情報を取得するサンプル
#XMLをJSONに変換
#フロムエー緯度経度をGoogleでそのままつかえる緯度経度に変換
#
#大井宏友@たたみラボ
#2006/07/06 初版
#使用するPerlモジュール
use strict;
use utf8;
use LWP::Simple;
use XML::Simple;
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
use JSON;
use CGI::Carp qw(fatalsToBrowser);
use Location::GeoTool;
use Encode qw/from_to/;
#リゾート版のエリアコード
my @area_code_array = ("81","e1","e2","e3","e4","85","86");
#結果の入れ物を用意。
my $results = [];
#リゾート版の中エリアごとにWEBサービスを呼ぶ
foreach my $area_cd (@area_code_array){
my $ws_url = 'http://xml.froma.com/s/r/jobSearch.jsp?api_key=(あなたが取得したAPIキー)&ksjcd=07&edition_cd=4&m_area_cd=' . $area_cd;
my $fa_res = get($ws_url);#WEBサービスをリクエスト
#結果をutf8に変換する
from_to($fa_res,'Shift_JIS', 'utf8');
#headerも置換
$fa_res =~ s/Shift_JIS/utf-8/;
#結果を分解
my $xmlsimple = XML::Simple->new();
my $fa_results = $xmlsimple->XMLin($fa_res, ForceArray => ['Offer','GeoPoint']);
if($fa_results->{Code} = 200){
foreach my $offer (@{$fa_results->{Offer}}){
#緯度経度を変換
foreach my $Geopoint (@{$offer->{GeoPointList}{GeoPoint}}){
my $lat = $Geopoint->{GeoPointLatitude};
my $lon = $Geopoint->{GeoPointLongitude};
#緯度経度の頭文字は不要なので消す。
$lat =~ s/N//;
$lon =~ s/E//;
#Location::GeoToolが認識できるようにミリ秒単位での表記に変更
$lat = $lat . ".000";
$lon = $lon . ".000";
#フロムエーの形式(度.分.秒、旧日本測地系)からGoogleの形式(degree、世界測地系)に変換
my $wGeo = Location::GeoTool->create_coord($lat, $lon, 'tokyo', 'gpsone')->datum_wgs84->format_degree;
$Geopoint->{GeoPointLatitude} = $wGeo->lat;
$Geopoint->{GeoPointLongitude} = $wGeo->long;
}
#結果用配列に追加
push(@{$results}, $offer);
}
}
}
#結果をJsonで返す
my $resJs = objToJson($results);
utf8::encode($resJs);
print "Content-Type: text/javascript; charset=utf-8\n\n";
print $resJs."\n";
JavaScript側の処理
CGIからはJSONで結果を戻しているので、それをJavaScript側で受け取って、 GoogleMaps上にプロットしています。
JavaScriptで、JSONからGoogle Mapsにプロットする方法についてはサンプルページのHTMLソースを読んでみてください。
バックナンバー
TRACKBACK URL:
POST COMMENT
TRACKBACKS
? JSONPでGoogle Mapsとカーセンサーのマッシュアップサンプル by メディアテクノロジーラボ ブログ大井宏友です。 「マッシュアップ」といえば「地図」を思い浮かべる方は結構多いと思います。昨年、MTLの前身組織のひとつ「たたみラボ」ではじゃらんやホットペ...


COMMENTS
mash upっていうんすねー。
意味はよくわかんないすけど。
金額だけの切り口で、これをやれ!みたいなサイトがあっても、
いいかな、とは、思いました。
0~10,000→バイトせえor国内旅行
10,000~50,000→バイトせえor国内旅行
50,000~250,000→海外旅行、引越しせえ
250,000~750,000→車買え、引越しせえ
750,000~→車買え、家買え
みたいな。
金額だけだと、散漫だったら、
「楽しみたい」
「楽したい」
「何かを変えたい」
みたいな、条件をつけるとか。
「フォローユアハート」検索で、
Rサイト全検索だ!
July 7, 2006 8:44 AM by matsuoy※web0.3ぐらいの会社にいるので、マヒしてて、
「まじめ」なアイデアは全然浮かばないす、、、
このFromA APIのびっくりなところは、取得する、XMLの文字コードが Shift_JIS であるというところ。
いまどき、XMLがShift_JISというのも驚きですが、素直に仕様だと思って、文字変換します。
しかし、ここで忘れてしまいそうなのがheaderの置換。
これをしないと、パーサーのエラーに悩まされます。
#headerも置換
$fa_res =~ s/Shift_JIS/utf-8/;
July 7, 2006 12:53 PM by フナミタカオこれ大切です