Windows Phoneアプリケーション開発入門

第23回Bing Mapsで遊んでみよう! おまけ

はじめに

今まではWindows Phone 7向けの開発は、C#でしかできませんでした。ようやく先日11月28日に、VB.NETでのWindows Phone 7に対応したVisual Basic for Windows Phone Developer ToolsがRTW版としてリリースされました。

普段からVB.NETを使っておられる方、Windows Phone 7のアプリケーション開発に興味はあるけれど、C#が判らないので触っていなかった方には、吉報ではないでしょうか。

MSDNオンラインライブラリに掲載されているWindows Phone 7向けのコードサンプルも、C#版のものだけでなくVB.NET版のものも徐々に追加されています。

マイクロソフトは今回の対応でVB.NETプログラマも取り込み、よりWindows Phone 7向けのMarketplaceを盛り上げていきたいと考えているのがよくわかりますね。

ただし、導入前に気をつけて頂きたいことが2点あります。

まず、Windows Phone 7では二つのフレームワークを使ってアプリ/ゲームを開発することができます。SilverlightとXNAです。VB.NETを使った開発は今のところSilverlightにしか対応しておりません。

次に、Windows Phone Developer Toolsについてくる無償のVisual Studio 2010 Express Edition for Windows Phoneでは、VB.NETを使って開発する機能を使用することができません。製品版であるProfessional以上のエディションのVisual Studio 2010が必要になります。

今回は、第20回から22回に掛けて連載していたWindows Phone 7でのBingマップ活用のおまけ編です。

Bing MapsコントロールでBing Maps以外の画像を使用する

Bing Mapには、Deep Zoomと呼ばれる技術が使われています。Deep Zoomというのは、超高画質の画像を例えば256ピクセルx256ピクセルと言った小さなタイルに分割して、描画に必要な箇所のタイルだけを読み込み、スムーズなズームイン、ズームアウト、スクロール(パン)を実現させることができます。

分割されたタイル画像は、地図画像が変更されてもサーバーサイドにて変更可能なように、Bing Mapコントローラーを介してサーバーから取得しています。一連の流れとしては、タイルのURLを作成して、Bing Mapコントロールでダウンロードおよび表示を行います。

実際にタイル取得のためのURLを作成しているメソッドは、Microsoft.Phone.Controls.Maps.TileSourceクラスの以下のメソッドになります。

Uri GetUri(int x, int y, int zoomLevel)

タイルを読み込むGetUriメソッドをオーバーライドして、本来のBing Mapの画像ではなく好きな画像のURLを渡すようにしてしまえば、Bing Maps以外の画像を表示させることが可能です。まずxamlに名前空間を追加しましょう。

  xmlns:mapCtrl="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
  xmlns:gMapEx="clr-namespace:GetMapsSample"
  xmlns:device="clr-namespace:System.Device.Location;assembly=System.Device">

次にBing Map Controlを配置しましょう。CredentialsProviderプロパティにはBing Maps Keyを設定しておいてください。ちなみにキーの取得の方法は、連載第20回のBing Maps Keyの取得方法あたりを見てくださいね。

接近しているほうがBing Mapsとの比較が判りやすいと思いますのでズームレベルは16にして、いつもの大阪駅を中心にして地図を表示しています。

  <mapCtrl:Map Height="610" HorizontalAlignment="Left" 
    Name="map1" VerticalAlignment="Top" Width="456"
          CredentialsProvider="your app key" ZoomLevel="16">
      <mapCtrl:Map.Center>
          <device:GeoCoordinate Altitude="NaN" Course="NaN" 
            HorizontalAccuracy="NaN" Latitude="34.701189" 
            Longitude="135.496016" Speed="NaN" VerticalAccuracy="NaN" />
      </mapCtrl:Map.Center>
      <mapCtrl:Map.Children>
          <mapCtrl:MapTileLayer>
              <mapCtrl:MapTileLayer.TileSources>
                  <gMapEx:GetMapTileSource TileSourceType="Street" />
              </mapCtrl:MapTileLayer.TileSources>
          </mapCtrl:MapTileLayer>
      </mapCtrl:Map.Children>
  </mapCtrl:Map>

XAMLで使ったGetMapTileSourceクラスとTileSourceType型が定義されていないので、Visual Studio上ではエラーになっているかと思います。適当にGetMapTileSource.csといったソースを新規作成してコピペしてください。

XAMLの名前空間の指定には、GetMapsSampleを使っていましたので、名前空間をきちん指定しましょう。必要であれば適切に変更をお願いします。

また、下記のサンプルコード内でGetUriメソッドをオーバーライドしています。自分の表示させたいタイルのURLを設定して頂ければと思います。

namespace GetMapsSample
{
    public enum GetMapTileSourceType
    {
        Street,
        Hybrid,
        Satellite,
        Physical,
        PhysicalHybrid,
        StreetOverlay,
        WaterOverlay
    }

    public class GetMapTileSource : Microsoft.Phone.Controls.Maps.TileSource
    {
        public GetMapTileSource()
        {
            TileSourceType = GetMapTileSourceType.Street;
        }
        private char _mapMode;

        private GetMapTileSourceType _tileSourceType;
        public GetMapTileSourceType TileSourceType
        {
            get { return _tileSourceType; }
            set
            {
                _tileSourceType = value;
                _mapMode = TypeToMapMode(value);
            }
        }

        public override Uri GetUri(int x, int y, int zoomLevel)
        {
            if (zoomLevel > 0)
          {
              var url = "ここでタイル画像取得の為のURLを設定します"; 
              return new Uri(url);
          }
          return null;
        }

        private static char TypeToMapMode(GetMapTileSourceType tileSourceType)
        {
            switch (tileSourceType)
            {
                case GetMapTileSourceType.Hybrid:
                    return 'y';
                case GetMapTileSourceType.Satellite:
                    return 's';
                case GetMapTileSourceType.Street:
                    return 'm';
                case GetMapTileSourceType.Physical:
                    return 't';
                case GetMapTileSourceType.PhysicalHybrid:
                    return 'p';
                case GetMapTileSourceType.StreetOverlay:
                    return 'h';
                case GetMapTileSourceType.WaterOverlay:
                    return 'r';
            }
             return ' ';
        }
    }
}

さて、上記のサンプルコードを実行してBing Mapを並べてみました。実験的にGoogle Mapのタイルが表示させているのが見てご理解頂けるかと思います。

図1 実験的にGoogle MapとBing Mapを並べた
図1 実験的にGoogle MapとBing Mapを並べた

さいごに

これは偶然にもGoogle Mapが、Bing Mapと同じ256ピクセル×256ピクセルの画像をタイルに使用していたので同じズーム値で表示させることができました。Bing Mapコントロールひとつを取ってみても、Windows Phone 7プログラミングはWindows Mobile 6.xとは違った自由度の高さがあります。

ほかにもこのTipsを流用するとすれば、MMOなど広大なマップが用意されているゲームの販促アプリケーションで使えるかもしれませんね。色々と試して頂ければと思います。

以上で今回は終わりです。ありがとうございました。

おすすめ記事

記事・ニュース一覧