[UWP][MapControl] 緯度と経度から住所を求める

前回はジオコーディングについて説明しました。

今回は緯度と経度から住所を求める、逆ジオコーディングについて見ていきましょう。

※本コードを記述してみてわかりましたが、日本国内では詳しい住所は取得できないようです。

はじめにMainPage.xamlに住所を表示するためのTextBlockコントロールと、MapControlを配置します。

<StackPanel Orientation="Vertical">

    <!--<StackPanel Orientation="Horizontal">
        <TextBox x:Name="txtAddress" TextWrapping="Wrap" Text="" Width="381"/>
        <Button x:Name="btnGetLocation" Content="現在値の取得"
		    HorizontalAlignment="Left" VerticalAlignment="Stretch"
		    Width="120" Click="btnGetLocation_Click"	/>
        <TextBlock x:Name="txbPos" TextWrapping="Wrap" Text=""/>
    </StackPanel>-->
    <TextBlock x:Name="txtAddress" Width="500" HorizontalAlignment="Left" Text=""/>

    <Maps:MapControl x:Name="mapControl1" HorizontalAlignment="Left" VerticalAlignment="Top"
		Margin="0"
		Width="500"
		Height="500"    
		ZoomInteractionMode="GestureAndControl"
		TiltInteractionMode="GestureAndControl" 
		MapServiceToken="取得済みのキー" 
		MapTapped="mapControl1_MapTapped" />
</StackPanel>

MapControlのクリックされた位置の住所を求めるようにコーディングをします。

private async void mapControl1_MapTapped(MapControl sender, MapInputEventArgs args)
{
    // タップされた位置を検索
    MapLocationFinderResult result =
      await MapLocationFinder.FindLocationsAtAsync(args.Location);

    // 検索が成功したか
    if (result.Status == MapLocationFinderStatus.Success)
    {
        if (result.Locations.Count > 0)
        {
            string display =
                result.Locations[0].Address.Country +
                result.Locations[0].Address.District;

            // 住所を表
            txtAddress.Text = display;
        }
    }
}

result.Locations[0].Addressに取得した住所が入ってくるのですが、「日本」「東京」くらいまでの住所しか取得できませんでした。

逆ジオコーディングについてはあまり実用的でないかもしれません。

[UWP][MapControl] 住所から緯度と経度を求める

MapLocationFinderResultクラスのFindLocationAsyncメソッドを使用すると、住所から緯度と経度を求めることができます。

住所から緯度と経度を求めることをジオコーディングと呼びます。

今回のコードを実行する前に、MainPage.xamlを以下のように編集します。

画面上部には、検索する住所を入力できるTextBox、検索を開始するためButton、求めた緯度と経度を表示するTextBlockを配置します。

また、画面上にMapControlを1つ配置します。

<StackPanel Orientation="Vertical">

    <StackPanel Orientation="Horizontal">
        <TextBox x:Name="txtAddress" TextWrapping="Wrap" Text="" Width="381"/>
        <Button x:Name="btnGetLocation" Content="現在値の取得"
		    HorizontalAlignment="Left" VerticalAlignment="Stretch"
		    Width="120" Click="btnGetLocation_Click"	/>
        <TextBlock x:Name="txbPos" TextWrapping="Wrap" Text=""/>
    </StackPanel>
    
    <Maps:MapControl x:Name="mapControl1" HorizontalAlignment="Left" VerticalAlignment="Top"
		Margin="0"
		Width="500"
		Height="500"    
		ZoomInteractionMode="GestureAndControl"
		TiltInteractionMode="GestureAndControl" 
		MapServiceToken="取得済みのキー" 
                 />

</StackPanel>

続いて、Buttonが押されたときに、TextBoxに入力されている住所から緯度と経度を求めるコードを入力します。

private async void btnGetLocation_Click(object sender, RoutedEventArgs e)
{
    // ①TextBoxに入力されている住所を取得
    string addressToGeocode = txtAddress.Text;
    
    // ②現在 MapControlの中心に表示されている緯度と経度を取得しGeoPointを作成する
    BasicGeoposition queryHint = new BasicGeoposition();
    queryHint.Latitude = mapControl1.Center.Position.Latitude;
    queryHint.Longitude = mapControl1.Center.Position.Longitude;
    Geopoint hintPoint = new Geopoint(queryHint);

    // ③住所を元に緯度と経度を求める
    MapLocationFinderResult result =
          await MapLocationFinder.FindLocationsAsync(
                            addressToGeocode,
                            hintPoint,
                            3);

    // ④住所から緯度と経度の取得が成功したか
    if (result.Status == MapLocationFinderStatus.Success)
    {
        // TextBlockに検索結果の緯度と経度を表示する
        txbPos.Text = "result = (" +
              result.Locations[0].Point.Position.Latitude.ToString() + "," +
              result.Locations[0].Point.Position.Longitude.ToString() + ")";

        // ⑤MapControlの中心を、検索結果の位置に設定する
        mapControl1.Center = result.Locations[0].Point;
    }
}

①は、TextBoxに入力されている住所を変数に格納しています。

②は、MapControlの現在の中心位置の緯度と経度を取得しています。個々で取得した緯度と経度は、検索時の起点となる位置とします(③で使用します)。

③はFindLocationAsyncメソッドを使用して、住所から位置情報を取得します。第1引数は住所を表す文字列を、第2引数は検索を開始する地理的な場所をセットします(②で作成した位置)、第3引数は返される位置情報の最大数です。

④は、検索が成功したかどうかをチェックしています。取得結果はresul.Locationsで取得することができます。ここからLatitudeとLongtitudeを取得します。

⑤は、検索した緯度と経度を、MapControlの中心に設定しています。

 

以下に、東京都庁の住所を入力して検索をしてみた実行例を示します。

実行例

[UWP][MapControl] マップアイコンを表示する

MapControlにはプッシュピンや画像、図形などを表示することができます。

プッシュピンや画像、図形を表示するにはMapIconオブジェクトを作成します。

以下に、C#でのコード例を示します。

// 表示位置となる緯度と経度を設定する
BasicGeoposition cityPosition = new BasicGeoposition() { Latitude = 35.689, Longitude = 139.692 };
Geopoint cityCenter = new Geopoint(cityPosition);

// マップアイコンの作成
MapIcon mapIcon1 = new MapIcon();                       // ①
mapIcon1.Location = cityCenter;                         // ②
mapIcon1.NormalizedAnchorPoint = new Point(0.5, 1.0);   // ③
mapIcon1.Title = "都庁";                                // ④
mapIcon1.ZIndex = 0;                                    // ⑤

mapControl1.MapElements.Add(mapIcon1);                  // ⑥

// 地図の中心とズームレベルを設定する
mapControl1.Center = cityCenter;
mapControl1.ZoomLevel = 16;
  • ①マップアイコンオブジェクトを作成します
  • ②マップアイコンの表示位置を設定します
  • ③マップアイコンのアンカーポイントを作成します。
    マップアイコンは左上隅が(0,0)、右下が(1,1)の座標系で表されます。この座標県の中でどこの位置をGeoPointの位置とするかを決めます。
  • ④マップアイコンの脇に表示するテキストを設定します。
  • ⑤は重なり順を設定します。
  • ⑥は作成したマップアイコンをMapControlに追加しています

実行例を以下に示します。

実行例

[UWP][MapCotrol] 表示スタイルを変更する

MapControlはStyleプロパティを使用して表示スタイルを変更することができます。

Styleプロパティには、以下の表に示すMapStyle列挙体の値を設定することができます。

メンバー 説明
 None  スタイルなし
 Road  道路地図を表示
 Aerial  航空写真地図を表示
 AerialWithRoads  航空地図&道路地図を表示
 Terrain  地形地図を表示
 Aerial3D  航空写真地図(3D)を表示
 Aerial3DWithRoads  航空地図(3D)&道路地図を表示

以下は航空地図(3D)&道路地図を表示する例です

public MainPage()
{
    this.InitializeComponent();

    // 表示位置となる緯度と経度を設定する
    BasicGeoposition cityPosition = new BasicGeoposition() { Latitude = 35.689, Longitude = 139.692 };
    Geopoint cityCenter = new Geopoint(cityPosition);

    // 地図の中心とズームレベルを設定する
    mapControl1.Center = cityCenter;
    mapControl1.ZoomLevel = 12;

    // 航空地図(3D)&道路地図を表示
    mapControl1.Style = Windows.UI.Xaml.Controls.Maps.MapStyle.Aerial3DWithRoads;
}

航空地図(3D)&道路地図を表示する例

[UWP][MapCotrol] 表示角度を設定する

MapControlは、表示時の地図の角度を設定することができます。

角度を設定するには Headingプロパティを使用します。

Headingプロパティには0~360までの値を設定することができ、0(360)=北、90=東、180=南、270=西 となります。

以下は90度(東)回転させて表示するように、Headingプロパティに90を設定しています。

<Maps:MapControl x:Name="mapControl1" HorizontalAlignment="Left" VerticalAlignment="Top"
             Margin="0"
             Width="1910"
             Height="1000"    
             ZoomInteractionMode="GestureAndControl"
             TiltInteractionMode="GestureAndControl" 
             MapServiceToken="取得したキー" 
             Heading="90"/>

90度回転させた地図の表示