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

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

この記事を読むのに必要な時間:およそ 3 分

はじめに

今までは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など広大なマップが用意されているゲームの販促アプリケーションで使えるかもしれませんね。色々と試して頂ければと思います。

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

著者プロフィール

和田健司(わだけんじ)

1982年10月12日生まれ。大阪で働くプログラマ。Microsoft MVP for Device Application Development(Jul 2010 - Jun 2011)。Windows Mobileに傾倒し今に至る。Windows Mobile向けのTipsを書いています。iPhoneアプリ開発を始めました。嫌いな食べ物はカレー。

URL: http://ch3cooh.jp/
Blog: http://d.hatena.ne.jp/ch3cooh393/

コメント

コメントの記入