デスクトップ地図アプリ開発 -属性表示-

233
0
02-01-2024 05:22 PM
Labels (1)

デスクトップ地図アプリ開発 -属性表示-

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

net00_01.png

今回は、第4弾で作成した地図アプリに、マップで参照している各データの個別値属性を表示する機能を追加します。本記事で紹介する機能のサンプル コードは Esriジャパン GitHub で公開しています。

 

個別属性の表示

マップ上で選択したフィーチャが持つ属性情報を表示する機能を実装して、フィーチャがどのような値を持っているのかを確認できるようにします。今回は、マップ上でタップした小中学校区のポリゴンまたは小中学校のポイントの属性情報を見てみましょう。

 

1. MainWindows.xaml を開き、GeoViewTappedイベントを実装します(GeoViewTapped="MainMapView_GeoViewTapped" を追加)。

 

MainWindows.xaml

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

 

 2. MainWindows.xaml.cs を開き、以下の名前空間の参照を追加します。

 

‍‍‍‍‍‍MainWindows.xaml.cs

using Esri.ArcGISRuntime.Data;
using Esri.ArcGISRuntime.Geometry;
using Esri.ArcGISRuntime.UI.Controls;
using Esri.ArcGISRuntime.UI;

 

3. GeoViewTapped イベントで実行する処理を作成します。タップした地点のフィーチャの取得には、GeoView.IdentifyLayerAsync() を使用します。このメソッドに、識別対象のレイヤーとタップ イベントの戻り値に含まれるタップ地点のスクリーン ポイントを渡して実行すると、レイヤーからタップ地点上にあるフィーチャを取得できます。
属性表示の UI 作成には、Callout(コールアウト)を使用します。コールアウトを使用すると、簡単にマップ上の任意の地点に吹き出しを表示することができます。GeoView.ShowCalloutAt() に、表示する位置(タップ地点)とコンテンツ(CalloutDefinition)を渡し、コールアウトを表示します。

 

MainWindows.xaml.cs

// マップ ビューのタップイベント ハンドラー
public async void MainMapView_GeoViewTapped(object sender, GeoViewInputEventArgs e)
{
   // 既に表示されているコールアウトを非表示にする
   MainMapView.DismissCallout();

   // タップした地点のスクリーン座標を取得する
   Point tapScreenPoint = e.Position;

   // タップした地点のマップ座標を取得する
   MapPoint tapMapPoint = e.Location!;

   // 識別範囲(タップした地点を中心)とするスクリーン座標の幅と高さ
   int pixelTolerance = 1;

   // ポップアップ オブジェクト作成の有無
   var returnPopupsOnly = false;

   // タップ地点に含まれるレイヤーを識別し、結果を取得する
   IReadOnlyList<IdentifyLayerResult> identifyLayerResults = await MainMapView.IdentifyLayersAsync(tapScreenPoint, pixelTolerance, returnPopupsOnly);

   var currentMapViewModel = (MapViewModel)this.FindResource("MapViewModel");

   // コールアウトの表示内容を作成する
   CalloutDefinition? calloutDefinition = currentMapViewModel.Identify(identifyLayerResults);

   // コールアウトをマップ上に表示する
   if (calloutDefinition != null)
   {
      MainMapView.ShowCalloutAt(tapMapPoint, calloutDefinition);
   }
}

 

Tips: IdentifyLayerAsync メソッドに渡す第2引数には、識別する範囲を渡します。タップ地点を中心として、設定したスクリーン座標値の高さおよび幅を持つ正方形が識別範囲です。この値が大きいとタップ地点からより広い範囲を識別し、値が小さいと識別される範囲は狭くなります。

 4. MapViewModel.cs に、Callout に表示するコンテンツ(CalloutDefinition)を定義する処理と取得されたフィーチャをハイライト表示する処理を作成します。IdentifyLayersAsync() を実行すると、該当するフィーチャの属性とジオメトリが含まれる GeoElement が返ります。GeoElement に含まれるフィーチャの属性情報を整形して CalloutDefinition を作成します。

 

MapViewModel.cs

public class MapViewModel : INotifyPropertyChanged
{
   private Feature? _selectedFeature;
   private FeatureLayer? _selectedLayer;

   ///中略///

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. アプリを実行して任意の地点をクリックしてみましょう。クリック地点上にフィーチャがある場合、コールアウトが表示され属性情報を確認できます。

net05_01.png

 

5弾「個別属性表示」ではマップに追加されているデータの属性情報を表示する方法を紹介しました。次回、第6弾ではデバイスの現在地をマップ上に表示する方法を紹介します。

 

関連リンク

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