使ってみよう! Bing API/SDK

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

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

エンティティの作成

次にユーザーが選択した写真ファイルから,PhotoEntityオブジェクトを作成します。既に記述したコードのCreateEntityメソッド部分です。このメソッドは,FileInfoオブジェクトからPhotoEnityを作成して返します。

private PhotoEntity CreateEntity(FileInfo file)
{
    var entity = new PhotoEntity();
    entity.Name = file.Name; // 名前はファイル名を使用
    entity.Id = Guid.NewGuid().ToString(); // ID は GUID を使用

    // (ここに処理を追記)

    return entity;
}

サムネイル・経緯度情報の取得

PhotoEntityオブジェクトの作成には次の処理が必要です。

  • ファイルに含まれるサムネイルの取得
  • ファイルに含まれる経緯度情報の取得

最近のデジタルカメラで撮影した写真には,カメラの情報や,写真のサムネイル,GPS機能がある場合は撮影場所の経緯度情報などがExifという形式でファイルに含まれています。上記の各情報の取得には,このExifのデータを利用します。

また,今回作成のアプリケーションでは処理を簡単にするため,ExifデータにGPSの経緯度およびサムネイルが含まれていない場合は,リストに追加しません。

Exifデータから情報の取得は,.NET Frameworkでは可能ですが,Silverlightからはライブラリーが用意されていません。そのため,今回はCodeProjectで公開されているExifLibというライブラリーを利用します。ライブラリーを使用しない場合も,Exifデータから必要な情報の読み取りだけであれば,比較的容易に実装できるのではないかと思います。仕様も公開されていますので興味のある方は調べてみるとよいでしょう。

それでは,ExifLibを使用した場合のコードを示します。あらかじめソースコードをダウンロードおよびビルドを行い,ExifLib.dllをプロジェクトの参照に追加しておいてください。用意されているExifReaderクラスのReadJpegメソッドを使用するとExifデータの参照が可能です。メソッドの引数にはFileInfoオブジェクトを渡します。

var info = ExifLib.ExifReader.ReadJpeg(file);
if (info.GpsLatitudeRef == ExifLib.ExifGpsLatitudeRef.Unknown ||
    info.ThumbnailData == null)
{
    // 経緯度情報・サムネイルが含まれていない場合は null を返す
    return null;
}

最初にGPS経緯度情報の取得です。Exifでは経緯度は,東経139度44分28秒のように度・分・秒で分かれて記録されていますので,Bing Maps用に度単位に変換して,Locationオブジェクトを生成します。西経・南緯で記録されている場合は東経・北緯基準へ変換します。

// 経緯度を Bing Maps で使用する形式に変換
var latitude = info.GpsLatitude[0] +
    info.GpsLatitude[1] / 60.0 +
    info.GpsLatitude[2] / 3600.0;
if (info.GpsLatitudeRef == ExifLib.ExifGpsLatitudeRef.South)
{
    latitude = -latitude;
}

var longitude = info.GpsLongitude[0] +
    info.GpsLongitude[1] / 60.0 +
    info.GpsLongitude[2] / 3600.0;
if (info.GpsLongitudeRef == ExifLib.ExifGpsLongitudeRef.West)
{
    longitude = -longitude;
}

var location = new Location(latitude, longitude);

サムネイルの取得は次のようになります。

// 画像の読み込み
var img = new BitmapImage();
using (var ms = new MemoryStream(info.ThumbnailData))
{
    img.SetSource(ms);
}

取得した情報を,PhotoEntityのプロパティに設定して完了です。

entity.BitmapImage = img;

// プッシュピンの作成
var pin = plugin.PushpinFactoryContract.CreateStandardPushpin(location);
entity.Primitive = pin;

// MediaPushpin にする場合
// var image = new Image() { Source = entity.BitmapImage };
// var pin = plugin.PushpinFactoryContract.CreateMediaPushpin(location, (Entity ey) =>
// {
//     return image;
// });

実行と確認

以上でエンティティ作成部分ができ,アプリケーションとして動作するようになったはずです。ここまでの内容を実行してみましょう図2⁠。Map app test toolでDLLを指定する際に,MyPhotoMapApp.dllとExifLib.dllの指定が必要になります。また,実行の確認には,サムネイル・経緯度情報を含んだJPEGファイルが必要です。

図2 実行結果

図2 実行結果

写真を追加すると,パネルのリストボックスおよびレイヤーへ反映されたでしょうか。リストボックスの各アイテムをクリックすると,写真の場所へ移動します。

ポップアップ

次は,プッシュピンをクリックした場合,写真のサムネイルをポップアップ表示できるようにしてみましょう。ポップアップは,第1回でも紹介しています。そのときとは異なり,今回はポップアップ用のコントロールを用意します。

ポップアップの見た目は,ユーザーコントロールを使用して自由にデザインできます。プロジェクトにSilverlightユーザーコントロールを追加して次のようにXAMLを編集します。ここではクラス名をPopupControlとしました。

PopupControl.xaml

<UserControl x:Class="MyPhotoMapApp.PopupControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White">
        <Image Source="{Binding BitmapImage}" Margin="10">
            <Image.Effect>
                <DropShadowEffect BlurRadius="5" ShadowDepth="1" Direction="0" Color="Gray" />
            </Image.Effect>
        </Image>
    </Grid>
</UserControl>

ポップアップを登録するメソッドは,MyPhotoPanelクラスの方に次のように追加します。

MyPhotoPanel.xaml.cs

private void RegisterPopup(PhotoEntity entity)
{
    this.plugin.PopupContract.Register(entity, (PopupStateChangeContext context) =>
    {
        context.Title = entity.Name;
        if (context.State == PopupState.Normal)
        {
            context.Content = new PopupControl() { DataContext = entity };
        }
    });
}

このメソッドをCreateEntityメソッド内で呼び出すように編集すればポップアップがアプリケーションで有効になります。

private PhotoEntity CreateEntity(FileInfo file)
{
    // (省略)

    // (追加)
    // ポップアップの登録
    RegisterPopup(entity);

    return entity;
}

著者プロフィール

松江祐輔(まつえゆうすけ)

日本システムウエア株式会社 勤務。現在,ハードウェア設計・検証業務を担当。大学生・大学院生時代はベンチャー企業 有限会社ミレニアムシステムズにプログラマーとして従事。趣味はプログラミング。好きな言語はVisual Basic。Microsoft MVP for Windows Live Platform(Jul 2010 - Jun 2011),Windows Live(Jul 2011 - Jun 2013)。

URL:http://katamari.jp