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
});
polygonHierarchy:PolygonHierarchy(外环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
});
⚠️重要限制
PerInstanceColorAppearance不支持 depthFailAppearance,面被地形埋住直接看不见,不能切换地下材质- 如果需要被遮挡也可见:
prim.depthTestEnabled = false;关闭深度测试(会浮在最上层,牺牲三维真实感) - 依靠
attributes.color,实现同一个 Primitive 里面多个面各自不同颜色。
| 属性 | 说明 |
|---|---|
| geometryInstances | GeometryInstance 数组,一个面 = 一个实例 |
| appearance | PerInstanceColorAppearance,支持实例独立颜色 |
| asynchronous | true 异步构建几何体,大数据不阻塞页面 |
| prim.depthTestEnabled | true 开启深度测试;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();
}
六、重要坑清单
perPositionHeight:true只对 PolygonGeometry 生效;GroundPolygonGeometry 不支持,会丢失 Z 高程。PerInstanceColorAppearance没有 depthFailAppearance,三维面埋进山体直接看不见,没有地下半透明方案。兜底:prim.depthTestEnabled=false。- 多边形顶点最少 3 个;WKT 解析要校验,少于 3 个直接跳过,否则渲染崩溃。
- 外环 / 内环建议首尾闭合,即使不闭合 Cesium 内部会自动闭合。
- Primitive 一旦创建,不能修改顶点坐标、不能修改单一面颜色;更新数据必须全部销毁重新构建。
- 想要每个面不同颜色:必须给每个
GeometryInstance设置attributes.color,不能改 appearance 材质。 - 透明度依靠
withAlpha();PerInstanceColorAppearance构造参数translucent:true必须打开,否则透明度失效。
七、对比总表(线 / 点 / 面)
| 要素 | 几何体 | Appearance | 地下遮挡变色 | 支持独立高程 Z |
|---|---|---|---|---|
| 三维折线 | PolylineGeometry | PolylineMaterialAppearance | ✅ depthFailAppearance | ✅ |
| 节点点 | PointPrimitiveCollection | - | ✅ depthFailColor | ✅ |
| 三维空间面 | PolygonGeometry | PerInstanceColorAppearance | ❌无 API,只能关闭 depthTestEnabled | ✅ |
| 贴地面 | GroundPolygonGeometry | PerInstanceColorAppearance | ❌ | ❌丢弃高程 |
业务选型总结
- MultiLineString‑Z 三维线:
PolylineGeometry + Primitive + depthFailAppearance - 折线上节点:
PointPrimitiveCollection + depthFailColor - MultiPolygon‑Z 带高程面:
PolygonGeometry + PerInstanceColorAppearance,地下看不见只能depthTestEnabled=false兜底


被折叠的 条评论
为什么被折叠?



