PhoneGapにおいて各種センサーや音楽再生、電話帳などといったデバイスやプラットフォーム固有の機能を利用したい場合には、PhoneGap APIと呼ばれるJavaScriptベースのAPIを利用します。通常、これらの機能にアクセスする手段はプラットフォームごとに異なりますが、その差異はPhoneGap APIによって吸収されるため、開発者は対象とするプラットフォームの違いを意識することなくコーディングを行うことが可能です。

この記事では、このPhoneGap APIを利用してGoogle Maps上に現在地を表示する方法を紹介します。なお、サンプルアプリケーションのビルドにはAdobe PhoneGap Buildを利用しています。PhoneGap Buildの基本的な使用方法については「Dreamweaver CS6とPhonaGap Buildで作るモバイル・アプリケーション」も参考にしてください。

Google Maps APIを使うための準備

PhoneGapでGoogle Maps APIなどの外部APIを利用するためには、設定ファイルに対象となるJavaScriptライブラリを読み込むための設定を記述しなければいけません。PhoneGapは外部サイトのJavaScriptの読み込みに対してホワイトリスト方式を採用しており、明示的に許可したサイト以外からのJavaScriptの読み込みを禁止しているからです。

PhoneGap Buildを使っている場合には、この設定は「config.xml」に記載します。記述方法は、次に挙げる例のようにaccessタグを利用してorigin属性にURLを指定します。subdomain属性の値に「true」を指定しておくと、指定されたURLに関する全てのサブドメインからのJavaScriptを許可するようになります。

[サンプルコード: config.xmlへのGoogle Maps API用設定の記述例]

<!-- Google Maps API利用のための設定 --> <access origin="http://maps.google.com" subdomains="true" /> <access origin="http://googleapis.com" subdomains="true" /> <access origin="http://gstatic.com" subdomains="true" />

ここに載せたのはGoogle Mapsを使うための設定例で、「http://maps.google.com」や「http://*.googleapis.com」、「http://*.gstatic.com」からののJavaScriptの読み込みを許可しています。

Geolocation APIを利用した位置情報の取得

PhoneGapで端末の位置情報を取得するためにはGeolocation APIを使用します。具体的には、以下のようにgeolocation.getCurrentPositionメソッドを用いることで、端末の現在位置の座標(緯度・経度)や高度、移動方向や速度などを取得することができます。取得した情報は、getCurrentPositionメソッドの第一引数に指定したコールバック関数(この例の場合はonSuccess関数)に対して、Positionオブジェクトとして渡されます。今回は、コールバック関数内でこのPositionオブジェクトの情報を使ってGoogle Mapsの地図を表示したり、マーカーを配置すればいいわけです。

[サンプルコード: Geolocation APIを使った位置情報の取得]

// 位置情報の取得 function getGeolocation() { navigator.geolocation.getCurrentPosition(onSuccess, onError); } // 位置情報の取得成功時のコールバック関数 function onSuccess(position) { createMap(position); } // エラー時のコールバック関数 function onError(error) { alert('コード: ' + error.code + '\n' + 'メッセージ: ' + error.message + '\n'); }

Geolocation APIの使い方については「PhoneGap APIを使いこなせ!(Geolocation API編) 」で解説しているので、詳細はそちらを参照してください。

なお、Geolocation APIを使うためには位置情報サービスにアクセスするためのパーミッションが必要なので、config.xmlに次の設定を追加するのを忘れないようにしましょう。

[サンプルコード: Geolocation APIを利用するためのパーミッションの設定]

<!-- パーミッションの要求 --> <preference name="permissions" value="none"/> <feature name="http://api.phonegap.com/1.0/geolocation"/>

Google Maps APIを利用した地図の描画

それでは、続いてGoogle Maps APIを使った地図の描画とマーカーの配置を行ってみましょう。次に示すcreateMapメソッドは、引数に渡されたPositionオブジェクトに含まれる緯度・軽度の情報をもとにしてGoogle Mapsの地図を描画するメソッドです。

[サンプルコード: 取得した位置情報をもとにして地図を描画]

// Google Mapsで現在地の地図を描画 function createMap(position) { // 緯度経度を取得 var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); // 地図オプションの指定 var myOptions = { zoom: 14, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; // 地図を取得 var map = new google.maps.Map( document.getElementById("mapCanvas"), myOptions); // マーカーを設定 var marker = new google.maps.Marker({ position: latlng, map: map }); }

まず、Positionのcoords.latitudeプロパティとcoords.longitudeプロパティから緯度および軽度の値を取り出し、それを元にして、Google Mapsで緯度経度情報を扱うためのgoogle.maps.LatLngオブジェクトを生成します。

次に、地図を描画するためのオプションを定義します。この例では、ズームレベルを14、地図の中心を端末の現在位置(生成したLatLngオブジェクトで指定)、地図の種類をMapTypeId.ROADMAP(通常の図版の地図)として設定しています。

実際の地図の描画は、google.maps.Mapオブジェクトによって行います。google.maps.Mapのコンストラクタの第1引数に地図を描画したい要素オブジェクト、第2引数に地図オプションを渡すことで、任意の座標を中心とした地図を描画することができます。

地図上への矢印マーカーの配置は、google.maps.Markerオブジェクトを作成することで行います。Marker生成時のオプションとしては、マーカーを配置する座標をpositionプロパティに、対象となるMapオブジェクトをmapプロパティに指定します。

以上を踏まえて、端末の現在位置を地図上に表示するプログラムは次のように作ることができます。

[サンプルコード: 端末の現在位置を地図上に表示する例]

<!DOCTYPE html> <html> <head> <title>PhoneGapによる位置情報の利用</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" /> <meta charset="utf-8"> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #mapCanvas { height: 100% } </style> <script type="text/javascript" charset="utf-8" src="phonegap.js"></script> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript"> function onBodyLoad() { document.addEventListener("deviceready", onDeviceReady, false); } function onDeviceReady() { getGeolocation(); } // 位置情報の取得 function getGeolocation() { navigator.geolocation.getCurrentPosition(onSuccess, onError); } // 位置情報の取得成功時のコールバック関数 function onSuccess(position) { createMap(position); } // エラー時のコールバック関数 function onError(error) { alert('コード: ' + error.code + '\n' + 'メッセージ: ' + error.message + '\n'); } // Google Mapsで現在地の地図を描画 function createMap(position) { // 緯度経度を取得 var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); // 地図オプションの指定 var myOptions = { zoom: 14, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; // 地図を取得 var map = new google.maps.Map( document.getElementById("mapCanvas"), myOptions); // マーカーを設定 var marker = new google.maps.Marker({ position: latlng, map: map }); } </script> </head> <body onload="onBodyLoad()"> <h1>現在地を地図上に表示</h1> <div id="mapCanvas" style="width:100%; height:100%"></div> </body> </html>

図1は、iPhone上でこのプログラムを実行してみた例です。地図上のマーカーが現在地を示していることが確認できます。

端末の移動を地図上に反映させる

上記の例は、プログラムを実行した瞬間の端末の現在位置を地図に描画するだけのものでした。Geolocation APIでは、位置情報の変化を監視して、最新の現在位置を逐次取得することもできるので、この機能を使って端末の移動を地図に反映させてみましょう。

位置情報の監視は、geolocation.watchPositionメソッドで開始し、geolocation.clearWatchメソッドで終了します。監視を行なっている間は、位置情報に変化が生じる(端末が移動する)と、watchPositionメソッドに渡したコールバック関数が呼び出され、最新の位置情報を持ったPositionオブジェクトが渡されます。詳細は「PhoneGap APIを使いこなせ!(Geolocation API編) 」を参照してください。

今回は、この逐次渡される最新のPositionオブジェクトを使って地図とマーカーの座標を更新していけばいいわけです。以下にそのプログラムの例を示します。

[サンプルコード: 位置情報の変化を地図の表示に反映させる例]

<!DOCTYPE html> <html> <head> <title>PhoneGapによる位置情報の利用</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;" /> <meta charset="utf-8"> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #mapCanvas { height: 100% } </style> <script type="text/javascript" charset="utf-8" src="phonegap.js"></script> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript"> var map = null; // 地図オブジェクト var marker = null; // マーカーオブジェクト var watchId = null; // 監視対象の地図のID function onBodyLoad() { document.addEventListener("deviceready", onDeviceReady, false); } function onDeviceReady() { getGeolocation(); } // 位置情報の取得 function getGeolocation() { navigator.geolocation.getCurrentPosition(onSuccess, onError); } // 位置情報の取得成功時のコールバック関数 function onSuccess(position) { createMap(position); } // エラー時のコールバック関数 function onError(error) { alert('コード: ' + error.code + '\n' + 'メッセージ: ' + error.message + '\n'); } // Google Mapsで現在地の地図を描画 function createMap(position) { // 緯度経度を取得 var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); // 地図オプションの指定 var myOptions = { zoom: 14, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP }; // 地図を取得 map = new google.maps.Map( document.getElementById("mapCanvas"), myOptions); // マーカーを設定 marker = new google.maps.Marker({ position: latlng, map: map }); } // 監視の開始 function watchStart() { var options = { enableHighAccuracy: true }; watchId = navigator.geolocation.watchPosition( onWatchSuccess, onError, options); document.getElementById("stopButton").disabled = null; document.getElementById("startButton").disabled = "disabled"; } // 監視の終了 function watchStop() { navigator.geolocation.clearWatch(watchId); document.getElementById("startButton").disabled = null; document.getElementById("stopButton").disabled = "disabled"; } // 位置情報が変更された際に呼び出されるコールバック関数 function onWatchSuccess(position) { // 地図とマーカーの座標を更新 var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); map.setCenter(latlng); marker.setPosition(latlng); } </script> </head> <body onload="onBodyLoad()"> <h1>現在地を地図上に表示</h1> <input type="submit" id="startButton" value="監視スタート" onClick="watchStart()"/> <input type="submit" id="stopButton" value="監視ストップ" onClick="watchStop()" disabled="disabled"/> <div id="mapCanvas" style="width:100%; height:100%"></div> </body> </html>

地図の中心座標の変更は、MapオブジェクトのsetCenter()メソッドに新しい座標のLatLngオブジェクトを渡すことで行います。またマーカーの座標は、MakerオオブジェクトのsetPosition()メソッドにLatLngオブジェクトを渡すことで変更できます。

図2および図3はこのプログラムをiPhoneにインストールして実行した例です。[監視スタート]ボタンを押すと位置情報の監視を開始し、端末の移動が地図上のマーカーの位置に反映されることが確認できます。