はじめに
2月10日、Internet Explorer 9 製品候補版 が公開されました。この製品候補版では位置情報を取得するGeolocation API の利用が可能になっています。今回はGeolocation APIとBing Maps AJAX Controlを連携してみましょう。また、Bing Maps AJAX Controlについては今回で一旦終了です。
Geolocation API は、Internet Explorer 9以外の主要なWebブラウザーでも利用できます。Geolocation APIや位置情報に関する内容は、gihyo.jp内に「位置情報サービスのはじめ方 」という連載もありますので、こちらも参考になるかと思います。
余談ですが、Wi-FiのアクセスポイントやIPアドレスから位置情報を取得するサービスは、BingブランドではなくMSN Virtual Earthという名前で地図サービスが提供されていた2005年から提供されていました。一時期まではそのサービスを、Bing Mapsの前のバージョンにあたるLive Searchs Mapsで利用できていましたが、現在では終了しています。
Geolocation API
Geolocation APIは、W3Cで勧告候補の仕様で、このAPIを利用するとスクリプトから位置情報が取得できます(Geolocation API Specification ) 。Geolocation APIで定義されているGeolocationオブジェクトには次のメソッドがあります。
getCurrentPosition:現在の位置情報を取得
watchPosition:定期的に位置情報を取得
clearWatch:定期的な位置情報の取得を終了
この中のgetCurrentPosition メソッドを使ってみましょう。JavaScriptで現在位置を取得する場合は、次のように記述します。
window . navigator . geolocation . getCurrentPosition ( successCallback , errorCallback );
function successCallback ( position ) {
alert ( "Location: " + position . coords . latitude + ", " + position . coords . longitude );
}
function errorCallback ( error ) {
alert ( "Error code: " + error . code );
}
取得に成功した場合、getCurrentPositionメソッドの第1引数に指定した関数にPosition オブジェクトが渡されます。経緯度は、Positionオブジェクトのcoords プロパティ(Coordinates オブジェクト)からさらに、latitude とlongitude プロパティから得ます。ここでは説明しませんが、このような呼出し以外にも、キャッシュされた位置情報の許容時間の指定なども可能です。
現在位置の表示
それでは、Bing Maps AJAX Controlで現在位置を表示してみましょう。まず、地図を表示するコードはこれまでと同じように次のようになります。jQueryのライブラリーの参照など、後ほど使用するためコードも一部含まれています。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />
<title> Bing Maps Sample </title>
<script src = "http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.4.4.js" type = "text/javascript" ></script>
<script type = "text/javascript" src = "https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&ssl=1" ></script>
<script type = "text/javascript" >
<!--
var map = null ;
var bingMapsKey = " BingMapsKey " ;
var position = null ;
function GetMap () {
map = new Microsoft . Maps . Map ( document . getElementById ( "map" ), { credentials : bingMapsKey });
}
</script>
</head>
<body onload = " GetMap (); " >
<div id = "map" style = " position : relative ; width : 512px ; height : 512px " ></div>
<div id = "share" ></div>
</body>
</html>
位置情報の取得に成功した場合、その地点にプッシュピンを追加するコードを追記しましょう。まず、<body>要素に現在位置の取得処理を呼び出すボタンを追加します。
<input type = "button" value = "Locate Me!" onclick = " locateMe (); " />
続いてJavaScriptのコードです。次のコードは現在位置の取得の要求部分です。
function locateMe () {
if ( window . navigator != null &&
window . navigator . geolocation != null ) {
window . navigator . geolocation . getCurrentPosition ( successCallback , errorCallback );
} else {
alert ( "Geolocation not supported" );
}
}
現在位置の取得に成功した場合は、次のように記述します。Geolocation APIとの連携部分は、PositionオブジェクトからBing Maps AJAX ControlのLocationオブジェクトに変換するだけですので、特に難しいところはありませんね。
function successCallback ( p )
{
position = p ;
var loc = new Microsoft . Maps . Location ( p . coords . latitude , p . coords . longitude );
map . entities . clear ();
var pin = new Microsoft . Maps . Pushpin ( loc );
map . entities . push ( pin );
map . setView ({ center : loc , zoom : 12 });
}
最後に、取得に失敗した場合です。関数に渡されるPositionError オブジェクトには次の3種類のエラー内容が定義されています。
function errorCallback ( error ) {
var message = "" ;
switch ( error . code ) {
case error . PERMISSION_DENIED :
message = "Permission denied" ;
break ;
case error . POSITION_UNAVAILABLE :
message = "Position unavailable" ;
break ;
case error . TIMEOUT :
message = "timeout" ;
break ;
}
alert ( message );
}
以上で、現在位置を取得して地図上にプッシュピンを表示するところまでできました。実際に実行して確認してみてください。Internet Explorer 9では、図1 のように通知バーが表示されます。許可すると位置情報が利用できる場合、その地点にプッシュピンが表示されます。
図1 位置情報取得の要求
精度の表示
現在位置の表示は、実際とはかなり異なった結果だったかもしれません。これはIPアドレスなどからの推測のためしかたありません。Geolocation APIでは位置情報の精度も取得できます。この情報も地図上に表示するよう変更してみましょう。
Coordinatesオブジェクトのaccuracy プロパティを参照すると、経緯度の精度がメートル単位で取得できます。この値を半径、取得した経緯度を中心とした円を地図に描きます。領域を表すにはBing Maps AJAX ControlのPolygon クラスを使用します。
Polygonオブジェクトを作成するには円周上の経緯度を求める必要があります。中心の経緯度とメートル単位の半径から円周上の経緯度を求める計算は複雑なため、Movable Type Ltd で公開されているコードを使用します。このスクリプトを参照し、destVincenty関数が呼び出せる状態にしてください。
経度・緯度・精度からPolygonを地図上に表示するコードは次のようになります。
function displayPolygon ( lat , lon , meters ){
var verticies = new Array ();
for ( var d = 0 ; d <= 360 ; d += 3 ) {
var result = destVincenty ( lat , lon , d , meters );
var loc = new Microsoft . Maps . Location ( result . lat , result . lon );
verticies . push ( loc );
}
var color1 = new Microsoft . Maps . Color ( 25 , 0 , 163 , 239 );
var color2 = new Microsoft . Maps . Color ( 150 , 0 , 163 , 239 );
var polygon = new Microsoft . Maps . Polygon ( verticies , { fillColor : color1 , strokeColor : color2 });
map . entities . push ( polygon );
}
上記のdisplayPolygon関数の呼び出しを、successCallback関数内のプッシュピン表示前に追加しましょう。
displayPolygon ( p . coords . latitude , p . coords . longitude , p . coords . accuracy );
実行結果は図2 のようになります。
図2 精度の表示
実はここまでの内容は、Internet Explorer 9 Platform Previewや、HTML5などのデモを公開しているWebサイト、Internet Explorer Test Drive にあるGeolocation デモ(図3 )とほぼ同じものを作成していました。
図3 Geolocation デモ
作成したアプリケーションは、Geolocation APIが実装されているGoogle ChromeなどのWebブラウザーでも動作します(図4 ) 。Webブラウザー内部で位置取得のために使用しているサービスが、Internet ExplorerとGoogle Chrome・Firefox・Operaとでは異なるため、結果も異なっています。
図4 Google Chromeでの実行結果
ソーシャルネットワークサービスとの連携
現在位置を取得するユースケースとして、ソーシャルネットワーク アプリケーションでユーザーの更新情報に利用するといったことがあるかと思います。次はBing Maps AJAX Controlとは直接関係ありませんが、Bing Maps REST Servicesなどを利用して、ソーシャルネットワーク機能を追加します。
Messenger Connect Sharing badge
今回利用するのは、Messenger Connect Sharing badge です。Sharing badgeを利用すると、Webサイトや写真などをLive MessengerなどのWindows Liveサービス上の友人や知り合いと共有できます。
Sharing badgeは図5 のようなWebサイトに貼り付けるボタンです。ユーザーがクリックすると、指定されたWebサイトなどを共有できます(図6 ) 。
図5 Messenger Connect Sharing badge
図6 Webサイトの共有
共有した内容は、live.comの更新情報や、Live Messengerの表示メッセージと更新情報(図7 ) 、Messenger Companionで使用されます。また、ユーザーがFacebookなどのサービスとWindows Liveサービスを接続していた場合、接続先のサービスにも反映されます(図8 ) 。
図7 Live Messenger 表示メッセージと更新情報
図8 Facebookとの連携
Sharing badgeの作成
このSharing badgeを利用して、現在位置を共有できるようにしましょう。リンク先を次のようなURLにするだけで、簡単に共有できます。このほかにもパラメーターを指定できますが、ここでは説明しません。
http://profile.live.com/badge/?
url =共有するWebサイトのURL &
title =タイトル &
screenshot =サムネイルのURL
今回は、WebサイトのURLには、Bing Mapsで現在地を表示できるよう指定します。また、Bing Maps REST ServicesのLocation API で現在地の住所を取得してタイトルに使用し、Imagery API で地図画像を作成してサムネイルに指定します。Location APIとImagery APIについては、第9回 と第10回 に紹介していてますので、併せて参照してください。
Location APIによる逆ジオコーディング部分は次のようになります。
function share () {
map . getCredentials ( createGeocodeRequest );
}
function createGeocodeRequest ( credentials ) {
if ( credentials === null ) {
alert ( "Credentials is null." );
return ;
}
$ . ajax ({
type : "GET" ,
url : "https://dev.virtualearth.net/REST/v1/Locations/" +
position . coords . latitude + "," +
position . coords . longitude ,
dataType : "jsonp" ,
data : {
key : credentials ,
c : "ja-JP" ,
o : "json"
},
jsonp : "jsonp" ,
success : function ( data , dataType ) {
geocodeCallback ( data );
}
});
}
function geocodeCallback ( response ) {
if ( response && response . errorDetails ) {
var text = "" ;
$ . each ( response . errorDetails , function () {
text += this + "\n" ;
});
alert ( text );
return false ;
}
if ( response &&
response . resourceSets &&
response . resourceSets . length > 0 &&
response . resourceSets [ 0 ]. resources &&
response . resourceSets [ 0 ]. resources . length > 0 ) {
var addr = response . resourceSets [ 0 ]. resources [ 0 ]. name ;
createBadge ( position . coords . latitude , position . coords . longitude , addr );
} else {
alert ( "No result." );
}
}
Sharing badgeをWebページに追加する部分は次のようになります。この中で、Imagery APIを利用した地図画像のURLも作成しています。
function createBadge ( lat , lon , addr ) {
var url = "http://profile.live.com/badge/?" +
"url=" + encodeURIComponent ( "http://bing.jp/map/?q=" + lat + "," + lon ) +
"&title=" + encodeURIComponent ( "現在地 " + addr ) +
"&screenshot=" + encodeURIComponent ( "http://dev.virtualearth.net/REST/v1/Imagery/Map/Road/" + lat + "," + lon + "/12?&pp=" + lat + "," + lon + ";35&ms=128,128&key=" + bingMapsKey );
var badge = '<a title="Share with Messenger"><img style="border-style:none; vertical-align:middle; margin-right:4px" src="http://js.live.net/static/img/SharingBadge22x22Orange.png" alt="Share with Messenger" />共有</a>' ;
$ ( "#share" ). html ( badge ). find ( "a" ). attr ( "href" , url );
}
最後に、作成したshare関数をsuccessCallback関数内で呼び出すようにすれば完成です。現在位置を取得すると、WebページにSharing badgeが現れます。ボタンをクリックすると図9 のような画面になります。
図9 現在地の共有
おわりに
今回の内容は以上です。Bing Maps AJAX Controlとその他のWebサービスを連携して簡単なアプリケーションを作成してみました。いかがでしたでしょうか。今回でBing Maps AJAX Controlの紹介は一区切りです。
Bing Maps AJAX Controlはこれまでの連載からもわかるようにシンプルなライブラリーです。その機能については前回までの内容で概ね紹介していますが、各クラスの持つすべてのプロパティやメソッドの内容などについてはMSDN Library の参照をお願いします。
Bing Maps AJAX Controlを実際に使用してみると、Bird’s eye(概観図)やスムーズな動作など、注目する点があるのではないでしょうか。それらの点を活かして、ほかのライブラリーやWebサービスともうまく組み合わせて利用してみるとよいのではないかと思います。
また、この連載中にiPhoneだけでなくAndroid 2.x のブラウザーにも対応されています。モバイルアプリケーションにもぜひ活用してみてください。