Série "Desenvolvimento de aplicativo de mapa para desktop"Parte7.
Desta vez,Parte6 do aplicativo de mapa criado, adicionaremos a função de pesquisa de endereço. O código de exemplo das funções apresentadas neste artigo está disponível no GitHub da Esri Japão .
Pesquisa de endereço
No ArcGIS Maps SDK for .NET, há funções para obter a localização correspondente a partir de uma string de endereço em texto, chamada
Geocodificação, e para obter o endereço a partir de uma localização específica, chamada geocodificação reversa. Desta vez, implementaremos a função que permite inserir um endereço em uma caixa de texto e dar zoom no mapa para a localização correspondente. 1. Em MapViewModel.cs, crie uma nova propriedade chamada GraphicsOverlays. Esta é uma coleção de GraphicsOverlay que armazena os gráficos dos resultados da pesquisa de endereço (símbolo da localização do endereço e rótulo do texto do endereço).
MapViewModel.csprivate GraphicsOverlayCollection? _graphicsOverlays;public GraphicsOverlayCollection? GraphicsOverlays{ get { return _graphicsOverlays; } set {
_graphicsOverlays = value;
OnPropertyChanged();
}
}
2. Abra MainWindow.xaml e vincule a propriedade GraphicsOverlays do MapViewModel ao controle MapView usando data binding (adicione 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. No método SetupMap em MapViewModel.cs, crie um novo GraphicsOverlay para exibir os resultados da pesquisa de endereço, adicione-o à coleção e atribua à propriedade GraphicsOverlays.
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. アプリを実行してみましょう。入力した住所にマップが移動し、住所テキストとシンボルがマップ上に表示されます。
第7弾「住所検索」では住所文字列から該当する位置を取得するジオコーディングの機能を実装する方法を紹介しました。次回、第8弾では概観図の作成方法を紹介します。
関連リンク