Cesium加载大数据量多边形

297 阅读1分钟

加载思路

  • 选择Primitive API,至于为何选择Primitive API在此就不赘述
  • 根据官网API描述,Primitive表示场景中的几何图形,几何图形可以来自单个几何实例,也可以来自实例数组,即使几何图形来自不同的几何类型。 Primitive将几何形状GeometryInstance与外观Appearance组合在一起,粗略地说,几何实例定义了结构和位置,外观定义了视觉特征。
  • 将多个实例合并到一个Primitive中称为批处理,可显著提高静态数据的性能。
  • 因此本文采用以下方式进行加载:将多个几何体实例集合成一个实例数组组成一个Primitive加载

代码实践

const list: number[][] = [];
  let num = 0;
  for (let i = 0; i < 1000; i++) {
    const array = [];
    array.push(
      113.36777 + num,
      22.98309 + num,
      1,
      113.36777 + num,
      22.98389 + num,
      1,
      113.36543 + num,
      22.98389 + num,
      1,
      113.36543 + num,
      22.98309 + num,
      1
    );
    list.push(array);
    num += 0.002
  }
  createMultiPolygon(viewer, {
    coordinates: list,
    heightAboveGround: 10,
    polyHeight: 40,
    color: "#dbd942"
  })
interface polygonOptions {
  // 形成底面的坐标串
  coordinates: number[][];
  // 底面离地面高度
  heightAboveGround?: number;
  // 底面的拉伸高度
  polyHeight?: number;
  // 多边形面的颜色
  color?: string;
  // 多边形轮廓的颜色
  outLineColor?:string
}
// 大数据量的primitive
export const createMultiPolygon = (
  viewer: Cesium.Viewer,
  options: polygonOptions
)=>{
  const {
    coordinates,
    color = "grey",
    heightAboveGround = 0,
    polyHeight = 0,
  } = options;
  let instances: Cesium.GeometryInstance[] = [];
  // 将几何体集合成一个实例再加进去
  for(let i=0;i<(coordinates as number[][]).length;i++){
    instances.push(
      new Cesium.GeometryInstance({
        geometry: new Cesium.PolygonGeometry({
          polygonHierarchy: new Cesium.PolygonHierarchy(
            Cesium.Cartesian3.fromDegreesArrayHeights(coordinates[i] as number[])
          ),
          height: heightAboveGround,
          extrudedHeight: heightAboveGround + polyHeight,
        }),
        attributes: {
          color: Cesium.ColorGeometryInstanceAttribute.fromColor(
            Cesium.Color.fromCssColorString(color)
          ),
        },
      })
    );
  }
  let primitiveInstance=new Cesium.Primitive({
    geometryInstances: instances,
    appearance: new Cesium.PerInstanceColorAppearance({
      flat: true,
      translucent: false, //是否透明
    })
  })
  let primitive;
  if (heightAboveGround === 0 && polyHeight === 0) {
    //贴地面
    primitive = new Cesium.GroundPrimitive(
      primitiveInstance
    );
  } else {
    primitive = new Cesium.Primitive(
      primitiveInstance
    );
  }
  viewer.scene.primitives.add(primitive);
};

image.png

1720426349357.jpg