コンテンツにスキップ

レイヤーと Descriptor

navara_three では、3D シーンに表示される要素を「レイヤー」や「Descriptor」として管理します。地図データの描画にはレイヤーを使用します。レイヤーは Source(データの取得元)を参照し、それをどのように描画するかを記述します。一方、3D オブジェクトの配置、ポストプロセッシングエフェクト、照明は Descriptor として追加・制御します。

navara_three には 4 種類の Descriptor があります:

Descriptor の種類説明メソッド
LayerSource の地理データを描画レイヤータイプ("vector", "raster", "terrain", "3d-tiles")と source を指定して addLayer()
Mesh Desc3D メッシュオブジェクトをシーンに追加addMesh()
Effect Descポストプロセッシングエフェクトを適用addEffect()
Light Descシーンの照明を管理addLight()

レイヤーは、地理データを以下の階層構造で管理します:

Layer

FeatureSet

Feature

Batch

  • Layer: addLayer() で追加されるトップレベルのコンテナ。各レイヤーは一意の LayerId を持ちます。
  • FeatureSet: レイヤー内の描画単位。フィーチャーイベント(featureCreatedfeatureUpdated など)はフィーチャーセットごとに発行され、それぞれ FeatureSetId を持ちます。1 つのフィーチャーセットは複数の LOD レベルにまたがる場合があります。
  • Feature: プロパティを持つ概念的な単位。データソースが GIS データの場合、フィーチャーは個々の地理的エンティティ(建物、道路セグメントなど)に対応します。LOD レベルをまたいで特定のフィーチャーを識別するには、プロパティ内の値(id フィールドなど)を使用してください。
  • Batch: 最下位の単位で、実際のジオメトリで構成されます。各バッチは batchId を持ちます。

フィーチャーイベント(featureCreatedfeatureUpdated など)の詳細は Layer Types を参照してください。

レイヤー自身はデータを取得しません。レイヤーは Source を参照します。Source はデータがどこにあり、どのように取得・デコードされるか(URL、ズーム範囲、タイリングスキーム、標高デコーダー)を記述し、レイヤーはどのように描画するか(Material)を記述します。1 つの Source は複数のレイヤーで共有できます。

// 1. Register a source (the data)
const imagery = view.addSource({
type: "raster-tile",
url: "https://example.com/{z}/{x}/{y}.png",
maxZoom: 19,
});
// 2. Add a layer that renders it (the styling)
view.addLayer({ type: "raster", source: imagery, raster: { opacity: 0.8 } });

Source の種類については About Source を、レイヤーの種類と描画オプションについては レイヤーの種類 を参照してください。

レイヤーと他の Descriptor の違い

Section titled “レイヤーと他の Descriptor の違い”

レイヤーは外部の地理データを描画するため、メッシュ・エフェクト・ライトの Descriptor とは扱いが異なります。

レイヤーは、GeoJSON、ベクタタイル、ラスタ画像、地形、3D Tiles などの Source を描画します。

特徴:

  • type にはレイヤータイプを指定("vector", "raster", "terrain", "3d-tiles"
  • source プロパティでデータを参照(Source ハンドルまたはその id
  • レイヤータイプに応じて複数の Material を指定可能
  • 指定できる Material はレイヤータイプによって異なる
// Vector layer example (a geojson / vector-tile source)
const features = view.addSource({
type: "geojson",
data: { type: "FeatureCollection", features: [] },
});
const vectorHandle = view.addLayer({
type: "vector",
source: features,
// A vector layer can take several materials at once
point: { color: 0xff0000, size: 10 },
polyline: { color: 0x00ff00, width: 2 },
polygon: { color: 0x0000ff, opacity: 0.5 },
});
// Terrain layer example (a raster-dem / quantized-mesh source)
const dem = view.addSource({
type: "raster-dem",
url: "https://example.com/dem/{z}/{x}/{y}.png",
maxZoom: 15,
});
const terrainHandle = view.addLayer({
type: "terrain",
source: dem,
terrain: { castShadow: true, receiveShadow: true },
});

メッシュ Descriptor、エフェクト Descriptor、ライト Descriptor は、クライアントサイドで Three.js オブジェクトを直接作成します。

特徴:

  • 種類ごとの専用メソッドを使用:addMesh(), addEffect(), addLight()
  • 1 つの Descriptor につき 1 つの Material(設定オブジェクト)を持つ
  • Material のキー名で Descriptor の種類が決まる
  • 使用前に Descriptor クラスの登録が必要registerMesh, registerEffect, registerLight
import { BoxMeshDesc, FXAAEffectDesc, SunLightDesc } from "@navaramap/three-default-descs";
// Register descriptor classes (required before addMesh/addEffect/addLight)
view.registerMesh("box", BoxMeshDesc);
view.registerEffect("fxaa", FXAAEffectDesc);
view.registerLight("sun", SunLightDesc);
// Mesh descriptor example (BoxMeshDesc)
const boxHandle = view.addMesh<BoxMeshDesc>({
box: {
// Recognized as BoxMeshDesc by the box key
width: 100,
height: 100,
},
});
// Effect descriptor example (FXAAEffectDesc)
const fxaaHandle = view.addEffect<FXAAEffectDesc>({
fxaa: {
// Recognized as FXAAEffectDesc by the fxaa key
},
});
// Light descriptor example (SunLightDesc)
const sunHandle = view.addLight<SunLightDesc>({
sun: {
// Recognized as SunLightDesc by the sun key
intensity: 1.0,
castShadow: true,
},
});

返却されるハンドルクラスの違い

Section titled “返却されるハンドルクラスの違い”

view.addLayer() / view.addMesh() / view.addEffect() / view.addLight() から返されるハンドルクラスは、Descriptor の種類によって異なります:

Descriptor の種類返却されるクラス主な機能
LayerLayerupdate(), delete(), forceUpdate(), フィーチャーイベント
Mesh・Effect・Light DescBaseHandle<T>update(), delete(), visible, ref(基底インスタンスへのアクセス)
const source = view.addSource({
type: "geojson",
url: "https://example.com/data.geojson",
});
const layerHandle = view.addLayer({ type: "vector", source });
// Update by fully overwriting the configuration
layerHandle.update({ type: "vector", source, point: { color: 0x00ff00 } });
// Subscribe to feature events
layerHandle.on("featureCreated", (evaluator) => {
console.log("A feature was created");
});
// Delete the layer
layerHandle.delete();

BaseHandle(Mesh・Effect・Light Desc 用)

Section titled “BaseHandle(Mesh・Effect・Light Desc 用)”
// BoxMeshDesc must be registered
const boxHandle = view.addMesh<BoxMeshDesc>({
box: { width: 100, height: 100, depth: 100 },
});
// Partial update (only the specified properties are changed)
boxHandle.update({ box: { width: 200 } });
// Toggle visibility
boxHandle.visible = false;
// Access the underlying Three.js object
const boxMesh = boxHandle.ref;
// Delete the object
boxHandle.delete();

詳細な API リファレンスは Descriptor Types を参照してください。

観点LayerMesh・Effect・Light Desc
用途Source のデータを描画3D オブジェクト・エフェクト・照明
メソッドレイヤータイプ + sourceaddLayer()addMesh(), addEffect(), addLight()
事前登録不要必要(registerMesh / registerEffect / registerLight
Material 数レイヤータイプに応じて複数可1 Descriptor 1 Material
ハンドルクラスLayerBaseHandle<T>
更新方法完全な設定オブジェクトで上書き部分的な更新が可能