※本記事は、連載記事「.NET SDK アプリ構築」の第 9 回目の記事です。
前回 (第 8 回) の記事では、ArcGIS Online のジオプロセシング サービスを利用して、指定した位置から徒歩 で 10 分以内に到達できる範囲を算出する方法を紹介しました。第 9 回となる今回は、この到達圏の結果を基に空間検索を行い、到達圏に含まれる物件をリスト表示する手順をご紹介します。

手順の概要
指定した位置から徒歩 10 分圏の到達圏を基に空間検索を行い、該当する物件をリスト表示するための手順は以下の通りです。
1) 選択された物件リストを表示するための Listbox の設定
2) 選択されているフィーチャのコレクションの初期化と Listbox のデータコンテキストの設定
3) 到達圏(選択範囲内)にある物件の選択
(ア) 「async」キーワードを使用した Task クラスの作成
(イ) 空間検索用フィルタの作成
(ウ) 空間検索の実行
(エ) 空間検索結果の処理
4) 物件を表示するリストボックス内のアイテムの選択変更時の処理
1) 選択された物件リストを表示するための ListBox の設定
選択された物件リストを表示するための Listbox(名前:selectedBuildingListBox)は第 2 回で画面レイアウトを定義した際にすでに追加されているため、ここでは設定の確認のみ行います。MainWindow.xaml の「選択された建物リスト」とコメントされている行以下が物件リストを定義している箇所です。ListBox クラスのテンプレートを使用して、リスト内に表示される項目として「名前」と「築年数」を設定しています。
[MainWindow.xaml]
<!--選択された物件リスト--> <ListBox x:Name="selectedBuildingListBox" ItemsSource="{Binding}" Grid.Row="1" SelectionMode="Single"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Vertical"> <StackPanel Orientation="Horizontal"> <TextBlock Text="名前: " /> <TextBlock Text="{Binding Attributes[BuildingName]}" /> </StackPanel> <StackPanel Orientation="Horizontal"> <TextBlock Text="築年数: " /> <TextBlock Text="{Binding Attributes[Age]}" /> <TextBlock Text="年" /> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>ListBox クラスのテンプレートには ItemsSource プロパティに物件データのコレクションが設定された際に物件レコードの属性情報を表示するためのバインド設定が行われています。フィーチャ サービスから取得される Feature の Attributes プロパティから「名前」に対応する [BuildingName] と築年数に対応する [Age] キーをそれぞれテンプレートに配置した TextBlock クラスの Text プロパティにバインドしています。ここで設定する Feature の Attributes プロパティのキーは、物件データのフィーチャ サービスの REST エンドポイントのページ内の「Fields:」セクション内で確認することができます。
※ REST エンドポイントの表示方法は第 4 回を参照してください。

2) 選択されているフィーチャのコレクションを初期化と Listbox のデータコンテキストの設定
まず初めに、 MainWindow.xaml.cs にメンバ変数を定義します。ここでは、以下のメンバ変数を定義します。
[MainWindow.xaml.cs]
private ObservableCollection<Feature> selectedFeatures; //選択されているフィーチャのコレクション
定義した選択されているフィーチャのコレクションを表す ObservableCollection<Feature> を初期化し、ListBox のデータコンテキストに設定します。
[MainWindow.xaml.cs]
//選択されているフィーチャのコレクションを初期化し選択リストのデータコンテキストに設定 selectedFeatures = new ObservableCollection<Feature>(); selectedBuildingListBox.DataContext = selectedFeatures;
3) 到達圏 (選択範囲内) にある物件の選択
(ア) 「async」 キーワードを使用した Task クラスの作成
到達圏(範囲)にある物件を選択するために「async」キーワードを使用した Task クラス(SelectFeatureWithIn)を作成します。Task クラスの引数には、Graphic クラスを設定します。
[MainWindow.xaml.cs]
/// <summary> /// 選択範囲内にある物件フィーチャを選択 /// </summary> /// <param name="g">選択範囲を示すグラフィック</param> private async Task SelectFeatureWithIn(Graphic g) { }(イ) 空間検索用フィルタの作成
空間検索用のフィルタに使用する SpatialQueryFilter クラスを初期化します。Geometry プロパティには、到達圏解析結果を示すグラフィックのジオメトリを設定し、SpatialRelationship プロパティには、物件フィーチャが到達圏に含まれることを示す Within を指定します。
[MainWindow.xaml.cs]
//空間検索用のフィルタを作成 SpatialQueryFilter spatialQueryFilter = new SpatialQueryFilter() { Geometry = g.Geometry, SpatialRelationship = SpatialRelationship.Within, };SpatialRelationship は空間検索の範囲を指定するプロパティです。例えば、フィーチャ同士の重なりあうことを示す Overlaps やフィーチャ同士が交差することを示す Crosses 等を指定することができます。
(ウ) 空間検索の実行
物件レイヤの ServiceFeatureTable に対して、空間検索を実行します。空間検索の実行には、QueryAsync メソッドを使用し、引数には空間検索用のフィルタ(spatialQueryFilter)を指定します。
[MainWindow.xaml.cs]
//物件レイヤのフィーチャテーブルに対して空間検索を実行 ServiceFeatureTable serviceFeatureTable = buildingLayer.FeatureTable as ServiceFeatureTable; IEnumerable<Feature> features = await serviceFeatureTable.QueryAsync(spatialQueryFilter);
(エ) 空間検索結果の処理
空間検索の結果として取得される Feature のコレクションを foreach 文を使用して、
「メンバ変数の定義」の手順にて定義した選択されているフィーチャのコレクションを表す selectedFeatures に追加します。
[MainWindow.xaml.cs]
IEnumerable<Feature> features = await serviceFeatureTable.QueryAsync(spatialQueryFilter); //空間検索結果のフィーチャを選択フィーチャコレクションに追加 foreach (Feature f in features) { selectedFeatures.Add(f); }最後に物件リストボックスの選択変更時のイベントハンドラを設定します。
[MainWindow.xaml.cs]
//物件リストボックスの選択変更時のイベントハンドラを設定 selectedBuildingListBox.SelectionChanged += selectedBuildingListBox_SelectionChanged;
4) 物件を表示するリストボックス内のアイテムの選択変更時の処理
物件を表示するリストボックス内のアイテムの選択変更時の処理としてまず、ClearSelection メソッドを使用して、物件レイヤを表す buildingLayer のフィーチャの選択をクリアします。
[MainWindow.xaml.cs]
/// <summary> /// 物件リストボックスの選択変更時の処理 /// </summary> private void selectedBuildingListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { //物件リストボックスで新規選択が行われていなければ処理を行わない if (e.AddedItems.Count < 1) return; //物件レイヤのフィーチャの選択をすべてクリア buildingLayer.ClearSelection();次に、物件リストボックスで選択された物件をハイライト表示するとともに、そのフィーチャを中心に地図を移動します。
[MainWindow.xaml.cs]
//物件リストボックスで選択された最初の物件フィーチャを物件フィーチャレイヤ上で選択 Feature selectedFeature = e.AddedItems[0] as Feature; buildingLayer.SelectFeatures(new long[] { Convert.ToInt64(selectedFeature.Attributes[buildingLayer.FeatureTable.ObjectIDField]) }); //選択されたフィーチャを中心に地図を移動 ainMapView.SetView((MapPoint)selectedFeature.Geometry);到達圏解析結果のクリア メソッドでの処理
[解析] ボタンをクリックした際に実行される ClearAnalystResult() メソッドに、結果やイベントハンドラを解除する記述を追加します。
[MainWindow.xaml.cs]
/// <summary> /// 到達圏解析結果のクリア /// </summary> private void ClearAnalysisResult() { //到達圏グラフィックをクリア serviceAreaGraphic = null; //到達圏解析結果表示用グラフィックスレイヤのグラフィックをクリア serviceAreaResultLayer.Graphics.Clear(); //物件レイヤのフィーチャの選択をすべてクリア buildingLayer.ClearSelection(); //物件リストボックスの選択変更時のイベントハンドラを解除 selectedBuildingListBox.SelectionChanged -= selectedBuildingListBox_SelectionChanged; //選択されているフィーチャのコレクションをクリア selectedFeatures.Clear(); }以上で、到達圏の結果を基に空間検索を行い、該当する物件をリスト表示するための実装は完了です。
アプリケーションの実行
アプリケーションを実行し、到達圏の結果の中に含まれる物件のみがリスト表示されることを確認します。またリスト内の物件を選択すると地図上の物件が選択されて地図がその物件を中心に移動することも確認します。

関連リンク
ArcGIS Runtime SDK for .NET サンプル アプリ構築:
ESRIジャパン Web サイト:
Esri 社(米国) Web サイト: