home / skills / saschabrunnerch / arcgis-maps-sdk-js-ai-context / arcgis-3d-advanced

arcgis-3d-advanced skill

/contexts/4.34/skills/arcgis-3d-advanced

npx playbooks add skill saschabrunnerch/arcgis-maps-sdk-js-ai-context --skill arcgis-3d-advanced

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
12.8 KB
---
name: arcgis-3d-advanced
description: Advanced 3D features including VoxelLayer, PointCloudLayer, weather effects, daylight simulation, glTF model imports, and custom WebGL rendering. Use for volumetric data, LiDAR visualization, and immersive 3D experiences.
---

# 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
```javascript
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
```html
<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
```javascript
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
```javascript
// 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
```javascript
// Create isosurface at specific value
const isosurface = {
  value: 25,
  enabled: true,
  color: [255, 0, 0, 0.7]
};
```

## PointCloudLayer (LiDAR Data)

### Basic PointCloudLayer
```javascript
import PointCloudLayer from "@arcgis/core/layers/PointCloudLayer.js";

const pcLayer = new PointCloudLayer({
  url: "https://tiles.arcgis.com/tiles/.../SceneServer"
});

map.add(pcLayer);
```

### PointCloud Renderers

```javascript
// 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
```javascript
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
```javascript
pcLayer.filters = [{
  field: "CLASS_CODE",
  operator: "includes",
  values: [2, 6] // Ground and Building only
}];

// Remove filters
pcLayer.filters = [];
```

## Weather Effects

### Weather Types
```javascript
// 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
```html
<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](https://developers.arcgis.com/javascript/latest/components-transition-plan/).

```javascript
// 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
```javascript
// 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
```html
<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)
```javascript
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
```javascript
// 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
```javascript
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
```javascript
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

```javascript
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
```javascript
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
```javascript
// 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
```javascript
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)

```javascript
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
```javascript
// 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
```javascript
view.qualityProfile = "high"; // "low", "medium", "high"

// Custom quality settings
view.environment.atmosphereEnabled = true;
view.environment.starsEnabled = true;
view.environment.lighting.ambientOcclusionEnabled = true;
```

### Background
```javascript
// 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
```javascript
// Monitor memory usage
view.watch("memoryUsage", (memoryUsage) => {
  console.log("Memory:", memoryUsage.total, "bytes");
});

// Reduce quality for performance
view.qualityProfile = "low";
```

### Level of Detail
```javascript
// For SceneLayer
sceneLayer.lodFactor = 1.0; // 0.5 = lower detail, 2.0 = higher detail
```

## Viewing Modes

```javascript
// Global mode (default) - spherical Earth
view.viewingMode = "global";

// Local mode - flat, for local areas
view.viewingMode = "local";
```

```html
<!-- 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`:

```typescript
// 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](../arcgis-core-maps/SKILL.md) for detailed guidance on autocasting vs explicit classes.

## Common Pitfalls

1. **VoxelLayer requires local viewing mode**: Use `viewing-mode="local"` for best results

2. **PointCloud renderer fields**: Common fields are `RGB`, `CLASS_CODE`, `ELEVATION`, `INTENSITY`

3. **Weather only in SceneView**: Weather effects don't work in MapView

4. **glTF model scale**: Models may need scaling to fit the scene properly

5. **Ground navigation constraint**: Set `navigationConstraint: "none"` to allow underground viewing