Dreamweaver/HTML5でiPhoneアプリ開発(その7: 住所を表示する)

Filed in Adobe, iPhone, Web関係

その6では、現在地から目的地までのルート検索を行うアプリを作成しました。今回は、それを拡張して、地図の中心の住所を画面に表示する様にしてみます。

住所を取得するためには、緯度・経度⇔住所の変換処理が必要です。住所から緯度・経度を求める機能を、「ジオコーディング」と呼びます。逆に、緯度・経度から住所を求める機能を、「リバースジオコーディング(逆ジオコーディング)」と呼びます。

今回は住所を求めたいので、リバースジオコーディングを使用する事になるのですが、これを行うためのAPIがYOLPに用意されているので、それを使用します。

APIの詳細はYOLPのリファレンスでも見て頂くとして、私が作成したソースを載せておきます。コードの量が増えてきたので、今回からはhtmlとjavascriptでファイルを分ける事にしました。

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">

<link href="jquery-mobile/jquery.mobile-1.0.1.min.css" rel="stylesheet" type="text/css"/>
<script src="jquery-mobile/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="jquery-mobile/jquery.mobile-1.0.1.min.js" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8" src="http://js.api.olp.yahooapis.jp/OpenLocalPlatform/V1/jsapi?appid=【アプリケーションID】"></script>
<script src="maptest.js" type="text/javascript"></script>
</head>

<body>
<div align="center">
	<div data-role="header" id="address" style="width:320px; height:24px;"></div>
	<div id="map" style="width:320px; height:380px;"></div>
	<div data-role="footer" style="width:320px;height:56px">
		<div data-role="controlgroup" data-type="horizontal">
			<div data-role="button" data-inline="true" data-icon="home" onClick="returnHome()">現在地</div>
			<div data-role="button" data-inline="true" data-icon="search" onClick="routeSearchStart()">検索</div>
			<div data-role="button" data-inline="true" data-icon="delete" onClick="routeSearchEnd()">中止</div>
		</div>
	</div>
</div>
</body>

</html>

maptest.js

$(document).ready(function() {
	// 初期化
	ymap = new Y.Map("map");
	draw = false;
	follow = true;
	watchID = 0;

	// イベントリスナ
	ymap.__eventlistener__ = ymap.bind('drag', watchStop);
	ymap.__eventlistener__ = ymap.bind('click', move);
	ymap.__eventlistener__ = ymap.bind('moveend', getAddress);

	// 現在地のマーカーで使用するアイコン
	icon = new Y.Icon('http://i.yimg.jp/images/map/yy/images/icon/yy_aicon_01_32pix.gif');

	// ルート検索結果を描画するレイヤ
	route = new Y.RouteSearchLayer();
	ymap.addControl(new Y.CenterMarkControl)

	// 追従開始
	watchStart();
});

// 位置情報の取得と地図の描画を行う
function watchStart() {
	// 位置情報を取得する
	watchID = navigator.geolocation.watchPosition(
		// 位置情報の取得に成功したら、現在地の周辺地図を描画する
		function (position) {
			// 現在地の緯度・経度を取得
			var lat = position.coords.latitude;
			var lng = position.coords.longitude;
			cur = new Y.LatLng(lat, lng);

			// 1回だけ地図を描画する
			if(!draw) {
				ymap.drawMap(cur, 17, Y.LayerSetId.NORMAL);
				draw = true;
			}

			// 現在地にマーカーを描画する
			ymap.clearFeatures();
			var marker = new Y.Marker(cur, {icon: icon});
			ymap.addFeature(marker);

			// 現在地が中心にくる様にマップを移動する
			if(follow) {
				ymap.panTo(cur);
			}
		},
		// 位置情報の取得に失敗したら、エラーダイアログを出す
		function (error) {
			var message = "";

			switch(error.code)
			{
				case error.PERMISSION_DENIED:
					message = "位置情報が利用できません";
					break;
				case error.POSITION_UNAVAILABLE:
					message = "位置情報の取得に失敗しました";
					break;
				case error.TIMEOUT:
					message = "タイムアウトしました";
					break;
			}
			window.alert(message);
		}
	);
}

// 手動で地図をスクロールさせたら、一旦追従をやめる
function watchStop() {
	watchID = 0;
	follow = false;
}

// 地図をタップしたら、その地点を中心に設定する
function move(position) {
	ymap.panTo(position);
	watchID = 0;
	follow = false;
}

// 地図を現在地周辺に戻す
// 追従停止中であれば、追従を再開する
function returnHome() {
	ymap.panTo(cur);
	watchStart();
	follow = true;
}

// ルート検索を行い、結果を地図上に表示する
function routeSearchStart() {
	var latlngs = [cur, ymap.getCenter()];
	route.execute(latlngs);
	ymap.addLayer(route);
}

// ルート検索結果を非表示にする
function routeSearchEnd() {
	ymap.removeLayer(route);
}

// 現在地の住所を取得する
function getAddress() {
	var latlng = ymap.getCenter();
	var lat = latlng.lat();
	var lng = latlng.lng();
	jQuery.ajax({
			url:"http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder?lat=" + lat + "&lon=" + lng + "&appid=【アプリケーションID】",
			type:"get",
			success:function(data){
			address.innerHTML = data.getElementsByTagName("Address")[0].textContent;
		}
	});
}

上記をシミュレータで実行すると、図1の様になります。地図の上部にある黒い帯の上に、地図の中心部分の住所が表示されます。

実行結果

図1: 実行結果

この例では、「カリフォルニア州」という、余りにも抽象的な住所しか取得出来ていません。調べてみたところ、海外では以下の様な制限があるらしく、正直日本国内以外は使い物になりそうにありません。

※日本以外は、国情報のみ出力します。ただし、アメリカ・カナダ・オーストラリア・ブラジルは州まで、中国は省まで出力します。

また、日本国内であっても、どれほど詳細に住所を取得出来るかは、測定する地点によってまちまちの様です(ある地点では番地まで取得出来るのに、ある地点では町名までしか取得出来ないなど)。

そのため、どうしても詳細な住所を取得しなければならない様な場合には使えなさそうです。利用の際は、「ないよりはマシ」くらいに思っておいた方が良いかもしれません。(その8に続く)

 
Click to view/hide