"Desktop Map App Development" SeriesPart5.
This time,in Part 4 we will add a feature to the map app created in that part to display individual attribute values of each data referenced on the map. Sample code for the features introduced in this article is available on Esri Japan GitHub .
Displaying Individual Attributes
We implement a feature to display attribute information of the selectedfeature on the map so you can check what values the feature has. This time, let's look at the attribute information of polygons for elementary and junior high school districts or points for elementary and junior high schools tapped on the map.
1. Open MainWindows.xaml and implement the GeoViewTapped event (add GeoViewTapped="MainMapView_GeoViewTapped").
MainWindows.xaml
<esri:MapView x:Name="MainMapView" Map="{Binding Map, Source={StaticResource MapViewModel}}" GeoViewTapped="MainMapView_GeoViewTapped"/>
2. Open MainWindows.xaml.cs and add references to the following namespaces.
MainWindows.xaml.cs
using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.UI.Controls;
using Esri.ArcGISRuntime.UI;
3. Create the process to execute in the GeoViewTapped event. To get the feature at the tapped location, use
GeoView.IdentifyLayerAsync(). This method takes the layer to identify and the screen point of the tap location included in the tap event arguments, and returns features on that layer at the tapped location.For creating the attribute display UI, use a Callout. Using a callout allows you to easily display a speech bubble at any point on the map.Pass the display position (tap location) and content (a CalloutDefinition) to , then show the callout.
MainWindows.xaml.cs
// Tap event handler for Map View
public async void MainMapView_GeoViewTapped(object sender, GeoViewInputEventArgs e)
{
// Dismiss any callout currently displayed
MainMapView.DismissCallout();
// Get screen coordinates of tapped point
Point tapScreenPoint = e.Position;
// Get map coordinates of tapped point
MapPoint tapMapPoint = e.Location!;
// Screen coordinate width and height for identification range centered on tapped point
int pixelTolerance = 1;
// Whether to create popup objects only or not
var returnPopupsOnly = false;
// Identify layers containing features at tapped point and get results
IReadOnlyList<IdentifyLayerResult> identifyLayerResults = await MainMapView.IdentifyLayersAsync(tapScreenPoint, pixelTolerance, returnPopupsOnly);
var currentMapViewModel = (MapViewModel)this.FindResource("MapViewModel");
// Create content for callout display
CalloutDefinition? calloutDefinition = currentMapViewModel.Identify(identifyLayerResults);
// Show callout on map if content is available
if (calloutDefinition != null)
{
MainMapView.ShowCalloutAt(tapMapPoint, calloutDefinition);
}
}
Tips: The second argument passed to IdentifyLayerAsync specifies the identification area. It is a square centered on the tap point with width and height equal to the specified screen coordinate value. A larger value identifies a wider area around the tap point, while a smaller value narrows it down.
///中略///
public CalloutDefinition Identify(IReadOnlyList<IdentifyLayerResult> identifyLayerResults)
{
CalloutDefinition? calloutDefinition = null;
try
{
// 既に選択されている(ハイライト表示されている)フィーチャの選択を解除する
if (_selectedFeature != null) {
_selectedLayer!.UnselectFeature(_selectedFeature);
}
if (identifyLayerResults.Count == 0 || identifyLayerResults[0].GeoElements.Count == 0) {
throw new Exception("フィーチャが見つかりません");
}
// IdentifyLayersAsync() で取得したフィーチャを選択する(ハイライト表示する)
_selectedFeature = (Feature)identifyLayerResults[0].GeoElements[0];
_selectedLayer = (FeatureLayer)identifyLayerResults[0].LayerContent;
_selectedLayer.SelectFeature(_selectedFeature);
// レイヤーの属性情報のフィールド名とエイリアスを取得する
// Key にフィールド名、Value にフィールドのエイリアスを格納したディクショナリを作成する
var fields = new Dictionary<string, string>();
for (int i = 0; i < _selectedLayer.FeatureTable!.Fields.Count; i++) {
Field? field = _selectedLayer.FeatureTable.Fields[i];
fields.Add(field.Name, field.Alias);
}
// コールアウトのコンテンツ(タイトル)を設定する
string layerName = _selectedLayer.Name;
// 該当フィーチャの全ての属性情報を結合した文字列を作成する
var attributes = new System.Text.StringBuilder();
if (_selectedFeature.Attributes.Count > 0)
{
foreach (var attribute in _selectedFeature.Attributes) {
// 該当フィールドのエイリアスを取得する(attribute.Key はフィールド名)
string fieldName = fields[attribute.Key];
// 該当フィールドのフィールド値を取得する
object fieldValue = attribute.Value!;
attributes.AppendLine(fieldName + ": " + fieldValue);
}
attributes.AppendLine();
}
// コールアウトのコンテンツを定義する CalloutDefinition を作成する
calloutDefinition = new CalloutDefinition(layerName, attributes.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "エラー");
}
return calloutDefinition!;
}
Tips: 選択したフィーチャをハイライトしたいときには FeatureLayer.SelectFeature()を使用します。このメソッドに渡されたフィーチャがハイライト表示されます。
5. アプリを実行して任意の地点をクリックしてみましょう。クリック地点上にフィーチャがある場合、コールアウトが表示され属性情報を確認できます。
第5弾「個別属性表示」ではマップに追加されているデータの属性情報を表示する方法を紹介しました。次回、第6弾ではデバイスの現在地をマップ上に表示する方法を紹介します。
関連リンク