From arcgis-maps-sdk-js-ai-context
3D layer types including VoxelLayer, PointCloudLayer, IntegratedMeshLayer, glTF model imports, and 3D analysis components. Use for volumetric data, LiDAR visualization, and immersive 3D experiences.
How this skill is triggered — by the user, by Claude, or both
Slash command
/arcgis-maps-sdk-js-ai-context:arcgis-3d-layersThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill for 3D layer types including voxel layers, point clouds, glTF imports, and 3D analysis components.
Use this skill for 3D layer types including voxel layers, point clouds, glTF imports, and 3D analysis components.
VoxelLayer displays 3D volumetric data like atmospheric, oceanographic, or geological data.
import VoxelLayer from "@arcgis/core/layers/VoxelLayer.js";
const voxelLayer = new VoxelLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer",
visible: true,
popupEnabled: true
});
map.add(voxelLayer);
import Map from "@arcgis/core/Map.js";
import SceneView from "@arcgis/core/views/SceneView.js";
import VoxelLayer from "@arcgis/core/layers/VoxelLayer.js";
const vxlLayer = new VoxelLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer"
});
const map = new Map({
ground: { navigationConstraint: { type: "none" } },
layers: [vxlLayer]
});
const view = new SceneView({
container: "viewDiv",
map: map,
viewingMode: "local" // local mode is best for voxel layers
});
await view.when();
const voxelLayer = new VoxelLayer({
url: "...",
// Variable to display
currentVariableId: 0,
// Slicing
enableDynamicSections: true,
// Rendering mode
renderMode: "volume" // or "surfaces"
});
// Access voxel-specific properties after load
await voxelLayer.load();
console.log("Variables:", voxelLayer.variables);
console.log("Volumes:", voxelLayer.volumes);
// Add dynamic section (slice)
voxelLayer.enableDynamicSections = true;
// Configure slice plane
const slicePlane = {
point: { x: 0, y: 0, z: -500 },
normal: { x: 0, y: 0, z: 1 }
};
// Create isosurface at specific value
const isosurface = {
value: 25,
enabled: true,
color: [255, 0, 0, 0.7]
};
import PointCloudLayer from "@arcgis/core/layers/PointCloudLayer.js";
const pcLayer = new PointCloudLayer({
url: "https://tiles.arcgis.com/tiles/.../SceneServer"
});
map.add(pcLayer);
// RGB (True Color) Renderer
const rgbRenderer = {
type: "point-cloud-rgb",
field: "RGB"
};
// Class (Classification) Renderer
const classRenderer = {
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 Renderer (Stretch)
const elevationRenderer = {
type: "point-cloud-stretch",
field: "ELEVATION",
fieldTransformType: "none",
colorModulation: null,
stops: [
{ value: 0, color: [0, 0, 255] },
{ value: 50, color: [255, 255, 0] },
{ value: 100, color: [255, 0, 0] }
]
};
pcLayer.renderer = rgbRenderer;
import colorRendererCreator from "@arcgis/core/smartMapping/renderers/color.js";
import 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"
});
// Continuous color renderer
const elevResponse = await colorRendererCreator.createPCContinuousRenderer({
layer: pcLayer,
field: "ELEVATION"
});
pcLayer.filters = [{
field: "CLASS_CODE",
mode: "include",
values: [2, 6] // Ground and Building only
}];
// Remove filters
pcLayer.filters = [];
For scene environment settings (atmosphere, lighting, weather, shadows), see arcgis-scene-environment.
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"
},
// Optional: scale and rotate
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"
}
}]
}
});
// Start placing model
sketchVM.create("point");
sketchVM.on("create", (event) => {
if (event.state === "complete") {
// Model placed, allow editing
sketchVM.update(event.graphic);
}
});
import IntegratedMeshLayer from "@arcgis/core/layers/IntegratedMeshLayer.js";
const meshLayer = new IntegratedMeshLayer({
url: "https://tiles.arcgis.com/tiles/.../IntegratedMeshServer"
});
map.add(meshLayer);
import DimensionLayer from "@arcgis/core/layers/DimensionLayer.js";
import DimensionAnalysis from "@arcgis/core/analysis/DimensionAnalysis.js";
import LengthDimension from "@arcgis/core/analysis/LengthDimension.js";
// Create dimension analysis with style
const dimensionAnalysis = new DimensionAnalysis({
style: {
type: "simple",
textBackgroundColor: [0, 0, 0, 0.6],
textColor: "white",
fontSize: 12
}
});
// Create dimension layer
const dimensionLayer = new DimensionLayer({
title: "Dimensions",
source: dimensionAnalysis
});
map.add(dimensionLayer);
// Add a dimension between two points
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, // Rotation in degrees
offset: 10 // Distance from line
});
dimensionLayer.source.dimensions.push(dimension);
const layerView = await view.whenLayerView(dimensionLayer);
// Start interactive placement
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();
import OpenStreetMapLayer from "@arcgis/core/layers/OpenStreetMapLayer.js";
// OSM tiles in 3D SceneView
const osmLayer = new OpenStreetMapLayer();
const map = new Map({
ground: "world-elevation",
layers: [osmLayer]
});
const view = new SceneView({
map: map,
container: "viewDiv"
});
// World elevation
map.ground = "world-elevation";
// Custom elevation layer
import ElevationLayer from "@arcgis/core/layers/ElevationLayer.js";
map.ground = {
layers: [
new ElevationLayer({
url: "https://elevation.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer"
})
]
};
// Underground navigation
map.ground.navigationConstraint = { type: "none" }; // Allow underground
map.ground.opacity = 0.5; // Semi-transparent ground
view.qualityProfile = "high"; // "low", "medium", "high"
// Custom quality settings
view.environment.atmosphereEnabled = true;
view.environment.starsEnabled = true;
view.environment.lighting.ambientOcclusionEnabled = true;
// Solid color background
view.environment.background = {
type: "color",
color: [0, 0, 0, 1]
};
// Transparent background (for screenshots)
view.environment.background = {
type: "color",
color: [0, 0, 0, 0]
};
import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
// Monitor performance
reactiveUtils.watch(
() => view.performanceInfo,
(info) => {
console.log("Quality:", info.quality);
}
);
// Reduce quality for performance
view.qualityProfile = "low";
// Global mode (default) - spherical Earth
// Set at construction time; viewingMode is read-only after view creation
const view = new SceneView({
container: "viewDiv",
map: map,
viewingMode: "global" // spherical Earth
});
// Local mode - flat projection, best for local areas, indoor/underground
const view = new SceneView({
container: "viewDiv",
map: map,
viewingMode: "local",
clippingArea: { // Required for local mode
xmin: -118.5,
ymin: 33.9,
xmax: -118.0,
ymax: 34.2,
spatialReference: { wkid: 4326 }
}
});
3D symbols and configurations use autocasting with type properties. For TypeScript safety, use as const:
// Use 'as const' for type safety
const graphic = new Graphic({
geometry: point,
symbol: {
type: "point-3d",
symbolLayers: [{
type: "object",
resource: { href: "https://example.com/model.glb" },
width: 10,
height: 10
}]
} as const
});
// Weather configuration
view.environment.weather = {
type: "rainy",
cloudCover: 0.8,
precipitation: 0.5
} as const;
Tip: See arcgis-core-maps skill for detailed guidance on autocasting vs explicit classes.
All 3D analysis widgets are Core API classes. Create with new Widget({ view }) and add with view.ui.add(widget, position).
| Widget class | Module | Purpose |
|---|---|---|
BuildingExplorer | widgets/BuildingExplorer.js | Explore BuildingSceneLayer by discipline and floor |
ElevationProfile | widgets/ElevationProfile.js | Generate elevation profiles along a path |
LineOfSight | widgets/LineOfSight.js | Analyze line-of-sight visibility |
ShadowCast | widgets/ShadowCast.js | Simulate shadow casting at different times |
Slice | widgets/Slice.js | Slice through 3D content to reveal interior |
Daylight | widgets/Daylight.js | Control sun position and time of day |
DirectLineMeasurement3D | widgets/DirectLineMeasurement3D.js | Measure direct distance between two 3D points |
AreaMeasurement3D | widgets/AreaMeasurement3D.js | Measure areas in a 3D scene |
import BuildingExplorer from "@arcgis/core/widgets/BuildingExplorer.js";
import ElevationProfile from "@arcgis/core/widgets/ElevationProfile.js";
import LineOfSight from "@arcgis/core/widgets/LineOfSight.js";
import ShadowCast from "@arcgis/core/widgets/ShadowCast.js";
import Slice from "@arcgis/core/widgets/Slice.js";
import Expand from "@arcgis/core/widgets/Expand.js";
// Add BuildingExplorer for a BuildingSceneLayer
const buildingExplorer = new BuildingExplorer({ view, layers: [buildingLayer] });
view.ui.add(buildingExplorer, "top-right");
// Add LineOfSight inside an Expand
const lineOfSight = new LineOfSight({ view });
const expand = new Expand({ view, content: lineOfSight });
view.ui.add(expand, "top-left");
// Add ShadowCast
const shadowCast = new ShadowCast({ view });
view.ui.add(shadowCast, "bottom-left");
// Add Slice widget
const slice = new Slice({ view });
view.ui.add(slice, "top-right");
layers-voxel - Working with VoxelLayer in 3Dweather - Weather effects in SceneViewdaylight - Daylight widget for sun positionimport-gltf - Importing glTF 3D modelslayers-dimension - DimensionLayer for 3D measurementsVoxelLayer requires local viewing mode: Set viewingMode: "local" on the SceneView for best results
PointCloud renderer fields: Common fields are RGB, CLASS_CODE, ELEVATION, INTENSITY
Weather only in SceneView: Weather effects don't work in MapView
glTF model scale: Models may need scaling to fit the scene properly
Ground navigation constraint: Set navigationConstraint: { type: "none" } to allow underground viewing
npx claudepluginhub elowen53/arcgis-maps-sdk-js-ai-context-4.0 --plugin arcgis-maps-sdk-js-ai-contextCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.