Projektbild
ESRIIn Japan,Yamaha Motor Co., Ltd.undDaikin Industries, Ltd.haben gemeinsam eine Forschungskooperation zur digitalen Darstellung von Wäldern durchgeführt, und im Rahmen dessenArcGIS Maps SDK for Unity (im Folgenden,ArcGIS SDK) wurde verwendet für die Entwicklung der Unity App. Kürzlich wurde diesesProjektauf dem GitHub unseres Unternehmens veröffentlicht.
In diesem Artikel stellen wir vor, wie in der Unity App spezifische Funktionen des ArcGIS SDK genutzt werden und zeigen auch die Implementierungsmethoden.
Für Informationen zur Nutzung der App siehe bitte das GitHub README.
Wie genau wird das ArcGIS SDK eingesetzt?
In diesem Projekt wird das ArcGIS SDK hauptsächlich für drei Funktionen verwendet. Diese sind: ① Anzeige der Basiskarte, ② Einlesen von Paketdateien und ③ Verwaltung von Objektpositionen. Wir erklären sie der Reihe nach.
1. Anzeige der Basiskarte
Die Anzeige der Basiskarte ist eine grundlegende Funktion in GIS. Natürlich wird sie auch im ArcGIS SDK verwendet. In dieser Anwendung wird die Map Creator UI des ArcGIS SDK genutzt, um die Basiskarte zu erzeugen. Mit dieser Map Creator UI können auch Layer verwaltet werden, die auf ArcGIS Online gehostet werden. Im Projekt wird als Umgebungssimulation das Project PLATEAU , ein 3D-Stadtmodell von Seiryo City, angezeigt.
Map Creator UI
Außerdem verwenden wir diesmal zusätzlich eine weitere Karte als Mini-Map, um anschaulich zu zeigen, wo sich im weiten Waldgebiet etwas befindet: eine weitere Karte als Mini-Map.
2. Einlesen von Paketdateien
Im Projekt werden automatisch Dateien mit den Erweiterungen ".tpkx" oder ".slpk" aus dem StreamingAssets-Ordner eingelesen..tpkx.slpk.tpkx bezeichnet den Typ des Pakets, und im Projekt wird vorausgesetzt, dass es sich um Geländehöhendaten handelt.Paket. Außerdem steht bei .slpk .slpk für einen Szenenlayer-Typ, und im Projekt wird vorausgesetzt, dass es sich um ein 3D-Objektszenenlayer-Format handelt.
3D Objektszenenlayer.
StreamingAssets-Ordner
Diese Dateien werden mit dem Skript "LoadPackage" innerhalb des Spiels eingelesen.LoadPackage
Zum Beispiel bei Höhendaten: Wenn keine Datei im Ordner gefunden wird, werden Höhendaten vom Terrain 3D Dienst von ArcGIS Online bezogen und eingelesen.ArcGIS Online Terrain 3D .
if(tpkxFiles.Length > 0)
{
for (int i = 0; i < tpkxFiles.Length; i++)
{
string elevationPath = tpkxFiles[i];
mapComponent.Map.Elevation = new ArcGISMapElevation(new ArcGISImageElevationSource(elevationPath, i.ToString(), ""))
{
ExaggerationFactor = elevEx
};
}
}
else
{
string elevationPath = "https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer";
mapComponent.Map.Elevation = new ArcGISMapElevation(new ArcGISImageElevationSource(elevationPath, "Terrein 3D", ""))
{
ExaggerationFactor = elevEx
};
}
また、本プロジェクトでは林道を 3D オブジェクト シーン レイヤーとして読み込んでいます。ファイルは tex_elev008_w07.slpk として StreamingAssets フォルダー内に格納されています。下記コードの「ArcGISLayerType」を別の値に書き換えるとその他のレイヤー タイプを読み込むことができるようになります。ぜひ、お手持ちのデータでお試しください。
if (slpkFiles.Length > 0)
{
for (int i = 0; i < slpkFiles.Length; i++)
{
string sceneLayerPath = slpkFiles[i];
ArcGISLayer layer = new ArcGISLayer(sceneLayerPath, ArcGISLayerType.ArcGIS3DObjectSceneLayer, "");
mapComponent.Map.Layers.Add(layer);
}
}
3. オブジェクトの座標管理
本プロジェクトではサンプル データとして、1000 本以上の立木を表示しています。これらの座標は StreamingAssets フォルダー内に格納されている CSV のデータを参照していますが、立木のオブジェクトすべてに ArcGIS Location Component というコンポーネントがアタッチされています。
ArcGIS Location Component
しかし、上の画像をよく見ると緯度と経度(Latitude, Longitude)に関しては値が入力されていますが、高度(Altitude)は値が入力されていません。どのように高度を設定しているのでしょうか。
実は高度はコンポーネントの一番下にある Surface Placement で設定しています。この項目は、オブジェクトの高さを地形に対してどのように配置するかを決定する項目です。今回は没入感重視のため「On the Ground」で強制的に地表面にフィットさせています。この他にも、Altitude の値に準拠する「Absolute Height」と地表面との差分を設定できる「Relative to Ground」があります。
この設定は、TreeGenerator というスクリプトで行っています。この他にもオブジェクトの角度も同様に設定できるため、木によってばらつきを出すためにランダムな回転でバリエーションを出しています。
// LocationComponent 関連
var treeLocation = tree.GetComponent<ArcGISLocationComponent>();
if (treeLocation == null) treeLocation = Undo.AddComponent<ArcGISLocationComponent>(tree);
treeLocation.SurfacePlacementMode = ArcGISSurfacePlacementMode.OnTheGround;
treeLocation.Position = new ArcGISPoint(feature.POINT_X, feature.POINT_Y, 0, ArcGISSpatialReference.WGS84());
float randomizeAngle = UnityEngine.Random.Range(0.0f, 359.9f);
treeLocation.Rotation = new ArcGISRotation(randomizeAngle, 90, 0);
Tips: キャラクターなどの移動体に「On the Ground」を設定すると、地表面に押さえつけられるようになるため、アニメーションなどと干渉し意図しない挙動を起こすことがあります。その場合は、「Absolute Height」の設定がおすすめです。
最後に
本プロジェクトでは森林管理のデジタルツイン化を目指し、ArcGIS SDK を用いて雑木林の再現を行いました。ArcGIS と森林管理や林業をつなぎ、ゲームエンジンの可能性を広げることができたら嬉しく思います。
植林や樹木の範囲指定など、まだまだ実装の余地があると私は思っています。本プロジェクトは GitHub で公開していますので、ご興味のある方はプロジェクトをクローンして、自由にご活用ください。
参考リンク