こちらは、ArcGIS アドベントカレンダー2025 の 23 日目の記事です。他の記事もぜひご覧ください。
ArcGIS Maps SDKs for Game Engines は、米国時間 12/3 に新しいバージョン 2.2 がリリースされました。(Unity / Unreal Engine)
本バージョンでは、3D オブジェクト シーン レイヤーの属性情報を取得できるメソッドが追加されました。この機能は、以前までもArcGIS REST APIs を利用することで実現は可能でした。しかし、オブジェクトから取得した Object ID を頼りにクエリーをする必要がありました。クエリーを行うためには、HTTP リクエストを行い、返ってきた JSON をパースするなどの操作が必要で、実装に手間がかかりました。
しかし、これからはメソッド1つですべての属性情報を取得し、変数から値を取りだしていくだけで属性情報の表示が可能になったのです。属性情報の取得から、活用できるようにそれらを取り出すところまで解説いたしますので、皆様の参考になればと思います。
本稿では、REST API を使った属性情報のクエリーと比較して、どのように取得方法が変わったのか、Unity を使って確認していきましょう。
まずは従来通りの方法、ArcGIS REST APIs でフィーチャの属性情報を取得してみます。前提として、オブジェクトをクリックした際に、マウス カーソルからオブジェクトまで Ray を飛ばしています。
Ray がレイヤーに当たったとき、その衝突を ArcGISRaycastHit クラスに代入します。すると、プロパティの featureId を取得することができます。これはフィーチャに含まれる「OBJECTID」と同じ値なので、これを頼りにリクエスト URL(もしくは JSON)を作成します。
従来までは下記のように、リンクを作成する必要がありました。この例では、OBJECTID が 23316 のオブジェクトのすべての属性情報を JSON 形式でクエリーしようとしています。
その後、HTTP Request を作成し、送信します。上記のリンクで geoJson を指定したため、下の画像のように JSON 形式でレスポンスが返ってきます。
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"id": 23316,
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-71.1045437396496, 42.2616978566384],
[-71.1046313028647, 42.2616979600908],
[-71.1046312134738, 42.2617398672438],
[-71.1045436489872, 42.2617397628817],
[-71.1045437396496, 42.2616978566384]
]
]
},
"properties": {
"OBJECTID": 23316,
"FP_ID": null,
"WARD": null,
"PARCEL": null,
"PID_LONG": null,
"WPD": null,
"LOTSIZE": null,
"BLDG_AREA": null,
"DISTRICT": null,
"STAGE": null,
"ZONE_": null,
"DISTRICT_1": null,
"MAPNO": null,
"ARTICLE": null,
"SUBDISTRIC": null,
"Unique_Code": null,
"FAR": null,
"STRUCT_ID": "232624_890214",
"SOURCE": "ROLTA",
"SOURCETYPE": "ROOFPRINT",
"SOURCEDATE": 20110000,
"MOVED": "N",
"AREA_SQ_FT": 361.98078808,
"TOWN_ID": 35,
"TOWN_ID2": 0,
"TOWN_ID3": 0,
"LOCAL_ID": " ",
"Height": 12,
"BaseHeight": 41,
"HT": 4,
"Scenario": 0,
"Archive": "No"
}
}
]
}
ここから、JSON をパースして、必要な属性情報である properties の内部データを取得します。
これで、属性情報を取得できました。簡単な説明でしたが、非同期処理などを行う必要があるため、実際のコードはもう少し複雑になります。
続いて、新しく実装されたメソッド「IdentifyLayersAsync」、「IdentifyLayerAsync」ではどうなるのか確認してみましょう。例として、複数のレイヤーから属性情報を取得できる IdentifyLayersAsync で解説します。IdentifyLayerAsync はレイヤーを設定してほぼ同様の操作が可能です。
以下のようにメソッドを使用します。
ArcGISFuture future = arcGISMapComponent.View.IdentifyLayersAsync(start, end, maximumResultsPerLayer);
//引数の start と end は ArcGISPoint 型で表された Ray の始点と終点。//maximumResultsPerLayer はレイヤーごとに返されるジオエレメントの数の制限を整数型 で入力します。-1 を入力すると無制限になります。
情報の取得はこれだけでできてしまいました。あとは表示できる形に取り出すだけです。
このメソッドが返すクラスは、ArcGISFuture<ArcGISImmutableCollection<ArcGISIdentifyLayerResult>> という、非同期処理の結果を表現するクラスです。
future = ArcGISFuture.TaskComplete;
上記の状態になった際に、非同期処理が完了したことがわかり、情報を取得することができます。
情報を取得する際は、シンプルな Get() メソッドでコードを書くことができます。
ArcGISImmutableCollection<ArcGISIdentifyLayerResult> identifyLayerResult;
identifyLayerResult = future.Get();
クリックしたときに Ray が触れた(情報を取得したい)レイヤーが複数あれば、ArcGISImmutableCollection<ArcGISGeoElement> 型でフィーチャの属性情報を取得するオブジェクトを決定します。(1 つであれば NumberOfTargetLayer に 0 を入力)
ArcGISImmutableCollection<ArcGISGeoElement> elements = identifyLayerResults.At(NumberOfTargetLayer).GeoElements;
// NumberOfTargetLayer は含まれるレイヤーの数より小さい符号なし長整数
ここから、ArcGISDictionary<string,object> 型を取得し、キーを取得します。
ArcGISDictionary<string,object> attributes = elements.At(NumberOfResults).Attributes;
//NumberOfResult は Ray が触れたビルディング シーンのオブジェクトの数
これにより、属性情報を辞書型に格納することができました。あとは、辞書型のキーを抽出して、属性情報にアクセスできます。
ArcGISImmutableArray<string> keys = attributes.Keys;
String value = attributes[keys.At(indexOfKey)].ToString();
// indexOfKey はループ処理で走査中のキー配列(keys)の現在位置を表すインデックス
以上で、ArcGIS Maps SDK for Unity で IdentifyLayersAsync を利用する方法をざっくり解説しました。
手順が多いように感じるかと思いますが、自分でリクエスト URL を作成したり、JSON をパースしたりするなどの操作がないため、特定の手順を踏むだけでデータの取得を行えるようになりました。レイヤーごとにフィーチャの属性情報の構造を認識する必要もありません。
また、明確に ArcGIS REST APIs を使うよりも優れている点があります。こちらのメソッドを使えば、ローカル データや ArcGIS Online 上にフィーチャとしてホストされていないレイヤーからも 属性情報を取り出すことができる点です。例えば、国土交通省が 展開する Project PLATEAU は ArcGIS Online 上にシーン サービスとしてホストされています。この状態だと ArcGIS REST APIs が使えず、フィーチャ サービスとしてホストし直す必要があります。そこで、IdentifyLayersAsync などを使うとシーン サービスから属性情報を取得することができます。
PLATEAU の 属性表示
本稿では、ArcGIS Maps SDKs for Game Engines の新機能を用いて属性情報を取得してみました。
本機能を利用したサンプルが米国Esri から GitHubにて公開されています。(Unity/Unreal Engine)
こちらも併せてご確認いただければと思います。皆さんの環境でもぜひお試しください!
ArcGIS Maps SDKs for Game Engines