使ってみよう! Bing API/SDK

第28回最新機能をチェック! Bing Maps AJAX Control

はじめに

今回はJavaScriptライブラリーで提供されている地図コントロール、Bing Maps AJAX Controlの新しい機能を紹介します。前回の冒頭でも少しふれていますが、今月にアップデートがあり、新しい機能が追加されています。Bing Maps AJAX Controlの基本的な使い方や機能については連載の第1318回でも紹介していますので、そちらも併せて参照してください。

また、Bingの地図サービス自体のアップデートが前回から今回の間にあり、道路地図の見た目の改善(主に米国のみ)や、地図コントロールのUIの更新などが行われています図1図2⁠。このUIの変更は、AJAX Controlには反映されていません。

図1 従来のUI
図1 従来のUI
図2 新しいUI
図2 新しいUI

さて、Bing Maps AJAX Controlの追加された大きな機能は次の3種類です。

  • ルート検索(経路検索)および表示図3
  • 交通情報の表示図4
  • ショッピングモールなどの地図表示と情報の取得
図3 ルート検索
図3 ルート検索
図4 交通情報の表示
図4 交通情報の表示

以上の機能は追加モジュールとして参照し使用します。今回はこれらの機能を順番に紹介します。

モジュールの登録とロード

最初に、モジュールの登録とロードについて紹介します。Bing Maps AJAX Controlでは、独自のスクリプトをモジュールとして登録し、必要になった時点でロードする機能があります。今回紹介する3種類の機能もモジュールとしてロードして使います。モジュールに必要なCSSファイルも併せてロードできます。

モジュールの作成

さっそく使ってみましょう。モジュールとして登録するスクリプトを作成します。内容はなんでも構いませんが、スクリプトの最後にMicrosoft.MapsクラスのmoduleLoadedメソッドにモジュールのキー名を渡して終わります。

MyModule.js
function MyModule(map) {
    this.drawCircle = function(location, meters) {
        // (省略)
    }
}
Microsoft.Maps.moduleLoaded("GihyoSample.MyModule");

スクリプトで使用する関数や、モジュールのキー名はアプリ内で一意になるような任意の名前を設定します。

モジュールの登録

モジュールを作成した次は、アプリから利用しましょう。まず、利用するモジュールをMicrosoft.Maps.registerModuleメソッドで登録します。

Microsoft.Maps.registerModule(
    "GihyoSample.MyModule",
    "http://example.jp/MyModule.js");

registerModuleメソッドの引数は、モジュールのキー名、モジュールのURLです。

オプションとして、モジュールのロード時に併せてロードするCSSファイルがあれば次のように指定できます。

Microsoft.Maps.registerModule(
    "GihyoSample.MyModule", 
    "http://example.jp/MyModule.js",
    {styleUrls: ["http://example.jp/MyModule.css"]});

モジュールのロード

最後にモジュールのロードです。モジュールを使用するときは、Microsoft.Maps.loadModuleメソッドで登録したモジュールをロードします。

Microsoft.Maps.loadModule(
    "GihyoSample.MyModule",
    {callback: moduleLoaded});

モジュールのロードが完了すると、第2引数で指定した関数が呼ばれます。

サンプル

以上をまとめたサンプルを示します。次のコード中では、MyModule.jsをモジュールとして登録し、すぐにロードしています。モジュールのコードは省略しますが、地図上に円を描画するコードになっています。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>Module Sample</title>
        <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&amp;mkt=ja-jp"></script>
        <script type="text/javascript">
            var map = null;
    
            function ModuleLoaded()
            {
                var loc = new Microsoft.Maps.Location(35.55, 139.7862);
                map.setView({center: loc, zoom: 12});

                // モジュールの利用
                var module = new MyModule(map);
                module.drawCircle(loc, 5000);
            }
    
            function GetMap()
            {
                // 地図の表示
                var options = {credentials: "BingMapsKey"};
                map = new Microsoft.Maps.Map(document.getElementById("map"), options);
    
                // モジュールの登録とロード
                Microsoft.Maps.registerModule("GihyoSample.MyModule", "MyModule.js");
                Microsoft.Maps.loadModule("GihyoSample.MyModule", {callback: ModuleLoaded});
            }
        </script>    
    </head>
    <body onload="GetMap();">
      <div id="map" style="position:relative;width:512px;height:512px;"></div>
    </body>
</html>

実行結果は図5のようになります。

図5 モジュールの登録とロード
図5 モジュールの登録とロード

ルート検索

続いてBing Maps AJAX Controlの新しい機能をみていきましょう。ルート検索は、強力な機能が追加されています。これまでルート検索は、RESTサービスのBing Maps REST Servicesと組み合わせることで利用できていましたが、新しいAJAX ControlではREST Servicesを利用する必要がなく、UIも提供されるようになりました。

新しい機能を利用すれば、Webページ内にUIを表示する<div>タグ要素を用意するだけで、図6のようなUIを描画可能です。

図6 ルート検索のUIの描画
図6 ルート検索のUIの描画

もちろん地図コントロール内にもルート検索結果の表示や、ドラッグで出発・到着地点の変更など操作に関する部分も提供されています図7⁠。

図7 ルート検索結果の表示
図7 ルート検索結果の表示

ルート検索の種類は次の3種類が提供されています。

  • 自動車のルート探索(ドライブルート)
  • 徒歩のルート検索
  • 電車・バスなどのルート検索(乗り換え案内)

これらのルート探索は、国・地域によってサービス内容が異なります。AJAX Controlのライブラリーを参照するときにmktパラメーターで指定する言語および国・地域の指定で検索結果が変わります。

日本を指定した場合
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&mkt=ja-jp"></script>

乗り換え案内は、現在のバージョンでは日本でのみ利用できます。ドライブルートおよび徒歩のルート検索は、日本ではサポートされていません。結果は出ますが、出発・到着地点が直線の経路となるなど実際は利用できません。

コードの記述

それでは、コードでルートを検索してみましょう。

HTMLファイルは次のようになります。<body>要素内には、地図を表示する部分とルート検索結果を表示する部分を<div>要素で用意しておきます。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>Direction Sample</title>
        <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&amp;mkt=ja-jp"></script>
        <script type="text/javascript">
            var map = null;

            function GetMap()
            {
                var options = {credentials: "BingMapsKey", showBreadcrumb: true};
                map = new Microsoft.Maps.Map(document.getElementById("map"), options);
                Microsoft.Maps.loadModule("Microsoft.Maps.Directions", {callback: ModuleLoaded});
            }

            function ModuleLoaded()
            {
                // (ここにルート検索処理を追記します)
            }
        </script>
    </head>
    <body onload="GetMap();">
        <div id="map" style="position:relative;width:512px;height:512px;float:left;"></div>
        <div id="itinerary" style="position:relative;width:400px;float:left;"></div>
    </body>
</html>

GetMap関数内で、モジュールをロードしています。ルート検索モジュールのキー名は、Microsoft.Maps.Directionsです。

Microsoft.Maps.loadModule("Microsoft.Maps.Directions", {callback: ModuleLoaded});

次にモジュールをロードした後に呼ばれるModuleLoaded関数の処理を追記します。

ルート検索処理は、DirectionsManagerオブジェクトを用いて行います。DirectionsManagerオブジェクトに対して、出発・到着地点の場所の設定や、検索のオプションの指定を行い、最後にルート検索処理を実行するメソッドを呼びます。必要に応じてDirectionsManagerオブジェクトのイベント処理を行います。

function ModuleLoaded()
{
    // DirectionsManager オブジェクトの生成 (Map オブジェクトを渡す)
    var directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
    
    // 出発・到着地点を追加
    var startWaypoint = new Microsoft.Maps.Directions.Waypoint({address: "東京"});
    var endWaypoint = new Microsoft.Maps.Directions.Waypoint({address: "大阪"});
    directionsManager.addWaypoint(startWaypoint);
    directionsManager.addWaypoint(endWaypoint);
    
    // UI の描画 (<div>要素の id 値を指定)
    directionsManager.setRenderOptions({itineraryContainer: document.getElementById("itinerary")});
    
    // 検索オプションの指定
    // (routeMode は driving, transit, walking のいずれかを指定)
    // (timeType は arrival, departure, lastAvailable のいずれかを指定)
    directionsManager.setRequestOptions({
        routeMode: Microsoft.Maps.Directions.RouteMode.transit,
        transitOptions: {
            timeType: Microsoft.Maps.Directions.TimeType.departure,
            transitTime: new Date}});

    // イベント処理 (ここではルート検索時のエラーイベントを処理)
    Microsoft.Maps.Events.addHandler(directionsManager, "directionsError", function (e) {
        alert("responseCode: " + e.responseCode + "\n" + e.message);
    });

    // ルート検索 (結果を地図に表示)
    directionsManager.calculateDirections();
}

上記コードの実行結果は図8のようになります。

図8 ルート検索結果
図8 ルート検索結果

ルート検索は、さまざまなオプションの指定や機能が用意されています。今回はその内容は割愛しますが、地図上のUIの表示内容のカスタマイズから、検索件数、終電の検索など多数のオプション指定が可能です。この内容についてはまたの機会に紹介したいと思います。詳しくは、MSDN Libraryを参照してください。

ドライブルートの結果も示しておきます。次のコードでは、地域を米国に指定しています。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>Direction Sample</title>
        <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&amp;mkt=en-us"></script>
        <script type="text/javascript">
            var map = null;

            function GetMap()
            {
                var options = {credentials: "BingMapsKey", showBreadcrumb: true};
                map = new Microsoft.Maps.Map(document.getElementById("map"), options);
                Microsoft.Maps.loadModule("Microsoft.Maps.Directions", {callback: ModuleLoaded});
            }

            function ModuleLoaded()
            {
                // DirectionsManager オブジェクトの生成 (Map オブジェクトを渡す)
                var directionsManager = new Microsoft.Maps.Directions.DirectionsManager(map);
                
                // 出発・到着地点を追加
                var startWaypoint = new Microsoft.Maps.Directions.Waypoint({address: "Seattle, WA"});
                var endWaypoint = new Microsoft.Maps.Directions.Waypoint({address: "Portland, OR"});
                directionsManager.addWaypoint(startWaypoint);
                directionsManager.addWaypoint(endWaypoint);
                
                // UI の描画 (<div>要素の id 値を指定)
                directionsManager.setRenderOptions({itineraryContainer: document.getElementById("itinerary")});
                
                // ルート検索 (結果を地図に表示)
                directionsManager.calculateDirections();
            } 
        </script>
    </head>
    <body onload="GetMap();">
        <div id="map" style="position:relative;width:512px;height:512px;float:left;"></div>
        <div id="itinerary" style="position:relative;width:400px;float:left;"></div>
    </body>
</html>

実行結果は図9のようになります。ドライブや徒歩ルートの場合、地図上の出発・到着地点のフラッグをドラッグして再指定ができるようになっています。

図9 ドライブルートの検索
図9 ドライブルートの検索

交通情報の表示

次は交通情報の表示です。渋滞情報を視覚的に表示します図10⁠。ただし、サービスを提供している地域は米国のみのようです。

図10 交通情報の表示
図10 交通情報の表示

交通情報の表示機能はシンプルです。さっそくコードを書いてみましょう。モジュールのキー名は、Microsoft.Maps.Trafficです。

Microsoft.Maps.loadModule("Microsoft.Maps.Traffic", {callback: ModuleLoaded});

モジュールをロードすると、TrafficLayerクラスが使用できるようになります。交通情報の表示・非表示は、TrafficLayerクラスのshowhideメソッドで行います。

function ModuleLoaded()
{
    var trafficLayer = new Microsoft.Maps.Traffic.TrafficLayer(map);
    trafficLayer.show();
}

交通情報の表示は、Bing Maps AJAX Controlのカスタム タイル画像の表示機能を利用しています。タイルについては第16回で紹介しています。

交通情報のタイル情報は、TrafficLayerクラスのgetTileLayerメソッドでTileLayerオブジェクトを得られます。TrafficLayerクラスのメソッドはshow・hideとgetTileLayerの3個のみです。

あまり利用することはないと思いますが、TileLayerオブジェクトから、次のように交通情報のタイル画像のURL書式は次のように取得できます。

alert(trafficLayer.getTileLayer().getTileSource("mercator").getUriConstructor());

また、TileLayerオブジェクトのオプションを設定することで、交通情報の表示を半透明に変更もできます。

var tileLayer = trafficLayer.getTileLayer();
tileLayer.setOptions({opacity: 0.5});

屋内の地図の表示

次は、ショッピングモールなどの地図表示図11とその情報の取得です。このような屋内の地図表示は、Bingのサービス自体では昨年から利用できていましたが、今回のアップデートで、AJAX Controlからも利用できるようになりました。参照できる情報は、施設の名前や各フロアーにある店舗などの名前やカテゴリーや位置情報などがあります。

図11 ショッピングモールの表示
図11 ショッピングモールの表示

今のところ、屋内の地図が利用できる施設は、米国内の一部に限られているようです。また、新しく提供されたクラスを用いて独自に地図を作成することもできません。

屋内の地図情報を得るには、次の2種類の方法があります。

  • IDの指定
  • 指定した地点付近から検索

各地図にはIDが割り当てられており、そのIDを直接指定して情報を得ます。また、経緯度と半径を指定し、その範囲内にある地図情報の取得も可能です。範囲指定で得られる情報に地図のIDも含まれています。詳細な情報はIDを用いて個々に得る必要があります。

コードの記述

それではコードを書いていきましょう。モジュールのキー名は、Microsoft.Maps.VenueMapsです。

Microsoft.Maps.loadModule("Microsoft.Maps.VenueMaps", {callback: ModuleLoaded});

屋内の地図情報を得るには、VenuMapFactoryクラスを使用します。

IDの指定

まず、IDを指定して地図情報を取得する方法です。これにはVenuMapFactoryクラスのcreateメソッドを使います。

function ModuleLoaded()
{
    var factory = new Microsoft.Maps.VenueMaps.VenueMapFactory(map);
    factory.create({venueMapId: "hcl-seatacairportd",
                    success: ShowVenue,
                    error: ShowError}); 
}

createメソッドに渡すオプションは次の通りです。

名前説明
venueMapId屋内地図のID
success結果を受け取る関数を指定
errorエラー発生時の関数を指定(省略可)

結果は、オプションのsuccessに指定した関数でVenueMapオブジェクトを受け取ります。

function ShowVenue(venue)
{
    map.setView(venue.bestMapView);
    venue.show();
}

function ShowError(errorCode)
{
    alert("Error Code: " + errorCode);
}

VenueMapクラスのbestMapViewプロパティには、最適な経緯度とズームレベルが格納されています。上記コードでは、これを使用して地図を移動させています。

ここまでの内容を実行した結果は図12図13のようになります。

図12 空港の地図表示(1)
図12 空港の地図表示(1)
図13 空港の地図表示(2)
図13 空港の地図表示(2)

指定した地点付近から検索

次に経緯度と半径を指定し、その範囲内にある屋内の地図を検索する方法です。これにはVenuMapFactoryクラスのgetNearbyVenuesメソッドを使います。

function ModuleLoaded()
{
    var factory = new Microsoft.Maps.VenueMaps.VenueMapFactory(map); 
    factory.getNearbyVenues(
        {map: map, 
         location: map.getCenter(),
         radius: 20000, // 20km
         callback: DisplayNearbyVenueCount});
}

getNearbyVenuesメソッドに渡すオプションは次の通りです。

名前説明
mapMapオブジェクト
location検索する地点の経緯度
(Locationオブジェクト)
radius検索範囲の半径(メートル単位)
callback検索結果を受け取る関数を指定

オプションのradiusに、あまり大きい検索範囲を指定すると結果が得られないようです。callbackに指定した関数では、各地図情報をNearbyVenueオブジェクトの配列として受け取ります。ID指定時の結果と異なり、VenueMapオブジェクトの配列でないことに注意です。NearbyVenueクラスの持つプロパティは次の通りです。

プロパティ説明
distance指定した地点からの距離(メートル単位)
metadataIDなどの地図情報
Metadataオブジェクト)

検索結果を受け取るDisplayNearbyVenueCount関数の内容を記述します。ここでは指定した地点からの距離と、Metadataオブジェクトから施設の名前とIDを表示しています。

function DisplayNearbyVenueCount(venues)
{
    var displayResults = "";
    for (var i = 0; i < venues.length; i++) {
        displayResults += venues[i].metadata.Name + 
                          "\n\tID: " + venues[i].metadata.MapId + 
                          "\n\tDistance: " + (venues[i].distance / 1000).toFixed(1) + " km\n";
    }
    alert(displayResults);
}

実行結果は図14のようにメッセージが表示されます。

図14 指定した地点周辺の施設
図14 指定した地点周辺の施設

この屋内の地図表示に関して、ルート検索ほどではありませんが、多数の情報を参照でき大きめのモジュールとなっています。地図を構成するPolygonの情報や、各フロアーの店舗情報、表示フロアーの切り替えなどが可能です。今回はそれらの内容については割愛します。詳しくはMSDN Libraryを参照してください。

おわりに

今回はここまでです。いかがでしたでしょうか。乗り換え案内以外は、日本の対応がないため使いどころが難しいですが、日本でサービスが開始された時のために少しふれておくとよいかもしれません。また、日本に対応していないサービスは、日本版のBing自体でサービスがないため利用できない状況です。日本でもサービスが開始されるようフィードバックするのも重要かもしれませんね。

また、今回からサンプルコードをすぐ確認できるようWebページも用意しました。

第26回のガソリンスタンドアプリのサンプルも公開していますので、参照してみてください。

おすすめ記事

記事・ニュース一覧