mcpField
A
arcgis-3d-layers

arcgis-3d-layers

github.com/saschabrunnerch开发2351 次安装29 周前更新
代码仓库

关于 arcgis-3d-layers

供开发者构建 ArcGIS SceneView 应用的 3D 图层参考技能,涵盖图层类型、可视化与查询、测量、glTF 导入及常见配置限制。

主要功能

  1. 01配置场景、网格、点云和体素图层
  2. 02设置点云样式与筛选条件
  3. 03查询和编辑 SceneLayer 要素
  4. 04显示体素切片与等值面
  5. 05添加尺寸标注和 glTF 模型

适用场景

  1. 01在 3D 场景中显示建筑或实景网格
  2. 02浏览 LiDAR 或体积数据集
  3. 03测量、查询或编辑场景内容
  4. 04在 SceneView 中放置 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);
带地图组件的 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 关键属性
属性类型描述
currentVariableIdnumber要显示的活动变量
currentStyleIdnumber活动样式/渲染
enableDynamicSectionsboolean允许交互式切片
volumeDisplayQualitystring"low"、"medium"、"high"
variablesVoxelVariable[]可用数据变量
stylesVoxelTransferFunctionStyle[]渲染样式
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>

常见注意事项

  1. 仅限 SceneView:SceneLayer、IntegratedMeshLayer、PointCloudLayer 和 VoxelLayer 只能在 SceneView 中使用,不能在 MapView 中使用。

  2. VoxelLayer 需要本地查看模式:使用 viewing-mode="local" 可获得最佳体素数据查看效果。

  3. PointCloud 渲染器字段:常见字段包括 RGB、CLASS_CODE、ELEVATION、INTENSITY。

  4. glTF 模型比例:可能需要显式设置 width/height/depth,才能让模型在场景中正确显示。

  5. 地面导航限制:设置 navigationConstraint: { type: "none" } 以允许地下查看。

  6. 访问元数据前先加载:访问 variables、styles、allSublayers 或类似属性前,务必先执行 await layer.load()。

参考示例

  • layers-scenelayer — SceneLayer 基础用法
  • layers-scenelayer-edges — 边缘渲染样式
  • layers-pointcloud — 使用渲染器的 PointCloudLayer
  • layers-pointcloud-filters — 筛选点云数据
  • layers-voxel — VoxelLayer 基础用法
  • layers-voxel-isosurface — 等值面可视化
  • layers-voxel-dynamic-sections — 体素切片
  • layers-integratedmeshlayer — IntegratedMeshLayer
  • layers-dimension — DimensionLayer 测量
  • import-gltf — 导入 glTF 3D 模型

相关技能

  • arcgis-scene-environment — 光照、天气、大气、阴影
  • arcgis-custom-rendering — 使用 RenderNode 进行自定义 3D WebGL 渲染
  • arcgis-visualization — 渲染器和符号系统
  • arcgis-layers — 常见图层模式和配置

评论

支持 Markdown