Serie "Desarrollo de aplicación de mapas de escritorio"Parte7.
En esta ocasión,Parte6 añadiremos la función de búsqueda de direcciones a la aplicación de mapas creada. El código de ejemplo para las funciones presentadas en este artículo está disponible en Esri Japón GitHub .
Búsqueda de direcciones
ArcGIS Maps SDK for .NET proporciona funciones para obtener la ubicación correspondiente a partir de una cadena de texto con dirección mediantegeocodificacióny para obtener la dirección desde una ubicación específica mediante geocodificación inversa. En esta ocasión, implementaremos una función que permite ingresar una dirección en un cuadro de texto y hacer zoom en el mapa a la ubicación correspondiente.
1. En MapViewModel.cs,creamos una nueva propiedad llamadaGraphicsOverlays.Esta es una colección de GraphicsOverlay que almacena los gráficos del resultado de búsqueda (símbolo de ubicación y etiqueta con la dirección).
MapViewModel.cs
private GraphicsOverlayCollection? _graphicsOverlays;
public GraphicsOverlayCollection? GraphicsOverlays
{
get { return _graphicsOverlays; }
set
{
_graphicsOverlays = value;
OnPropertyChanged();
}
}
2. Abra MainWindow.xaml y use data binding para enlazar la propiedad MapViewModel GraphicsOverlays MapView control (agregue 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. En MapViewModel.cs, agregue código en la función SetupMap , cree un nuevo
{
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弾では概観図の作成方法を紹介します。
関連リンク