かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

UWPで地図を表示する

UWPのMapControlを使うことで簡単に地図を表示することが出来ます。

ちょっとめんどくさいのが、Bing Map デベロッパーセンターというところでトークンを作らないといけないところです。

www.bingmapsportal.com

アカウントってMy accountのCreate or view keysのClick here to create a new keyのhereの所のリンクをクリックして必要情報を入力するとキーが作れます。

f:id:okazuki:20160214201056p:plain

f:id:okazuki:20160214201318p:plain

画面にMapControlを置いてMapServiceTokenにさっきのページで取得したキーを指定して使います。

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App31"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:Maps="using:Windows.UI.Xaml.Controls.Maps"
      x:Class="App31.MainPage"
      mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

        <Maps:MapControl x:Name="MapControl"
                         MapServiceToken="さっきのキー" />

    </Grid>
</Page>

これだけで実行するとマップが表示されます。

任意の場所に移動する

緯度経度がわかればその場所に移動できます。MapControlのCenterプロパティにGeopointを設定すればOKです。GeopointはBasicGeopositionというクラスを受け取ってBasicGeopositionで緯度経度を指定します。

var location = new Windows.Devices.Geolocation.Geopoint(
    new Windows.Devices.Geolocation.BasicGeoposition
    {
        Latitude = 34.396560,
        Longitude = 132.459622
    });
this.MapControl.Center = location;

拡大率を指定する

ZoomLevelで1~20で設定します。20が一番拡大した状態で、1が一番引いた状態です。

this.MapControl.ZoomLevel = 20;

アイコンを置く

MapIconというクラスをMapElementsに追加することで、アイコンが追加できます。

// MapIcon
var mapIcon = new MapIcon
{
    Location = location,
    Title = "ひろしま!",
    NormalizedAnchorPoint = new Point(0.5, 0.5)
};
this.MapControl.MapElements.Add(mapIcon);

XAMLを置く

任意のXAMLコントロールを置くことが出来るみたいです。 MapControlのChildrenに追加したあと、Location添付プロパティで場所を指定できます。NormalizedAnchorPointは、中心をどこにするかっていう0~1あたりを指定するものだと思います。0.5, 0.5を指定することで指定座標が真ん中に来るようになります。

// XAML
var border = new Border
{
    BorderBrush = new SolidColorBrush(Colors.Red),
    BorderThickness = new Thickness(5),
    Width = 100,
    Height = 100
};
this.MapControl.Children.Add(border);
MapControl.SetLocation(border, location);
MapControl.SetNormalizedAnchorPoint(border, new Point(0.5, 0.5));

全部まとめると

こんなコードになります。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Maps;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// 空白ページのアイテム テンプレートについては、http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 を参照してください

namespace App31
{
    /// <summary>
    /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            var location = new Windows.Devices.Geolocation.Geopoint(
                new Windows.Devices.Geolocation.BasicGeoposition
                {
                    Latitude = 34.396560,
                    Longitude = 132.459622
                });
            this.MapControl.Center = location;

            this.MapControl.ZoomLevel = 20;

            // MapIcon
            var mapIcon = new MapIcon
            {
                Location = location,
                Title = "ひろしま!",
                NormalizedAnchorPoint = new Point(0.5, 0.5)
            };
            this.MapControl.MapElements.Add(mapIcon);

            // XAML
            var border = new Border
            {
                BorderBrush = new SolidColorBrush(Colors.Red),
                BorderThickness = new Thickness(5),
                Width = 100,
                Height = 100
            };
            this.MapControl.Children.Add(border);
            MapControl.SetLocation(border, location);
            MapControl.SetNormalizedAnchorPoint(border, new Point(0.5, 0.5));
        }
    }
}

実行するとこんな感じです。広島県庁にピンと矩形が表示されます。

f:id:okazuki:20160214202351p:plain