cesium创建多段线缓冲区

发布时间 2023-07-21 22:32:37作者: MARSHBAN

两种方式:
一、前端直接引入turf库,使用turf.buffer方法创建。

二、后端数据库引入postgis,使用ST_Buffer方法创建,前端调用对应接口的方式获取。

下面分别给出两种方式的关键步骤,代码没有做整理,这里只是提供一下思路:

turf库创建

activeShapePoints数组里存的是鼠标拾取的多段线节点坐标,格式如下:

[
    {
        "x": -2604190.0220998726,
        "y": 4743916.5281634405,
        "z": 3364194.6405565036
    },
    {
        "x": -2604565.6748349112,
        "y": 4743962.48447861,
        "z": 3363841.3883513794
    },
    {
        "x": -2604935.5529875434,
        "y": 4743858.811577148,
        "z": 3363702.1196498023
    }
]
//世界坐标转化为经纬度
let ellipsoid = this.viewer.scene.globe.ellipsoid;
let cartographics = this.activeShapePoints.map((worldCoord) => {
    return ellipsoid.cartesianToCartographic(worldCoord);
})
let points = cartographics.map((cartographic) => {
    let longitude = Cesium.Math.toDegrees(cartographic.longitude);
    let latitude = Cesium.Math.toDegrees(cartographic.latitude);
    return [longitude, latitude];
})
//由turf库生成缓冲区(坐标)
let polylineF = turf.lineString(points);//Creates a LineString Feature from an Array of Positions.
let buffered = turf.buffer(polylineF, this.bufferDistance, { units: 'meters' });//缓冲区边界坐标,这是创建缓冲区面的关键
let coordinates = buffered.geometry.coordinates;
points = coordinates[0];
let degreesArray = this.pointsToDegreesArray(points);
this.addBufferPolyogn(Cesium.Cartesian3.fromDegreesArray(degreesArray));

绘制缓冲区面的函数addBufferPolyogn:

MapControl.addBufferPolyogn = function (positions) {
    console.log("turf缓冲区坐标:",positions);
    this.viewer.entities.add({
        polygon: {
            hierarchy: new Cesium.PolygonHierarchy(positions),
            material: Cesium.Color.RED.withAlpha(0.6),
            classificationType: Cesium.ClassificationType.BOTH,
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 15000),
        },
    });
}

postgis创建

data数组存的就是上面的activeShapePoints数据。
对坐标数据做一系列格式转换,然后将其作为请求参数向后台发送post请求,后台返回缓冲区面的坐标,然后绘制面。

//先转化为web墨卡托投影坐标
      let webMercatorData = CoordTransform.worldCoord_to_webMercator(data);
      //数据格式化
      let combineString = "";
      webMercatorData.forEach((item) => {
        combineString += `${item.x}` + ` ` + `${item.y},`;
      });

      combineString = combineString.slice(0, -1);
      combineString = `LINESTRING(` + combineString + `)`;
      //   console.log("combineString",combineString);
      //传入后台的参数
      const params = {
        lineString: combineString,
        bufferDistance: this.bufferDistance,
      };
      PsTimelineService.getBuffer(params).then((response) => {
        if (response) {
          console.log("getBuffer传回的数据:", response);
        }
        //验证postgis创建的缓冲区与turf创建的区别、
        const inputString = response.data[0].buffergeom;
        // 使用正则表达式匹配字符串中的数字
        const regex = /[-+]?\d*\.\d+|\d+/g;
        const matches = inputString.match(regex);

        // 提取数字到对象数组中,每两个为一个对象,键名为 x 和 y
        const resultArray = [];
        for (let i = 0; i < matches.length; i += 2) {
          resultArray.push({
            x: parseFloat(matches[i]),
            y: parseFloat(matches[i + 1]),
          });
        }

        console.log(resultArray);
        const webMercatorProjection = new Cesium.WebMercatorProjection();
        const worldCoordinates = resultArray.map((coordinate) => {
          const cartesian = new Cesium.Cartesian3(
            coordinate.x,
            coordinate.y,
            0
          );
          const cartographic = webMercatorProjection.unproject(cartesian);
          const longitude = Cesium.Math.toDegrees(cartographic.longitude);
          const latitude = Cesium.Math.toDegrees(cartographic.latitude);
          return { longitude, latitude };
        });
        // 将经纬度坐标转换为Cartesian3坐标
        const cartesianCoordinates = worldCoordinates.map((coordinate) => {
          const longitude = coordinate.longitude;
          const latitude = coordinate.latitude;
          const height = 0; // 可以设置高度,如果没有高度信息,可将height设置为0
          return Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
        });

        console.log("转换后的边界坐标postgis:",cartesianCoordinates);

        let bufferArr=cartesianCoordinates.map(item=>{
            return item;
        });
        bufferArr.push(cartesianCoordinates[0]);//最终的缓冲区边界坐标

        MapControl.addBufferPolyogn2(bufferArr);

后台缓冲区创建:

SELECT ST_AsText(ST_Buffer(ST_GeomFromText('LINESTRING(0 0, 1 1, 2 0)'), 5, 'endcap=flat join=round')) AS bufferGeom;

效果:

红色是使用turf库创建的缓冲区,蓝色是postgis创建的缓冲区,对比二者可发现区别不大。