ArcGIS 3D Advanced
Use this skill for advanced 3D visualization including voxel layers, point clouds, weather, daylight, glTF imports, and custom rendering.
VoxelLayer (Volumetric 3D Data)
VoxelLayer displays 3D volumetric data like atmospheric, oceanographic, or geological data.
Basic VoxelLayer
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);
VoxelLayer with Map Component
<arcgis-scene viewing-mode="local"> <arcgis-zoom slot="top-left"></arcgis-zoom> <arcgis-legend slot="bottom-right"></arcgis-legend> </arcgis-scene>
<script type="module"> import VoxelLayer from "@arcgis/core/layers/VoxelLayer.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: "none" } }); </script>
VoxelLayer Configuration
const voxelLayer = new VoxelLayer({ url: "...", // Variable to display currentVariableId: 0, // Slicing enableDynamicSections: true, // Rendering style renderStyle: "volume", // or "surfaces" // Quality settings qualityFactor: 1.0 });
// Access voxel-specific properties after load await voxelLayer.load(); console.log("Variables:", voxelLayer.variables); console.log("Dimensions:", voxelLayer.dimensions);
Voxel Slicing
// 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 } };
Voxel Isosurface
// Create isosurface at specific value const isosurface = { value: 25, enabled: true, color: [255, 0, 0, 0.7] };
PointCloudLayer (LiDAR Data)
Basic PointCloudLayer
import PointCloudLayer from "@arcgis/core/layers/PointCloudLayer.js";
const pcLayer = new PointCloudLayer({ url: "https://tiles.arcgis.com/tiles/.../SceneServer" });
map.add(pcLayer);
PointCloud Renderers
// 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;
Smart Mapping for PointCloud
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" });
PointCloud Filters
pcLayer.filters = [{ field: "CLASS_CODE", operator: "includes", values: [2, 6] // Ground and Building only }];
// Remove filters pcLayer.filters = [];
Weather Effects
Weather Types
// Sunny (default) view.environment.weather = { type: "sunny", cloudCover: 0.2 };
// Cloudy view.environment.weather = { type: "cloudy", cloudCover: 0.6 };
// Rainy view.environment.weather = { type: "rainy", cloudCover: 0.8, precipitation: 0.5 // 0-1 };
// Foggy view.environment.weather = { type: "foggy", fogStrength: 0.5 // 0-1 };
// Snowy view.environment.weather = { type: "snowy", cloudCover: 0.8, precipitation: 0.5, snowCover: "enabled" // or "disabled" };
Weather Component
<arcgis-scene item-id="..."> <arcgis-expand slot="top-right" expanded> <arcgis-weather></arcgis-weather> </arcgis-expand> </arcgis-scene>
Weather Widget (Core API) - Deprecated
DEPRECATED since 4.33: Use the arcgis-weather component shown above instead. For information on widget deprecation, see Esri's move to web components.
// DEPRECATED - Use arcgis-weather component instead import Weather from "@arcgis/core/widgets/Weather.js";
const weatherWidget = new Weather({ view: view });
view.ui.add(weatherWidget, "top-right");
Daylight & Lighting
Setting Date/Time
// Set lighting date and time view.environment.lighting = { date: new Date("2024-06-21T12:00:00"), directShadowsEnabled: true, ambientOcclusionEnabled: true };
// Update time dynamically function setTime(hours) { const date = new Date(view.environment.lighting.date); date.setHours(hours); view.environment.lighting.date = date; }
Daylight Component
<arcgis-scene item-id="..."> <arcgis-expand slot="top-right" expanded> <arcgis-daylight hide-timezone play-speed-multiplier="2"></arcgis-daylight> </arcgis-expand> </arcgis-scene>
<script type="module"> const daylight = document.querySelector("arcgis-daylight");
// Toggle sun position vs virtual lighting daylight.sunlightingDisabled = false; // Use sun position daylight.sunlightingDisabled = true; // Use virtual light </script>
Daylight Widget (Core API)
import Daylight from "@arcgis/core/widgets/Daylight.js";
const daylightWidget = new Daylight({ view: view, playSpeedMultiplier: 2 // Animation speed });
view.ui.add(daylightWidget, "top-right");
Shadow Analysis
// Enable shadows view.environment.lighting.directShadowsEnabled = true;
// Shadow cast analysis import ShadowCastAnalysis from "@arcgis/core/analysis/ShadowCastAnalysis.js";
const shadowAnalysis = new ShadowCastAnalysis(); view.analyses.add(shadowAnalysis);
Importing 3D Models (glTF)
glTF Symbol
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);
Interactive Model Placement
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); } });
IntegratedMeshLayer
import IntegratedMeshLayer from "@arcgis/core/layers/IntegratedMeshLayer.js";
const meshLayer = new IntegratedMeshLayer({ url: "https://tiles.arcgis.com/tiles/.../IntegratedMeshServer" });
map.add(meshLayer);
DimensionLayer (Length Dimensioning)
Basic 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";
// 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 Length Dimensions
// 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);
Interactive Dimension Placement
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();
OpenStreetMapLayer (3D Buildings)
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" });
Scene Environment
Ground Configuration
// 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 = "none"; // Allow underground map.ground.opacity = 0.5; // Semi-transparent ground
Scene Quality
view.qualityProfile = "high"; // "low", "medium", "high"
// Custom quality settings view.environment.atmosphereEnabled = true; view.environment.starsEnabled = true; view.environment.lighting.ambientOcclusionEnabled = true;
Background
// 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] };
Scene Performance
Memory Management
// Monitor memory usage view.watch("memoryUsage", (memoryUsage) => { console.log("Memory:", memoryUsage.total, "bytes"); });
// Reduce quality for performance view.qualityProfile = "low";
Level of Detail
// For SceneLayer sceneLayer.lodFactor = 1.0; // 0.5 = lower detail, 2.0 = higher detail
Viewing Modes
// Global mode (default) - spherical Earth view.viewingMode = "global";
// Local mode - flat, for local areas view.viewingMode = "local";
<!-- Local mode for indoor/underground --> <arcgis-scene viewing-mode="local"> </arcgis-scene>
TypeScript Usage
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.
Common Pitfalls
VoxelLayer requires local viewing mode: Use viewing-mode="local" 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: "none" to allow underground viewing