arcgis-3d-layers について
ArcGIS SceneView アプリで 3D レイヤーを扱う開発者向けのリファレンススキルです。レイヤーの種類、可視化と検索、計測、glTF の読み込み、設定時の注意点を扱います。
主な機能
- 01シーン・メッシュ・点群・ボクセルレイヤーの設定
- 02点群データのスタイル設定とフィルター
- 03SceneLayer フィーチャの検索と編集
- 04ボクセルの断面と等値面の表示
- 05寸法レイヤーと glTF モデルの追加
活用シーン
- 013D で建物や実景メッシュを表示
- 02LiDAR またはボリュームデータセットを確認
- 03シーン内容の計測・検索・編集
- 04SceneView に glTF モデルを配置
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ saschabrunnerch/ arcgis-maps-sdk-js-ai-context --skill arcgis-3d-layersインストール後、Claude Code で/arcgis-3d-layersを入力して読み込まれたか確認します。
詳細
ArcGIS 3D レイヤー
SceneView で3D固有のレイヤータイプ(シーンレイヤー、統合メッシュ、点群、ボクセル、ディメンション、glTF モデルのインポート)を使用する場合は、このスキルを利用してください。
インポートパターン
ESM(npm)
import SceneLayer from "@arcgis/core/layers/SceneLayer.js";
import IntegratedMeshLayer from "@arcgis/core/layers/IntegratedMeshLayer.js";
import IntegratedMesh3DTilesLayer from "@arcgis/core/layers/IntegratedMesh3DTilesLayer.js";
import PointCloudLayer from "@arcgis/core/layers/PointCloudLayer.js";
import VoxelLayer from "@arcgis/core/layers/VoxelLayer.js";
import DimensionLayer from "@arcgis/core/layers/DimensionLayer.js";
import BuildingSceneLayer from "@arcgis/core/layers/BuildingSceneLayer.js";
CDN(動的インポート)
const SceneLayer = await $arcgis.import("@arcgis/core/layers/SceneLayer.js");
const PointCloudLayer = await $arcgis.import(
"@arcgis/core/layers/PointCloudLayer.js",
);
const VoxelLayer = await $arcgis.import("@arcgis/core/layers/VoxelLayer.js");
3D固有のすべてのレイヤー(SceneLayer、IntegratedMeshLayer、PointCloudLayer、VoxelLayer)には SceneView が必要です。MapView では動作しません。
SceneLayer
SceneLayer は、シーン サービスの3D建物モデル、オブジェクト、メッシュデータを表示します。
基本的な SceneLayer
const sceneLayer = new SceneLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
popupTemplate: {
title: "{NAME}",
content: "{*}",
},
});
map.add(sceneLayer);
レンダラーを使用した SceneLayer
const sceneLayer = new SceneLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
renderer: {
type: "simple",
symbol: {
type: "mesh-3d",
symbolLayers: [
{
type: "fill",
material: { color: [244, 247, 134] },
edges: {
type: "solid",
color: [50, 50, 50, 0.5],
size: 1,
},
},
],
},
},
});
SceneLayer のエッジ描画
// Solid edges
const solidEdges = {
type: "solid",
color: [50, 50, 50, 0.5],
size: 1,
};
// Sketch edges
const sketchEdges = {
type: "sketch",
color: [50, 50, 50, 0.8],
size: 1.5,
extensionLength: 2,
};
sceneLayer.renderer = {
type: "simple",
symbol: {
type: "mesh-3d",
symbolLayers: [
{
type: "fill",
material: { color: "white" },
edges: sketchEdges,
},
],
},
};
SceneLayer のクエリ
const layerView = await view.whenLayerView(sceneLayer);
// Client-side query
const query = layerView.createQuery();
query.geometry = view.extent;
query.where = "HEIGHT > 100";
const results = await layerView.queryFeatures(query);
// Server-side query
const serverQuery = sceneLayer.createQuery();
serverQuery.where = "CATEGORY = 'Commercial'";
serverQuery.outFields = ["*"];
const serverResults = await sceneLayer.queryFeatures(serverQuery);
編集可能な SceneLayer
// Apply edits to scene layer (if editing enabled)
await sceneLayer.applyEdits({
addFeatures: [newGraphic],
updateFeatures: [updatedGraphic],
deleteFeatures: [{ objectId: 123 }],
});
IntegratedMeshLayer
IntegratedMeshLayer は、写真測量によるメッシュデータ(3Dリアリティキャプチャ)を表示します。
const meshLayer = new IntegratedMeshLayer({
url: "https://tiles.arcgis.com/tiles/.../IntegratedMeshServer",
});
map.add(meshLayer);
IntegratedMesh3DTilesLayer
3D Tiles 1.1 データソースの場合:
const mesh3DTiles = new IntegratedMesh3DTilesLayer({
url: "https://example.com/tileset.json",
});
map.add(mesh3DTiles);
メッシュの変更
// Clip or replace mesh areas
const modification = {
geometry: polygon,
type: "clip", // or "replace", "mask"
};
PointCloudLayer(LiDAR データ)
基本的な PointCloudLayer
const pcLayer = new PointCloudLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
});
map.add(pcLayer);
PointCloud レンダラー
// RGB (True Color) Renderer
pcLayer.renderer = {
type: "point-cloud-rgb",
field: "RGB",
};
// Classification Renderer
pcLayer.renderer = {
type: "point-cloud-unique-value",
field: "CLASS_CODE",
colorUniqueValueInfos: [
{ values: ["2"], label: "Ground", color: [139, 90, 43] },
{ values: ["6"], label: "Building", color: [194, 194, 194] },
{ values: ["5"], label: "High Vegetation", color: [34, 139, 34] },
],
};
// Elevation Stretch Renderer
pcLayer.renderer = {
type: "point-cloud-stretch",
field: "ELEVATION",
stops: [
{ value: 0, color: [0, 0, 255] },
{ value: 50, color: [255, 255, 0] },
{ value: 100, color: [255, 0, 0] },
],
};
PointCloud の密度とサイズ
pcLayer.pointsPerInch = 40; // Density control
PointCloud フィルター
// Include only specific classifications
pcLayer.filters = [
{
field: "CLASS_CODE",
mode: "include",
values: [2, 6], // Ground and Building
},
];
// Remove filters
pcLayer.filters = [];
PointCloud のスマートマッピング
import * as colorRendererCreator from "@arcgis/core/smartMapping/renderers/color.js";
import * as typeRendererCreator from "@arcgis/core/smartMapping/renderers/type.js";
// True color renderer
const rgbResponse = await colorRendererCreator.createPCTrueColorRenderer({
layer: pcLayer,
});
pcLayer.renderer = rgbResponse.renderer;
// Classification renderer
const classResponse = await typeRendererCreator.createPCClassRenderer({
layer: pcLayer,
field: "CLASS_CODE",
});
pcLayer.renderer = classResponse.renderer;
VoxelLayer(体積3Dデータ)
VoxelLayer は、3D体積データ(大気、海洋、地質)を表示します。
基本的な VoxelLayer
const voxelLayer = new VoxelLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
currentVariableId: 0,
});
map.add(voxelLayer);
Map コンポーネントを使用した VoxelLayer
<arcgis-scene viewing-mode="local">
<arcgis-zoom slot="top-left"></arcgis-zoom>
</arcgis-scene>
<script type="module">
import VoxelLayer from "@arcgis/core/layers/VoxelLayer.js";
import Map from "@arcgis/core/Map.js";
const vxlLayer = new VoxelLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
});
const viewElement = document.querySelector("arcgis-scene");
viewElement.map = new Map({
layers: [vxlLayer],
ground: { navigationConstraint: { type: "none" } },
});
</script>
VoxelLayer の設定
const voxelLayer = new VoxelLayer({
url: "...",
currentVariableId: 0,
enableDynamicSections: true,
volumeDisplayQuality: "high", // "low", "medium", "high"
});
await voxelLayer.load();
console.log("Variables:", voxelLayer.variables);
console.log("Styles:", voxelLayer.styles);
Voxel の主なプロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
currentVariableId | number | 表示するアクティブな変数 |
currentStyleId | number | アクティブなスタイル/描画 |
enableDynamicSections | boolean | 対話的なスライスを許可 |
volumeDisplayQuality | string | "low"、"medium"、"high" |
variables | VoxelVariable[] | 使用可能なデータ変数 |
styles | VoxelTransferFunctionStyle[] | 描画スタイル |
Voxel のスライス(動的セクション)
voxelLayer.enableDynamicSections = true;
// Configure slice plane
const slicePlane = {
point: { x: 0, y: 0, z: -500 },
normal: { x: 0, y: 0, z: 1 },
};
Voxel の等値面
// Create isosurface at specific value
const isosurface = {
value: 25,
enabled: true,
color: [255, 0, 0, 0.7],
};
Voxel のカラー停止点
// Customize color stops for variable rendering
// Accessed through voxelLayer.styles
DimensionLayer(3D計測)
基本的な DimensionLayer
import DimensionLayer from "@arcgis/core/layers/DimensionLayer.js";
import DimensionAnalysis from "@arcgis/core/analysis/DimensionAnalysis.js";
import LengthDimension from "@arcgis/core/analysis/LengthDimension.js";
const dimensionAnalysis = new DimensionAnalysis({
style: {
type: "simple",
textBackgroundColor: [0, 0, 0, 0.6],
textColor: "white",
fontSize: 12,
},
});
const dimensionLayer = new DimensionLayer({
title: "Dimensions",
source: dimensionAnalysis,
});
map.add(dimensionLayer);
長さのディメンションを追加
const dimension = new LengthDimension({
startPoint: {
x: -122.4,
y: 37.8,
z: 0,
spatialReference: { wkid: 4326 },
},
endPoint: {
x: -122.5,
y: 37.8,
z: 0,
spatialReference: { wkid: 4326 },
},
orientation: 0,
offset: 10,
});
dimensionLayer.source.dimensions.push(dimension);
対話的なディメンションの配置
const layerView = await view.whenLayerView(dimensionLayer);
const abortController = new AbortController();
async function startPlacement() {
try {
while (!abortController.signal.aborted) {
await layerView.place({ signal: abortController.signal });
}
} catch (error) {
if (!promiseUtils.isAbortError(error)) throw error;
}
}
startPlacement();
// Stop placement
abortController.abort();
BuildingSceneLayer
const buildingLayer = new BuildingSceneLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
});
await buildingLayer.load();
// Access sublayers (disciplines and categories)
buildingLayer.allSublayers.forEach((sublayer) => {
console.log(sublayer.title, sublayer.type);
});
3Dモデルのインポート(glTF)
glTF シンボル
const graphic = new Graphic({
geometry: {
type: "point",
longitude: -122.4,
latitude: 37.8,
z: 0,
},
symbol: {
type: "point-3d",
symbolLayers: [
{
type: "object",
resource: {
href: "https://example.com/model.glb",
},
width: 10,
height: 10,
depth: 10,
heading: 45,
tilt: 0,
roll: 0,
},
],
},
});
graphicsLayer.add(graphic);
対話的なモデルの配置
import SketchViewModel from "@arcgis/core/widgets/Sketch/SketchViewModel.js";
const graphicsLayer = new GraphicsLayer({
elevationInfo: { mode: "on-the-ground" },
});
const sketchVM = new SketchViewModel({
layer: graphicsLayer,
view: view,
pointSymbol: {
type: "point-3d",
symbolLayers: [
{
type: "object",
resource: { href: "https://example.com/model.glb" },
},
],
},
});
sketchVM.create("point");
sketchVM.on("create", (event) => {
if (event.state === "complete") {
sketchVM.update(event.graphic);
}
});
標高情報
// Feature placement relative to ground/scene
layer.elevationInfo = {
mode: "on-the-ground", // Features draped on ground
// mode: "relative-to-ground" // Features offset from ground
// mode: "relative-to-scene" // Features offset from scene
// mode: "absolute-height" // Features at absolute Z values
};
// With offset
layer.elevationInfo = {
mode: "relative-to-ground",
offset: 100,
unit: "meters",
};
// With expression
layer.elevationInfo = {
mode: "relative-to-ground",
featureExpressionInfo: {
expression: "Geometry($feature).z * 10",
},
unit: "meters",
};
3D解析コンポーネント
| コンポーネント | 目的 |
|---|---|
arcgis-building-explorer | 分野や階ごとに建物シーンレイヤーを探索する |
arcgis-elevation-profile | 経路に沿った標高プロファイルを生成する |
arcgis-line-of-sight | 見通しの可視性を解析する |
arcgis-shadow-cast | 時刻ごとの影の投影をシミュレートする |
arcgis-slice | 3Dコンテンツをスライスして内部を表示する |
arcgis-directional-pad | 方向コントロールを使って3Dシーンを操作する |
表示モード
// Global mode (default) - spherical Earth
view.viewingMode = "global";
// Local mode - flat, for local areas
view.viewingMode = "local";
<arcgis-scene viewing-mode="local"> </arcgis-scene>
よくある落とし穴
-
SceneView 専用:SceneLayer、IntegratedMeshLayer、PointCloudLayer、VoxelLayer は SceneView でのみ動作し、MapView では動作しません。
-
VoxelLayer にはローカル表示モードが必要:ボクセルデータを最適に表示するには、
viewing-mode="local"を使用してください。 -
PointCloud のレンダラーのフィールド:一般的なフィールドは
RGB、CLASS_CODE、ELEVATION、INTENSITYです。 -
glTF モデルのスケール:シーンに適切に収めるには、モデルに明示的な
width/height/depthの指定が必要な場合があります。 -
地面のナビゲーション制約:地下を表示できるようにするには、
navigationConstraint: { type: "none" }を設定してください。 -
メタデータにアクセスする前に読み込む:
variables、styles、allSublayersなどのプロパティにアクセスする前に、必ずawait layer.load()を実行してください。
参考サンプル
layers-scenelayer— SceneLayer の基本layers-scenelayer-edges— エッジのレンダリングスタイルlayers-pointcloud— レンダラーを使用した PointCloudLayerlayers-pointcloud-filters— 点群データのフィルタリングlayers-voxel— VoxelLayer の基本layers-voxel-isosurface— 等値面の可視化layers-voxel-dynamic-sections— ボクセルのスライスlayers-integratedmeshlayer— IntegratedMeshLayerlayers-dimension— DimensionLayer による計測import-gltf— glTF 3D モデルのインポート
関連スキル
arcgis-scene-environment— ライティング、天候、大気、影arcgis-custom-rendering— カスタム 3D WebGL レンダリングのための RenderNodearcgis-visualization— レンダラーとシンボル表現arcgis-layers— 一般的なレイヤーのパターンと設定