Open11

PLATEAU SDK for Unityを試してみる

bigdrabigdra

環境

  • Windows11
  • Unity2021.3.8f1
  • PLATEAU SDK for Unity v0.5.1

現時点ではARM系CPUは未対応とのこと

次のリポジトリのReleasesからtarball形式のunitypackageをダウンロード

https://github.com/Synesthesias/PLATEAU-SDK-for-Unity

UnityのPackage Managerの Add package from tarball からインポート

bigdrabigdra

都市データのインポートは「ローカル」と「サーバー」から行うことが可能だが、 現時点ではローカルのみ対応。
都市データはG空間情報センターのPLATEAUポータルサイト からダウンロードする

  • 入力フォルダには、直下にudxフォルダを持つパスを指定する
  • 基準座標系には利用する都市に最も近い地域を選ぶ

↑を選択したら、範囲選択へ

bigdrabigdra

シーンビューに地理院地図が表示された。
ここからインポートするモデルの範囲を選択する。

とりあえず渋谷駅周りを選択した。

bigdrabigdra

インポートする都市情報を選択できる画面が出てきた。

とりあえずデフォルトのまま全部インポート開始。

非同期でインポートされている。

ちなみに、 変換元のファイルはすべてStreamingAssets/.PLATEAU下にコピーされている(Unityからは見えない隠しフォルダ)。

bigdrabigdra

一部ファイルのパースに失敗していたが、建物はすべて変換された。
変換されたオブジェクトのトップにPLATEAUInstancedCityModelコンポーネントがアタッチされており、緯度経度などが確認できる。

bigdrabigdra

都市情報へアクセスするサンプル

タップした建物を都市情報を画面上へ表示するというもの

タップしたときにインポート済みのCityGMLファイルをパースして都市情報を取得している。

bigdrabigdra

Geospatial APIと組み合わせるときに、 これまではPlateauCityGmlSharpでCityGMLからヘッダーに座標を埋め込んだobjに変換して使ってたところを入れ替えたい

bigdrabigdra

Androidで実行時にこの位置情報を使いたいんだけどDllNotFoundException出てる。

using var geoRef = _plateauInstancedCityModelPrefab.GeoReference;
var geoCoord = geoRef.Unproject(new PlateauVector3d(0, 0, 0));
// geoCoord.Latitude で緯度がとれるはず...
Exception: DllNotFoundException: Unable to load DLL 'plateau'. Tried the load the following dynamic libraries: Unable to load dynamic library 'plateau' because of 'Failed to open the requested dynamic library (0x06000000) dlerror() = dlopen failed: library "plateau" not found


PLATEAU.Interop.NativeMethods.plateau_create_geo_reference (System.IntPtr& outGeoReferencePtr, PLATEAU.Interop.PlateauVector3d referencePoint, System.Single unitScale, PLATEAU.Geometries.CoordinateSystem coordinateSystem, System.Int32 zoneId) (at <00000000000000000000000000000000>:0)
PLATEAU.Geometries.GeoReference..ctor (PLATEAU.Interop.PlateauVector3d referencePoint, System.Single unitScale, PLATEAU.Geometries.CoordinateSystem coordinateSystem, System.Int32 zoneID) (at <00000000000000000000000000000000>:0)
PLATEAU.CityInfo.PLATEAUInstancedCityModel.get_GeoReference () (at <00000000000000000000000000000000>:0)
CityExtension.Scripts.Tests.Runtime.PlacePlateauByGeospatialTest.Start () (at <00000000000000000000000000000000>:0)
System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state,

これのことでエディタ専用かな

bigdrabigdra

東京湾海水面は標高0mのこと

Terrain Anchor使わずに通常のアンカーを使うなら、 楕円体高を渡すのでジオイド高だけ渡せばよさそう

楕円体高 = 標高(0) + ジオイド高

bigdrabigdra

https://twitter.com/bigdra50/status/1601207964009787395?s=20&t=kShM_OkSR1UM-0qYuOgLGQ

だいたいこんな処理
まだモデルはインポートしたあとシーンに置きっぱなしなので、 Geospatial Anchorを生成したら親子関係を整理する形
あとでSDKのエクスポート機能を試したら、Prefab状態のモデルを動的に生成するとかやると思う

// PLATEAUInstancedCityModelの位置に書かれていた基準位置をとりあえずベタ書き
var lat = 35.645d;
var lng = 139.695d;
// 高さ(標高)は0m

// 国土地理院のAPIからジオイドをリクエスト
var geoid = await GsiClient.Instance.RequestGeoidHeight(lat, lng);

var anchor = GeospatialManager.Instance.RequestGeospatialAnchor(new GeospatialPose
{
    Latitude = lat,
    Longitude = lng,
    Altitude = geoid.value
}, terrain: false);

// PLATEAUのモデルはシーンに置きっぱなしにしてあるので、親子関係を整理してローカル座標など初期化
if (_plateauInstancedCityModel != null)
{
    _plateauInstancedCityModel.transform.SetParent(anchor.transform);
    _plateauInstancedCityModel.transform.localPosition = Vector3.zero;
    _plateauInstancedCityModel.transform.localRotation = Quaternion.identity;
}