デスクトップ地図アプリ開発 -住所検索-

293
0
02-01-2024 05:28 PM
Labels (1)

デスクトップ地図アプリ開発 -住所検索-

「デスクトップ地図アプリ開発」シリーズ7弾です。 

net00_01.png
 

今回は、6 で作成した地図アプリに、住所検索機能を追加します。本記事で紹介する機能のサンプル コードは Esriジャパン GitHub で公開しています。

 

住所検索

ArcGIS Maps SDK for .NET では、テキストの住所文字列から該当する位置を取得するジオコーディングや、特定の位置からそこの住所を取得するリバースジオコーディングの機能が用意されています。今回は、テキストボックスに住所を入力して、該当する位置にマップをズームする機能を実装します。

 

1. MapViewModel.cs で、GraphicsOverlays という新しいプロパティを作成します。これは、住所検索結果のグラフィック(住所位置のシンボルと住所文字列のラベル)を格納する GraphicsOverlay のコレクションです。

 

MapViewModel.cs

private GraphicsOverlayCollection? _graphicsOverlays;
public GraphicsOverlayCollection? GraphicsOverlays
{
   get { return _graphicsOverlays; }
   set
   {
      _graphicsOverlays = value;
      OnPropertyChanged();
   }
}

 

2. MainWindow.xaml を開き、データ バインディングを使用して、MapViewModel GraphicsOverlays プロパティを MapView コントロールにバインドします(GraphicsOverlays="{Binding GraphicsOverlays, Source={StaticResource MapViewModel}}" を追加)。

 

MainWindow.xaml

<esri:MapView x:Name="MainMapView" 
                      Map="{Binding Map, Source={StaticResource MapViewModel}}" 
                      GraphicsOverlays="{Binding GraphicsOverlays, Source={StaticResource MapViewModel}}"
                      GeoViewTapped="MainMapView_GeoViewTapped"/>

 

3. MapViewModel.cs SetupMap 関数に、住所検索の結果を表示するための新しい GraphicsOverlay を作成してコレクションに追加し、GraphicsOverlays プロパティに代入するコードを追加します。
続いて、ジオコーディング サービスの URL をパラメーターに設定したLocatorTask を作成します。この LocatorTask ArcGIS Platform ジオコーディング サービスにリクエストして該当住所の位置を返します。

 

MapViewModel.cs

public class MapViewModel : INotifyPropertyChanged
{
   private LocatorTask? _geocoder;

   ///中略///

   private async Task SetupMap()
   {
      ///中略///

      // 住所検索結果の表示用の新しい GraphicsOverlay を作成する
      GraphicsOverlay geocodeResultOverlay = new GraphicsOverlay();
      // GraphicsOverlays (GraphicsOverlayCollection) プロパティを設定する
      GraphicsOverlayCollection graphicsOverlays = new 
      GraphicsOverlayCollection
      {
         geocodeResultOverlay
      };
      this.GraphicsOverlays = graphicsOverlays;

      // 住所検索用の LocatorTask を作成する
      Uri _serviceUri = new Uri("https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer");
      _geocoder = await LocatorTask.CreateAsync(_serviceUri);
   }

 

4. MainWindow.xaml で住所を入力するテキスト ボックスを含んだ画面を作成します。

 

MainWindow.xaml

<Border HorizontalAlignment="Right" VerticalAlignment="Top" Background="White" BorderThickness="0.5" BorderBrush="Gray" Margin="10" Padding="10" Width="250">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="4*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" FontWeight="SemiBold" Text="住所を入力" TextAlignment="Center" />
        <TextBox x:Name="SearchBox" Grid.Row="1" Grid.Column="0" Margin="0,5,5,0" Text="東京都千代田区平河町2-7-1"/>
        <Button x:Name="SearchButton" Grid.Row="1" Grid.Column="1" Margin="0,5,0,0" Click="SearchButton_Click" Content="検索"/>
    </Grid>
</Border>

 

5. MainWindow.xaml.cs に検索ボタンをクリックした時の処理を実装します。

 

MainWindow.xaml.cs

// 住所検索ボタンのクリック イベント ハンドラー
private async void SearchButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
   var currentMapViewModel = (MapViewModel)this.FindResource("MapViewModel");

   // テキストボックスの値を取得して、住所検索を実行する
   MapPoint? addressPoint = await currentMapViewModel.SearchAddress(SearchBox.Text);

   if (addressPoint != null) {
      // 検索した住所にマップの表示位置を変更する
      MainMapView.SetViewpoint(new Viewpoint(addressPoint, 20000));
   }
}

 

6. MapViewModel.cs に住所検索の処理を実装します。ジオコーディングを実行する GeocodeAsync メソッドには、オプションで検索結果を細かく指定するためのパラメーター(GeocodeParameters)を設定できます。GeocodeAsync メソッドは、デフォルトで検索結果の候補の住所全て(最大50個まで)が、マッチ率が高い順で返されます。今回は、MaxResults プロパティを設定し検索結果として返される候補の住所を1個に制限しています。検索結果で返される情報の詳細については、こちらも併せてご参照ください。

 

MapViewModel.cs

public async Task<MapPoint> SearchAddress(string searchText)
{
   MapPoint? addressLocation = null;
   try {
      // 既存の検索結果のグラフィックスを消去する
      GraphicsOverlay? geocodeResultOverlay = this.GraphicsOverlays?.FirstOrDefault();
      geocodeResultOverlay!.Graphics.Clear();

      // テキストボックスの値が空か LocatorTask が無効の場合は、処理を中止する
      if (String.IsNullOrWhiteSpace(searchText) || _geocoder == null) {
         throw new Exception("検索文字列が空か、ジオコーダーが無効です");
      }

      // 検索結果を1つ(マッチ率が最も高い住所)だけに制限する、ジオコーディングのパラメーターを作成する
      GeocodeParameters geocodeParameters = new GeocodeParameters();
      geocodeParameters.MaxResults = 1;

      //入力文字列からジオコーディングを実行しマッチする住所(住所文字列と位置)を取得する
      IReadOnlyList<GeocodeResult> addresses = await _geocoder.GeocodeAsync(searchText, geocodeParameters);

      // 検索結果が取得できない場合は処理を中止する
      if (addresses.Count < 1) {
         throw new Exception("一致する結果がありません");
      }

      // 住所の位置に表示するポイント シンボルを作成する
      SimpleMarkerSymbol pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle.Diamond, System.Drawing.Color.Red, 15);

      // 住所文字列のテキスト シンボルを作成する
      TextSymbol textSymbol = new TextSymbol(addresses.First().Label, System.Drawing.Color.Yellow, 15, Esri.ArcGISRuntime.Symbology.HorizontalAlignment.Center, Esri.ArcGISRuntime.Symbology.VerticalAlignment.Bottom);

      textSymbol.HaloColor = System.Drawing.Color.Gray;
      textSymbol.HaloWidth = 3;
      textSymbol.OffsetY = 10;

      // ポイントとテキスト シンボルからグラフィックを作成する
      Graphic pointGraphic = new Graphic(addresses.First().DisplayLocation, pointSymbol);
      Graphic textGraphic = new Graphic(addresses.First().DisplayLocation, textSymbol);

      // GraphicsOverlay にグラフィックを追加する
      geocodeResultOverlay.Graphics.Add(pointGraphic);
      geocodeResultOverlay.Graphics.Add(textGraphic);

      // マップを住所の位置にズームするためのポイントを返す
      addressLocation = addresses.First().DisplayLocation;
   }

   catch (Exception ex) {
      MessageBox.Show(ex.ToString(), "エラー");
   }

   return addressLocation!;
}

 

7. アプリを実行してみましょう。入力した住所にマップが移動し、住所テキストとシンボルがマップ上に表示されます。 

net07_01.png

 

7弾「住所検索」では住所文字列から該当する位置を取得するジオコーディングの機能を実装する方法を紹介しました。次回、第8弾では概観図の作成方法を紹介します。

関連リンク

Labels (1)
Version history
Last update:
‎02-01-2024 05:28 PM
Updated by:
Contributors