使ってみよう! Bing API/SDK

第1回Hello, Bing Map App!─⁠─Silverlightで作るBing Mapsアプリケーション(1)

はじめに

みなさんはBing図1を利用していますか? BingとはMicrosoftの検索サービスです。2009年に従来の検索サービス、Live Searchからブランド名を変更し、新たなサービスとしてスタートしました。その後も、さまざまな新機能が追加されている注目のオンラインサービスです[1]⁠。まだ利用したことのない方は、ひとつの選択肢としてぜひ活用してみてください。

そしてBingには、開発者向けにBingサービスを利用できるAPIやSDKが提供されています。この連載では、Bingに関するAPI・SDKを紹介します。一緒にBingを利用したアプリケーションを開発してみましょう! 開発ではなくBing自体の使い方については、必要な部分しか紹介しません。詳しく知りたい方は、BingのホームからリンクされているBingのツアーなどを参照してください。

図1 Bing
図1 Bing

さて、2010年6月7日にMicrosoftの開発者向けカンファレンスTech・Ed 2010 North Americaにて、Bingの地図検索サービス Bing Mapsのアプリケーション(Bing Map App)が開発できる、Bing Map App SDKリリースの発表がありました。このSDKリリース以外には、Silverlight 4対応やBing Mapsの機能追加、REST APIの提供なども発表されています。第1回目は、Bing Map App SDKをさっそく利用してアプリケーションを作ってみましょう。Bing Map Appは、Silverlightを使用して作ります。

Bing Map App

そもそもBing Map App(以下Map App)とはなんでしょうか。まず、Bing Mapsは、技術的に分類すると、JavaScriptベースのものと、地図の描画やUIなどにSilverlightを使用した ふたつのモードがあります。JavaScriptベースはLive Searchブランド時代から続いているものであり、SilverlightのBing Mapsは2009年に新しくリリースされたものです。

日本のBing Mapsは、今のところ旧式のJavaScriptベースとなっています。米国のBing Mapsでは新しいSilverlightを使用したものが正式サービスとして提供されています(JavaScriptベースに戻すこともできます⁠⁠。

SilverlightのBing Mapsでは、Deep ZoomなどSilverlightの機能を使用し、JavaScriptベースでは体験できないUIを実現しています。また車載視点で地図上を移動できるStreetside view(Googleマップのストリートビューと似たもの)などSilverlightのBing Mapsにしかない機能もいくつかあります。Map Appは、その中の機能のひとつです。というわけで、連載ではSilverlightのBing Mapsを使用していきます。

Map Appは、Bing Mapsの左側のパネル下にある「MAP APPS」ボタンをクリックし、Bing Map App Gallery図2から起動します。Map Appには、Flickrの写真を地図上に合成して表示するStreetside Photos図3⁠、Twitterのツイートをリアルタイムに地図上に表示するTwitter Maps図4など見ているだけで楽しいものから、交通情報やホテル情報の表示など実用性のあるものまでが多数登録されています。

これまでは、Map Appは公式のアプリケーションしかありませんでしたが、Bing Map App SDKにより誰でも開発でき、公開が可能になります。

ただし、登録時に審査があります。Map Appである必要がない場合は、以前から提供されているBing Maps Silverlight Control SDKなどを利用する方法もあります。

図2 Bing Map App Gallery
図2 Bing Map App Gallery
図3 Streedside Photos
図3 Streedside Photos
図4 Twitter Maps
図4 Twitter Maps

開発環境

Bing Map Appの開発には次の環境が必要です。

無償のVisual Web Developer Express 2010 ExpressとSilverlight 4 Toolsの組み合わせでも開発できます。

Bing Map App SDKは、Microsoft Connectからダウンロードし、インストールしましょう。Windows Live IDアカウントによるサインインが必要です。

インストーラーを実行すると図5⁠、Bing Map Appの開発に必要なライブラリーとドキュメントおよびサンプルプログラムがインストールされます。また、Visual Studioの場合、C#のBing Map Appテンプレートが追加されています。

図5 Bing Map App SDK セットアップ
図5 Bing Map App SDK セットアップ

プラグイン

最初にMap Appの構成について説明します。Map Appはbing.comのSilverlightアプリケーションのプラグインのひとつとして動作します。Map App開発者は、SDKのライブラリーに含まれている特定のクラスを継承したクラスを作成します。これがプラグインとなり、必要な時点でロードされ実行されます。プラグインの以下のような構成になっています。

レイヤー(Layer)

プラグインは、ひとつ以上のレイヤーを持っています。何か情報を表示するためにはレイヤーを作成する必要があり、レイヤー単位で情報を管理します。レイヤーごとに複数のエンティティやオーバーレイ、ひとつのパネルを含んでいます。

エンティティ(Entity)

エンティティとは、プッシュピン図6などの特定の地点を示すポイントや、ルートや領域を表す線や多角形の地図上に表示するアイテムです。

図6 プッシュピン
図6 プッシュピン

オーバーレイ(Overlay)

オーバーレイは、地図上に重ねて表示するボタンなどのUIです。エンティティと異なり地図の移動と一緒に動きません。

パネル(Panel、Expanded Panel)

パネルは、Bing Mapsの左側に表示されている検索結果などを表示するためのUIです。パネルは折りたたみ可能で、またページ全体へ展開もできます。通常表示のときのパネル(Panel)と展開したときのパネル(Expanded Panel)は、プラグイン内では区別して扱います。

今回 作成するMap Appはひとつのレイヤーとプッシュピンを持っています。

プロジェクトの作成

それでは、Map Appを作っていきましょう。プログラミング言語は、C#を使用します。Visual Studioで新規にSilverlight Class Libraryプロジェクトを作成します図7⁠。ここではプロジェクト名をHelloWorldBingMapAppとしました。OKボタンクリック後に表示されるSilverlight のバージョン選択は、Silverlight 4を選択します。

図7 Silverlight Class Libraryプロジェクトの作成
図7 Silverlight Class Libraryプロジェクトの作成

続いて必要なライブラリーを参照します。プロジェクト メニューの「参照の追加」を選択します。Bing Map App SDKをインストールした場所(通常であれば、C:\Program Files\Microsoft SDKs\Bing Map App SDK\libraries)に、下記のDLLファイルがありますので、すべて追加します図8⁠。

  • Microsoft.Maps.Core.dll
  • Microsoft.Maps.Extended.dll
  • Microsoft.Maps.MapControl.Types.dll
  • Microsoft.Maps.Plugins.dll
図8 参照の追加
図8 参照の追加

プラグイン クラスの作成

プラグインは、Microsoft.Maps.Plugins.Pluginクラスを継承したクラスとして作成します。ここではHelloWorldPluginというクラス名にします。Class1.cs ファイルををHelloWorldPlugin.csに名前を変更し、クラス名もHelloWorldPluginクラスに変更します。

usingディレクティブを記述し必要な型をインポートします。

using Microsoft.Maps.Core;
using Microsoft.Maps.Plugins;

そして、Pluginクラスを継承します。

public class HelloWorldPlugin : Plugin
{
}

Pluginクラスには、プラグインの初期化処理を行うInitializeメソッドとMap App GalleryからMap Appを起動したときに呼ばれるActivateメソッドが定義されています。このふたつをオーバーライドします。

public override void Initialize()
{
    base.Initialize();
}

public override void Activate(System.Collections.Generic.IDictionary<string, string> activationParameters)
{
    base.Activate(activationParameters);
}

以上で何もしないプラグインができました。ここに各種機能を追加していきます。

ContractのImportとExport

さて、プラグインからどのように地図を操作したり、情報を表示・取得したりすればよいのでしょうか。Bing Mapsから提供される機能を使用するには、Contractという特定の機能を参照するための仕組みを用います。プラグインクラスにプロパティを定義し、使用したい機能を取り込み(Import)ます。場合によってはプラグインからBing Mapsに対して機能を提供する(Export)こともできます。たとえば地図上にプッシュピンを追加した場合、PushupinFactoryContractクラス型のプロパティを定義し、機能を取得したいことを示す属性を付けます。

[ImportSingle("Microsoft/PushpinFactoryContract", ImportLoadPolicy.Synchronous)]
public PushpinFactoryContract PushpinFactoryContract { get; set; }

PushpinFactoryContractは地図上にプッシュピンを追加する機能を提供します。上記のように記述することで、Initializeメソッドが呼ばれる前にPushpinFactoryContactプロパティが参照可能になっています。このようにプラグインに対し機能を提供する方法は、.NET Framework 4のアプリケーションの拡張機能の仕組みを提供するManaged Extensibility Framework(MEF)とよく似ています。ただし、SilverlightでもMEFを使用できますが、それとは異なっています。

レイヤーの追加

Map Appで何かしらの情報を表示するためには、プラグインにレイヤーを追加する必要があります。レイヤーはLayerクラスで表します。そして、レイヤーを追加や表示などの管理を行うContract、LayerManagerContractを参照します。

Layerクラスは、abstractクラスのため継承したクラスを作成します。ここではMainLayer.csという名前のクラスファイルを新しくプロジェクトに追加し、下記のようにコードを記述します。

namespace HelloWorldBingMapApp
{
    using Microsoft.Maps.Core;
    using Microsoft.Maps.Plugins;

    public class MainLayer : Layer
    {
        public MainLayer(PluginToken pluginToken) : base(pluginToken)
        {
        }
    }
}

今回はレイヤーで何も処理しないため、これだけです。

HelloWorldPluginクラスに戻り、Activateメソッドを変更します。ActivateメソッドはMap Appが起動されたときなどMap Appのレイヤーを表示すべきタイミングに呼ばれます。

このメソッド内でプラグインに既にレイヤーが追加されていればレイヤーを表示、そうでなければレイヤーをプラグインに追加するように処理を記述しましょう。コードは次のようになります。

private MainLayer mainLayer;

[ImportSingle("Microsoft/LayerManagerContract", ImportLoadPolicy.Synchronous)]
public LayerManagerContract LayerManagerContract { get; set; }

public override void Activate(System.Collections.Generic.IDictionary<string, string> activationParameters)
{
    if (LayerManagerContract.ContainsLayer(this.mainLayer))
    {
        LayerManagerContract.BringToFront(this.mainLayer);
    }
    else
    {
        LayerManagerContract.AddLayer(this.mainLayer);
    }
}

上記コードでは、MainLayerクラスをprivateフィールドとして定義、ContractのImportもしています。フィールドのmainLayerのインスタンス化は、次のInitializeメソッド内で処理することにしましょう。

プッシュピンの追加

続いてレイヤーの中にプッシュピンを追加してみましょう。今回作成するMap Appではユーザーが表示している地図上にひとつのプッシュピンを表示します。また、プッシュピンをクリックしたときにメッセージを表示するようにします。

表示されている地図の操作、プッシュピンの作成、プッシュピンクリック時に表示するポップアップ、それぞれContractがあります。各プロパティを宣言します。

[ImportSingle("Microsoft/MapContract", ImportLoadPolicy.Synchronous)]
public MapContract DefaultMap { get; set; }

[ImportSingle("Microsoft/PushpinFactoryContract", ImportLoadPolicy.Synchronous)]
public PushpinFactoryContract PushpinFactoryContract { get; set; }

[ImportSingle("Microsoft/PopupContract", ImportLoadPolicy.Synchronous)]
public PopupContract PopupContract { get; set; }

プッシュピンを作成するには、まずPushpinFactoryContractCreateStandardPushpinメソッドを使います。メソッドの引数に経緯度を渡すと、その地点を指し示すプッシュピンが戻り値になります。経緯度は表示している地図の中心を今回は指定します。ここでMapContractCenterプロパティを使います。そして、レイヤーにプッシュピン エンティティを追加します。

Initializeメソッドの内容を変更したコードを示します。先ほどのレイヤーのインスタンス生成もここで行います。

public override void Initialize()
{
    base.Initialize();
    this.mainLayer = new MainLayer(this.Token);

    var pin = PushpinFactoryContract.CreateStandardPushpin(this.DefaultMap.Center);
    var entity = new Entity(pin);

    this.mainLayer.Entities.Add(entity);
}

CreateStandardPushpinメソッドによる戻り値はレイヤーに直接追加できる型でありません。そのためEntityオブジェクトを生成しPrimitiveプロパティに値を設定しています。エンティティは地図上に表示するアイテムで、Primitiveはエンティティの地理的な位置や形状を定義したものです。

最後にプッシュピンクリック時の処理です。PopupContractRegisterメソッドを用いて次のように記述できます。Initializeメソッド内のレイヤーに追加する前に追記します。

PopupContract.Register(
    entity,
    (PopupStateChangeContext context) =>
    {
        context.Title = "こんにちは!";
        if (context.State == PopupState.Normal)
        {
            context.Content = pin.Location.ToString();
        }
    });

ポップアップを表示するエンティティとポップアップの状態が変更されたときの処理を指定しています。

Map Appのテスト

以上でコードの記述は終了です。きちんとビルドできましたか? ここまでのHelloWorldPlugin.csの内容は次の通りです。

namespace HelloWorldBingMapApp
{
    using Microsoft.Maps.Core;
    using Microsoft.Maps.Plugins;
 
    public class HelloWorldPlugin : Plugin
    {
        private Layer mainLayer;
 
        [ImportSingle("Microsoft/MapContract", ImportLoadPolicy.Synchronous)]
        public MapContract DefaultMap { get; set; }
 
        [ImportSingle("Microsoft/LayerManagerContract", ImportLoadPolicy.Synchronous)]
        public LayerManagerContract LayerManagerContract { get; set; }
 
        [ImportSingle("Microsoft/PushpinFactoryContract", ImportLoadPolicy.Synchronous)]
        public PushpinFactoryContract PushpinFactoryContract { get; set; }
 
        [ImportSingle("Microsoft/PopupContract", ImportLoadPolicy.Synchronous)]
        public PopupContract PopupContract { get; set; }
 
        public override void Initialize()
        {
            base.Initialize();
            this.mainLayer = new MainLayer(this.Token);
 
            var pin = PushpinFactoryContract.CreateStandardPushpin(this.DefaultMap.Center);
            var entity = new Entity(pin);
 
            PopupContract.Register(
                entity,
                (PopupStateChangeContext context) =>
                {
                    context.Title = "こんにちは!";
                    if (context.State == PopupState.Normal)
                    {
                        context.Content = pin.Location.ToString();
                    }
                });
 
            this.mainLayer.Entities.Add(entity);
        }
 
        public override void Activate(System.Collections.Generic.IDictionary<string, string> activationParameters)
        {
            if (LayerManagerContract.ContainsLayer(this.mainLayer))
            {
                LayerManagerContract.BringToFront(this.mainLayer);
            }
            else
            {
                LayerManagerContract.AddLayer(this.mainLayer);
            }
        }
    }
}

ビルドできたら、作成したプラグインをテストしてみましょう。ローカルでMap AppをテストするツールがMap Appとして用意されています。テストするためには、http://bing.com/maps/explore?developer=1へアクセスします(developer=1パラメーターを付けるとテストツールが有効になります⁠⁠。Map App Galleryを表示するとMap app test tool図9があるので、これをクリックします。

図9 Map app test tool
図9 Map app test tool

作成したプラグインをBing Mapに追加するには、左側のパネルから「Choose plug-in assembly」ボタンをクリックします。そしてビルドしてできたプラグインのDLLファイルを選択します図10⁠。

図10 プラグイン アセンブリファイルの選択
図10 プラグイン アセンブリファイルの選択

テスト用にローカルで実行できる環境ですので、ここでの操作はサーバーにアップロードしてプラグインを登録しているわけではありません。

もしプラグインが他に参照しているアセンブリファイルがある場合は「Add supporting assemblies」ボタンから追加できます。SDKのライブラリーは追加する必要はありません。

次に「Next」ボタンをクリックします。

次に進むと、Map Appの名前や説明、パラメーターの入力などができますが、今回は特に編集せずに「Add to map apps」をクリックして完了します。

以上で、Bing Map App Galleryに作成したプラグインが追加されました図11⁠。

図11 My Map App
図11 My Map App

クリックしてアプリケーションを実行してみましょう。地図上にプッシュピンが表示されたでしょうか。マウスポインターを合わせるとポップアップが「こんにちは!」とプレビュー表示され、クリックすると位置情報と「こんにちは!」と書かれたポップアップが表示されます図12⁠。

図12 実行結果
図12 実行結果

いかがでしたでしょうか。今回は簡単なBing Map Appを作成しました。これだけでは実用性はありませんが、Map Appの開発については少しわかったのではないかと思います。SDKにはパネルやユーザー操作なども活用したC#のサンプルプロジェクトが含まれていますので、参考にすると良いと思います。また、全世界の人に使用してもらうには、登録の申請作業も必要です。それらについてはまた次回以降で紹介します。

おすすめ記事

記事・ニュース一覧