ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Cesium PolygonGeometry 添加面完整知识点 TS 代码

2026/8/6 9:31:57 拓冰建站 浏览量
Cesium PolygonGeometry 添加面完整知识点  TS 代码

PolygonGeometry+Primitive+PerInstanceColorAppearance专门渲染MULTIPOLYGON Z 带逐点高程三维空间面(当前项目当前使用) 区分:

  • PolygonGeometry:三维空间面,支持perPositionHeight:true,每个顶点独立 Z 高程 ✅
  • GroundPolygonGeometry:贴地面,丢弃顶点高程,强制贴地形,不能用在 MultiPolygon‑Z 数据

一、核心 API 说明

PolygonGeometry 参数

const fillGeo = new Cesium.PolygonGeometry({ polygonHierarchy: hierarchy, // 多边形层级:外环 + 内环(洞) perPositionHeight: true, // ✅开启逐点高程,MULTIPOLYGON‑Z必须打开 vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT });
  • polygonHierarchyPolygonHierarchy(外环Cartesian3[], 内环洞数组),支持挖洞
  • perPositionHeight:true:每个顶点使用自身 Cartesian3 的高度,形成起伏三维面
  • vertexFormat:使用PerInstanceColorAppearance必须配套这个顶点格式

GeometryInstance(实现每个面不同颜色)

new Cesium.GeometryInstance({ geometry: fillGeo, id: item.id, //拾取ID attributes: { // 每个实例独立颜色 color: Cesium.ColorGeometryInstanceAttribute.fromColor(fillColor) } })

Primitive + PerInstanceColorAppearance

const prim = new Cesium.Primitive({ geometryInstances: instances, appearance: new Cesium.PerInstanceColorAppearance({ translucent: true, //支持透明度 closed: true //几何体闭合 }), asynchronous: true });

⚠️重要限制

  1. PerInstanceColorAppearance不支持 depthFailAppearance,面被地形埋住直接看不见,不能切换地下材质
  2. 如果需要被遮挡也可见:prim.depthTestEnabled = false;关闭深度测试(会浮在最上层,牺牲三维真实感)
  3. 依靠attributes.color,实现同一个 Primitive 里面多个面各自不同颜色。
属性说明
geometryInstancesGeometryInstance 数组,一个面 = 一个实例
appearancePerInstanceColorAppearance,支持实例独立颜色
asynchronoustrue 异步构建几何体,大数据不阻塞页面
prim.depthTestEnabledtrue 开启深度测试;false 关闭,永远显示在顶层

二、基础完整示例(单一个三维面,带洞)

// 1.外环顶点,带高程Z const outerRing = [ Cesium.Cartesian3.fromDegrees(102.48, 24.70, 1600), Cesium.Cartesian3.fromDegrees(102.49, 24.71, 1620), Cesium.Cartesian3.fromDegrees(102.50, 24.70, 1580), Cesium.Cartesian3.fromDegrees(102.48, 24.70, 1600), // 闭合,首尾相同 ]; // 2.内环(挖洞,可选) const holeRing = [ Cesium.Cartesian3.fromDegrees(102.485, 24.703, 1605), Cesium.Cartesian3.fromDegrees(102.488, 24.706, 1610), Cesium.Cartesian3.fromDegrees(102.486, 24.702, 1602), Cesium.Cartesian3.fromDegrees(102.485, 24.703, 1605), ]; // 3.构建层级,外环 + 多个内环洞 const hierarchy = new Cesium.PolygonHierarchy(outerRing, [ new Cesium.PolygonHierarchy(holeRing) ]); // 4.生成几何体,开启逐点高程 const polygonGeo = new Cesium.PolygonGeometry({ polygonHierarchy: hierarchy, perPositionHeight: true, vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }); // 5.包装实例,设置本面颜色 const instance = new Cesium.GeometryInstance({ geometry: polygonGeo, id: "poly_001", attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE.withAlpha(0.35)) } }); // 6.创建Primitive const prim = new Cesium.Primitive({ geometryInstances: instance, appearance: new Cesium.PerInstanceColorAppearance({ translucent: true, closed: true }), asynchronous: true }); // 如果需要被地形遮挡也可见,打开下面 // prim.depthTestEnabled = false; this.viewer.scene.primitives.add(prim);

三、批量渲染(多面,你项目 MULTIPOLYGON Z 逻辑)

const tempFillInstances: Cesium.GeometryInstance[] = []; // wktGeo.coordinates MULTIPOLYGON‑Z结构 wktGeo.coordinates.forEach((polygonParts: number[][][]) => { if (!Array.isArray(polygonParts) || polygonParts.length === 0) return; // polygonParts[0] = 外环;polygonParts[1...] = 内环洞 const outerRingCoord = polygonParts[0]; if (!Array.isArray(outerRingCoord) || outerRingCoord.length < 3) return; //外环转Cartesian3 const outerPositions = outerRingCoord.map(([lon, lat, h]) => Cesium.Cartesian3.fromDegrees(lon, lat, h ?? 0) ); //处理挖洞内环 const holes: Cesium.PolygonHierarchy[] = []; for (let i = 1; i < polygonParts.length; i++) { const innerCoord = polygonParts[i]; if (!Array.isArray(innerCoord) || innerCoord.length < 3) continue; const innerPositions = innerCoord.map(([lon, lat, h]) => Cesium.Cartesian3.fromDegrees(lon, lat, h ?? 0) ); holes.push(new Cesium.PolygonHierarchy(innerPositions)); } const hierarchy = new Cesium.PolygonHierarchy(outerPositions, holes); const fillGeo = new Cesium.PolygonGeometry({ polygonHierarchy: hierarchy, perPositionHeight: true, vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT }); const fillColor = Cesium.Color.fromCssColorString(colorStr).withAlpha(0.35); tempFillInstances.push(new Cesium.GeometryInstance({ geometry: fillGeo, id: item.id, attributes: { color: Cesium.ColorGeometryInstanceAttribute.fromColor(fillColor) } })); }); // 渲染Primitive if(tempFillInstances.length > 0){ const prim = new Cesium.Primitive({ geometryInstances: tempFillInstances, appearance: new Cesium.PerInstanceColorAppearance({ translucent: true, closed: true }), asynchronous: true }); // prim.depthTestEnabled = false; //需要强制可见打开 this.viewer.scene.primitives.add(prim); this.polygonPrimitiveMap.set(`fill_${Math.random()}`, prim); }

四、拾取点击


const handler = new Cesium.ScreenSpaceEventHandler(this.viewer.canvas); handler.setInputAction((click) => { const pick = this.viewer.scene.pick(click.position); if (Cesium.defined(pick)) { console.log('面要素ID', pick.id); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

五、销毁清除(内存泄漏)

private polygonPrimitiveMap = new Map<string, Cesium.Primitive>(); public clearPolygonPrimitive(){ this.polygonPrimitiveMap.forEach(prim=>{ this.viewer.scene.primitives.remove(prim); }) this.polygonPrimitiveMap.clear(); }

六、重要坑清单

  1. perPositionHeight:true只对 PolygonGeometry 生效;GroundPolygonGeometry 不支持,会丢失 Z 高程。
  2. PerInstanceColorAppearance没有 depthFailAppearance,三维面埋进山体直接看不见,没有地下半透明方案。兜底:prim.depthTestEnabled=false
  3. 多边形顶点最少 3 个;WKT 解析要校验,少于 3 个直接跳过,否则渲染崩溃。
  4. 外环 / 内环建议首尾闭合,即使不闭合 Cesium 内部会自动闭合。
  5. Primitive 一旦创建,不能修改顶点坐标、不能修改单一面颜色;更新数据必须全部销毁重新构建。
  6. 想要每个面不同颜色:必须给每个GeometryInstance设置attributes.color,不能改 appearance 材质。
  7. 透明度依靠withAlpha()PerInstanceColorAppearance构造参数translucent:true必须打开,否则透明度失效。

七、对比总表(线 / 点 / 面)

要素几何体Appearance地下遮挡变色支持独立高程 Z
三维折线PolylineGeometryPolylineMaterialAppearance✅ depthFailAppearance
节点点PointPrimitiveCollection-✅ depthFailColor
三维空间面PolygonGeometryPerInstanceColorAppearance❌无 API,只能关闭 depthTestEnabled
贴地面GroundPolygonGeometryPerInstanceColorAppearance❌丢弃高程

业务选型总结

  1. MultiLineString‑Z 三维线:PolylineGeometry + Primitive + depthFailAppearance
  2. 折线上节点:PointPrimitiveCollection + depthFailColor
  3. MultiPolygon‑Z 带高程面:PolygonGeometry + PerInstanceColorAppearance,地下看不见只能depthTestEnabled=false兜底