たたみラボ

  • about
  • member
  • r&d
  • blog
  • tatamicast

blog

RSS

じゃらんAPIを使って、宿をGoogle Map&Google Earthにマッピング

icon June 22, 2006 11:34 AM by funami このエントリーを含むはてなブックマーク

フナミタカオです
Where2.0で仕入れた、Google Map、Google EarthのKMLの有用性とためしてみたく、今回はAPIが公開されたじゃらんAPIをつかって、試してみました。


じゃらんAPI->KMLを生成し、そのKMLをGoogleMapとGoogleEarthで開いてみた。
いけました。
結構感動です。

↑北海道にじゃらんの宿がならんだ!

そして、GoogleMapでも、MAPの検索窓にKMLファイルを指定すれば、マップ上に表示されるという裏技(もちろん、オフィシャルに公開されているけど)をつかって、GoogleMap上でも表示できました。
じゃらん.net掲載の北海道の宿・ホテル100件
↑このリンクで表示されます。





実装は結構シンプルです


じゃらんAPIからJSONオブジェクトを出力する、スクリプトを以前公開しましたが、そのスクリプトを拡張しています。
#!/usr/bin/perl -w


#じゃらん宿表示API活用サンプル
#XMLをJSONに変換
#じゃらんの緯度経度をGoogleでそのままつかえる緯度経度に変換
#
#フナミタカオ@たたみラボ
#2006/06/22
#このソースは、コピー改変していただいてかまいません。どうぞ、じゃらん宿表示APIをご活用ください。
#じゃらん宿表示APIの詳細は http://jws.jalan.net/ws/viw/U01001

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;	#ココギコさんのGeoToolを使わせていただいています。
#http://www.annocpan.org/~KOKOGIKO/Location-GeoTool-1.98/lib/Location/GeoTool/Japanese.pod


my $xs = XML::Simple->new();

#QUERY_STRINGを取得
my $query_string = $ENV{'QUERY_STRING'};
if (!$query_string ){
	$query_string = "key=guest&pref=010000&l_area=012900&s_area=012911&h_type=1&start=1&count=1";

}

#じゃらんからデータを取得
my $url = "http://jws.jalan.net/APILite/HotelSearch/V1/?pict_size=1&$query_string";
my $res = get($url);
my $resRef = $xs->XMLin($res,ForceArray => ['Hotel']);
$resRef->{request_url} = $url;

#必要な情報を用いて、再構築、座標系の変換もここで行う。
#じゃらんは、測地系:日本、単位:ミリ秒(非常に目面しいですねえ...)
#Googleは  測地系:世界、単位:度
foreach my $hotel (@{$resRef->{Hotel}}){
	if ($hotel->{Y} == 999999999 || $hotel->{X} == 999999999){
		($hotel->{lat},$hotel->{lng}) = (-1,-1);
	}else{
		my $obj = Location::GeoTool->create_coord($hotel->{Y}/1000,$hotel->{X}/1000,'tokyo','second');
		 ($hotel->{lat},$hotel->{lng}) = $obj->datum_wgs84->format_degree->array;
	}
}
	
#JSONで戻す
if($query_string =~ /JSON=/){
	my $resJs = objToJson($resRef);
	utf8::encode($resJs);
	print "Content-Type: text/javascript; charset=utf-8\n\n";
	print $resJs."\n";
}elsif($query_string =~ /KML=/){
	#KMLへコンバージョン
	my $kmlRef = {Folder=>{Placemark => []}};
	my $folder = $kmlRef->{Folder};
	$folder->{name} = "jalan API -> KML Sample";
	$folder->{description} = "jalan API to KML";
	foreach my $hotel (@{$resRef->{Hotel}}){
		next if ($hotel->{lat} == -1);
		my $imgtag = ''.$hotel->{PictureCaption}.'' if ($hotel->{PictureURL});
		my $Placemark = 
			{
				description => ''.$hotel->{HotelCatchCopy}.'
'.$hotel->{HotelCaption}.'
'.$hotel->{}.'
じゃらんで詳細を見る
]]>', name => $hotel->{HotelName}, LookAt => { longitude => $hotel->{lng}, latitude => $hotel->{lat}, range => 0, tilt => 0, }, Point => { coordinates => $hotel->{lng}.','.$hotel->{lat}, } }; push(@{$folder->{Placemark}},$Placemark); } my $xml = $xs->XMLout($kmlRef,NoAttr=>1,RootName=>'kml'); print "Content-Type: text/kml; charset=utf-8\n"; print "Content-Disposition: attachment; filename=\"yado.kml\"\n\n"; my $head = qq(\n); $xml = $head . $xml; print $xml; }else{ my $xml = $xs->XMLout($resRef,NoAttr=>1,RootName=>'Results'); print "Content-Type: text/xml; charset=utf-8\n\n"; my $head = qq(\n); $xml = $head . $xml; print $xml; }

・descriptionの中に、Htmlのタグを埋め込んでいます。ここがちょっと面倒。この内容がGoogleMapのフキダシに出力されます。
・じゃらんAPIが返す、HotelタグをループでPlacemarkに変えてゆけばOKです。
・GoogleMapに読み込ませるには
print "Content-Type: text/kml; charset=utf-8\n";
print "Content-Disposition: attachment; filename=\"yado.kml\"\n\n";
として、Content-Dispositionでファイル名とContent-Typeで text/kmlを指定する。これをやっておかないと、GoogleMapは読み込んでくれません。
・GoogleMapが読み込むKMLのPlaceMarkの数は49件以下らしいです。50件以上は表示されません。


KMLを駆使すれば、もっと拡張は可能だとおもいます。
ひいき続きいろいろ試してみたいです。
参考
Ogawa::Memoranda
Ajaxを使ってKMLをGoogle Maps上にマップする
↑サンプルのKMLファイル助かりました
Google Earth KML ドキュメント
http://earth.google.com/kml/index.html

COMMENTS

「http://tatamilab.jp/~funami...の一部が大きすぎるため、表示できません。」とかって出てきてます.

June 22, 2006 12:26 PM by k.daiba  

k.daibaさん、早速コメントどうもありがとうございます。GoogleMapはKMLを取り込むときに50件以上あると、「一部が大きすぎるため、表示できません」ということになるようです。
じゃらんAPIのマックスが100件なので、あふれた部分が表示できていないようです。
ページングの仕組みをかなえる必要がありますね。
KMLを使って、ページングを実現するにはどうするのか、ちょっと工夫が必要そうです。

June 22, 2006 4:18 PM by フナミタカオ  

Content-typeはtext/plainでもgooglemapで読んでくれるみたいです。

June 23, 2006 5:17 PM by wakufactory  

wakufactoryさん、どうもコメントありがとうございます。
こちらでも試してみたのですが

-----------------------
print "Content-Type: text/plain; charset=utf-8\n";
print "Content-Disposition: attachment; filename=\"yado.kml\"\n\n";
my $head = qq(\n);
$xml = $head . $xml;
print $xml;
-----------------------

「... が有効な KML あるいは KMZ ファイルではないため、表示できません。」
といわれてしまいました。
いくつかの条件が組み合わさると、text/plainでもOKになるのかもしれませんが
一応、無難なところで、text/kmlにしておきます。

June 26, 2006 10:47 AM by フナミタカオ  

調査ありがとうございます。こちらでも試してみましたが


が入ってるとtext/plainでも大丈夫みたいです。cgiではなくstaticなテキストからでも表示できました。

まあ、text/kmlにするに越したことはないと思いますが。

June 26, 2006 4:28 PM by wakufactory  

うわタグ消えちゃいましたね

<kml xmlns="http://earth.google.com/kml/2.0">

です。

June 26, 2006 5:05 PM by wakufactory  

ネームスペースがあればいいのですね。なるほど、規約的には、こちらのほうが、正しそうです。
どうもありがとうございます。

June 26, 2006 5:56 PM by フナミタカオ  

#必要な情報を用いて、再構築、座標系の変換もここで行う。
#じゃらんは、測地系:日本、単位:ミリ秒(非常に目面しいですねえ...)
#Googleは  測地系:世界、単位:度

じゃらんのAPIページには緯度経度情報についてはミリ秒としかなかったですが、測地系は日本であってるんでしょうか?
それと、以前は知りませんが、現在、googlemapsは百分率で座標データを要求しますね。

July 27, 2006 9:03 PM by 匿名  

>じゃらんのAPIページには緯度経度情報についてはミリ秒としかなかったですが、測地系は日本であってるんでしょうか?
仕様を確認したわけではなく経験上ですが、じゃらんAPIの測地系は日本です。

>現在、googlemapsは百分率で座標データを要求しますね。
ごめんなさい、百分率というのがピンと来てないのですが、GoogleMaps V2の座標はGLanLon()で与えます。このメソッドの引数の緯度経度はdegree形式ですので、じゃらんAPIで貰える緯度経度から変換してあげます。
http://www.tatamilab.jp/rnd/archives/000232.html
…というコメントであってますか??

July 27, 2006 10:11 PM by 大井宏友  

POST COMMENT




(書式を変更するような一部のHTMLタグを使うことができます)

必ず利用規約に同意いただいた上で送信ください。

TRACKBACKS

ページトップへ



(C) RECRUIT MEDIA COMMUNICATIONS CO., LTD.