はじめに
以前、GeoNet ブログで 2019/8/23 (金) に弊社永田町オフィスにて開催した「 ArcGIS 開発者のための最新アプリ開発塾 2019 」のハンズオン資料を公開しました。本連載では、そのハンズオンで活用した、「 Data Collection for .NET 」アプリが持つ主要な機能について解説を、前半/後半2回にわたりご紹介しています。
このアプリが持つ主要な機能は以下の4つで、前回の記事では 「 1.認証 」,「 2.オフラインデータの作成 」 について解説を行いましたが、本記事では 「 3. (オフライン)データの編集 」,「 4.オフラインデータとオンラインデータの同期 」 について解説を行います。
1.認証
2.オフラインデータの作成
3.(オフライン)データの編集
4.オフラインデータとオンラインデータの同期
3. (オフライン)データの編集
以下のイメージでは、街路樹ポイント データの属性を編集しています。

今回使用している Web マップ では、属性値:「 Condition 」 を使用してポイントのシンボルを定義しているため、「 Condition 」 項目の値を変更するとポイントのシンボルが変更されます。
データ編集時の処理の流れ
データ編集時は以下3点が実装のポイントとなります。それぞれの処理概要を説明します。
1.フィーチャの選択
2.属性画面の表示
3.データの更新
1.フィーチャの選択
GeoView クラスの IdentifyLayersAsync メソッドを使用してクリックした地点にフィーチャがあるかどうか確認することができます。フィーチャが存在する場合、FeatureLayer クラスの SelectFeature メソッドでそのフィーチャを選択します。
※ ソースファイル:DataCollection.Shared\Binding Support\IdentifyController.cs
DataCollection.Shared\ViewModels\MainViewModel.cs
<SPAN class="comment token">// クリックした地点にフィーチャがあるか確認</SPAN>
<SPAN class="keyword token">var</SPAN> identifyLayersTask <SPAN class="operator token">=</SPAN> mapView<SPAN class="punctuation token">.</SPAN><SPAN class="token function">IdentifyLayersAsync</SPAN><SPAN class="punctuation token">(</SPAN>tapScreenPoint<SPAN class="punctuation token">,</SPAN> pixelTolerance<SPAN class="punctuation token">,</SPAN> returnPopupsOnly<SPAN class="punctuation token">,</SPAN> maxResultCount<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// クリックした地点にフィーチャがある場合</SPAN>
<SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN>identifyLayersTask<SPAN class="punctuation token">.</SPAN>Result<SPAN class="punctuation token">.</SPAN>Count <SPAN class="operator token">></SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
<SPAN class="comment token">// フィーチャを取得</SPAN>
<SPAN class="keyword token">var</SPAN> feature <SPAN class="operator token">=</SPAN> identifyLayerResult<SPAN class="punctuation token">.</SPAN>GeoElements<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">as</SPAN> ArcGISFeature<SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// フィーチャを選択</SPAN>
<SPAN class="keyword token">var</SPAN> featureLayer <SPAN class="operator token">=</SPAN> feature<SPAN class="punctuation token">.</SPAN>FeatureTable<SPAN class="punctuation token">.</SPAN>FeatureLayer<SPAN class="punctuation token">;</SPAN>
featureLayer<SPAN class="punctuation token">.</SPAN><SPAN class="token function">SelectFeature</SPAN><SPAN class="punctuation token">(</SPAN>feature<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>2.属性画面の表示
PopupManager と Popup クラスを使用して属性画面を表示させます。そして、StartEditing メソッドで編集開始、FinishEditingAsync メソッドで編集を終了します。
※ ソースファイル:DataCollection.Shared\ViewModels\IdentifiedFeatureViewModel.cs
<SPAN class="keyword token">public</SPAN> PopupManager PopupManager <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN>
<SPAN class="comment token">// 属性画面を表示</SPAN>
PopupManager <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">PopupManager</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Popup</SPAN><SPAN class="punctuation token">(</SPAN>feature<SPAN class="punctuation token">,</SPAN> featureTable<SPAN class="punctuation token">.</SPAN>PopupDefinition<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// 編集開始</SPAN>
PopupManager<SPAN class="punctuation token">.</SPAN><SPAN class="token function">StartEditing</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// 編集終了</SPAN>
PopupManager<SPAN class="punctuation token">.</SPAN><SPAN class="token function">FinishEditingAsync</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>3.データの更新
Popup クラスの GeoElement プロパティを使用して編集対象フィーチャを取得します。そして、FeatureTable クラスの UpdateFeatureAsync メソッドを使用してフィーチャの更新を行います。
※ ソースファイル:DataCollection.Shared\ViewModels\EditViewModel.cs
<SPAN class="comment token">// 編集対象フィーチャの取得</SPAN>
<SPAN class="keyword token">var</SPAN> editedFeature <SPAN class="operator token">=</SPAN> popupManager<SPAN class="punctuation token">.</SPAN>Popup<SPAN class="punctuation token">.</SPAN>GeoElement <SPAN class="keyword token">as</SPAN> ArcGISFeature<SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// フィーチャの更新</SPAN>
table<SPAN class="punctuation token">.</SPAN><SPAN class="token function">UpdateFeatureAsync</SPAN><SPAN class="punctuation token">(</SPAN>editedFeature<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
4. オフラインデータとオンラインデータの同期
以下のイメージでは、編集したオフラインデータをオンラインデータに同期させています。

オフラインデータとオンラインデータの同期は 「 Esri.ArcGISRuntime.Tasks.Offline 」 ネームスペースにあるクラスやプロパティを使用することによって実現することができます。以下に詳細を記載します。
オフラインデータ同期の流れ
1.同期用のインスタンス作成
OfflineMapSyncTask クラスの CreateAsync メソッドを使用します。
2.同期用のパラメータ作成
OfflineMapSyncParameters クラスで同期用のパラメータを作成します。パラメータの詳細は以下に記載します。
・SyncDirection ⇒ 同期方法の指定
・RollbackOnFailure ⇒ 処理失敗時にロールバックするかの指定
3.同期用のジョブ作成
OfflineMapSyncJob クラスの SyncOfflineMap メソッドを使用します。
4.同期処理実行
OfflineMapSyncJob クラスの Start メソッドを使用します。
※ ソースファイル:DataCollection.Shared\ViewModels\SyncViewModel.cs
<SPAN class="comment token">// 1.同期用のインスタンス作成</SPAN>
<SPAN class="keyword token">var</SPAN> syncTask <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">await</SPAN> OfflineMapSyncTask<SPAN class="punctuation token">.</SPAN><SPAN class="token function">CreateAsync</SPAN><SPAN class="punctuation token">(</SPAN>map<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// 2.同期用のパラメータ作成</SPAN>
<SPAN class="keyword token">var</SPAN> taskParams <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">OfflineMapSyncParameters</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN>
<SPAN class="punctuation token">{</SPAN>
SyncDirection <SPAN class="operator token">=</SPAN> SyncDirection<SPAN class="punctuation token">.</SPAN>Bidirectional<SPAN class="punctuation token">,</SPAN>
RollbackOnFailure <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">true</SPAN>
<SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// 3.同期用のジョブ作成</SPAN>
<SPAN class="keyword token">internal</SPAN> OfflineMapSyncJob OfflineMapSyncJob <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">get</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">private</SPAN> <SPAN class="keyword token">set</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN>
OfflineMapSyncJob <SPAN class="operator token">=</SPAN> syncTask<SPAN class="punctuation token">.</SPAN><SPAN class="token function">SyncOfflineMap</SPAN><SPAN class="punctuation token">(</SPAN>taskParams<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="comment token">// 4.同期処理実行</SPAN>
OfflineMapSyncJob<SPAN class="punctuation token">.</SPAN><SPAN class="token function">Start</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN>
<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>まとめ
いかがでしたでしょうか。本記事では、Data Collection for .NET に実装されている 「 (オフライン)データの編集 」 や 「 オフラインデータとオンラインデータの同期 」 について簡単ですが、機能の解説を行いました。 Web マップを活用してオフラインで使用するアプリの開発を行う際には、本記事の内容を参考にしていただければと思います。また、Data Collection for .NET は 参照するWeb マップを変更するだけで、汎用的にご利用いただけますので、現在業務でお使いのデータでアプリを使用してみてください。
関連リンク
Data Collection for .NET の機能を解説 (前半)
Data Collection
Data Collection .NET (GitHub)
Data Collection iOS (GitHub)
ArcGIS Runtime SDK for .NET (ArcGIS for Developers)
ArcGIS for Developer 開発リソース集