Cesium+Turf.js实现缓冲分析

1.效果预览

2.实现工具

1.用cesium的handle进行线绘制。

2.用turf.buffer函数对绘制的线进行缓冲区分析。

3.在地图上绘制缓冲区。

3. 监听鼠标状态获取当前坐标绘制线

1.创建绘制工具类
/*
 * @Descripttion:绘制
 * @version:
 * @Author: zhjs
 * @Date: 2023-8-24 09:49:46
 * @LastEditors: zhjs
 * @LastEditTime: 2023-8-24 09:49:46
 */

//=========================绘制============================================== 
import * as Cesium from 'cesium'
class drawGraphic {
    //绘制线(贴地) 
    static drawLine(viewer) {
        var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas)
        var positions = []
        var polyline = null
        var bufferedPolygon = undefined
        const _this = this
        var cartesian = null
        var PolyLinePrimitive = (function () {
          function _(positions) {
            this.options = {
              name: '直线',
              polyline: {
                show: true,
                positions: [],
                material: Cesium.Color.CHARTREUSE,
                width: 5,
                clampToGround: true
              }
            }
            this.positions = positions
            this._init()
          }

          _.prototype._init = function () {
            var _self = this
            var _update = function () {
              return _self.positions
            }
            //实时更新polyline.positions
            this.options.polyline.positions = new Cesium.CallbackProperty(
              _update,
              false
            )
            var addedEntity = viewer.entities.add(this.options)
          }
          return _
        })()
        // 监听鼠标移动事件
        handler.setInputAction(function (movement) {
          let ray = viewer.camera.getPickRay(movement.endPosition)
          cartesian = viewer.scene.globe.pick(ray, viewer.scene)
          if (!Cesium.defined(cartesian))
            //跳出地球时异常
            return

          if (positions.length > 1) {
            if (!Cesium.defined(polyline)) {
              polyline = new PolyLinePrimitive(positions)
              console.log(polyline)
            } else {
              positions.pop()
              positions.push(cartesian)
            }
          }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
        handler.setInputAction(function (movement) {
          let ray = viewer.camera.getPickRay(movement.position)
          cartesian = viewer.scene.globe.pick(ray, viewer.scene)
          if (!Cesium.defined(cartesian))
            //跳出地球时异常
            return
          if (positions.length == 0) {
            positions.push(cartesian.clone())
          }
          positions.push(cartesian)
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
        // 监听鼠标右键点击事件
        handler.setInputAction(function (movement) {
          handler.destroy() //关闭事件句柄
          handler = undefined
          positions.pop() //最后一个点无效
          if (positions.length == 1)
            viewer.entities.remove(floatingPoint)
            
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
        
        return positions
    }
    
}
export default drawGraphic;
2.调用工具类(别忘了代码中定义的全局变量)
import drawGraphic from '@/utils/cesiumPluginsExtends/libs/drawLine'
this.positions = drawGraphic.drawLine(this.c_viewer)
3.绘制效果

在这里插入图片描述

4.缓冲区分析

1.解析返回的positions数据,因为返回的数据是数组类型,且每个节点都是笛卡尔坐标,我们可以将笛卡尔坐标转成弧度坐标,再将弧度坐标转换为经纬度。
import * as Cesium from 'cesium'
import { initCesium } from '@/utils/cesiumPluginsExtends/index'
import * as turf from '@turf/turf'
 this.positions.forEach(item => {
          const cartographic = Cesium.Cartographic.fromCartesian(item);
          const longitude = Cesium.Math.toDegrees(cartographic.longitude);
          const latitude = Cesium.Math.toDegrees(cartographic.latitude);
          const altitude = cartographic.height;
          this.newPositions.push([longitude, latitude, altitude])
        });
        console.log(this.newPositions);
        // 将Cesium的线转换为GeoJSON格式
        //const lineGeoJson = this.toHeightJson(this.positions)
        const lineGeoJson = turf.lineString(this.newPositions)
        console.log(lineGeoJson)
        // 缓冲距离(单位:米)
        const bufferDistance = this.formInline.distance

        // 使用Turf库的缓冲函数进行线的缓冲
        const bufferedLine = turf.buffer(lineGeoJson, bufferDistance, {
          units: 'meters'
        })
2.将缓冲后的面再绘制到viewer中,因为cesium绘制面需要的坐标数据是这种格式。

在这里插入图片描述
而我使用turf.buffer获取的数据是这种格式
在这里插入图片描述
需要再次转换一下

var res = []
bufferedLine.geometry.coordinates[0].forEach((element) => {
     res.push(element[0], element[1])
   })
console.log(res)

完整代码(记得检查一下this和_this,viewer和c_viewer)

aaa(){
        this.positions.forEach(item => {
          const cartographic = Cesium.Cartographic.fromCartesian(item);
          const longitude = Cesium.Math.toDegrees(cartographic.longitude);
          const latitude = Cesium.Math.toDegrees(cartographic.latitude);
          const altitude = cartographic.height;
          this.newPositions.push([longitude, latitude, altitude])
        });
        console.log(this.newPositions);
        // 将Cesium的线转换为GeoJSON格式
        //const lineGeoJson = this.toHeightJson(this.positions)
        const lineGeoJson = turf.lineString(this.newPositions)
        console.log(lineGeoJson)
        // 缓冲距离(单位:米)
        const bufferDistance = this.formInline.distance

        // 使用Turf库的缓冲函数进行线的缓冲
        const bufferedLine = turf.buffer(lineGeoJson, bufferDistance, {
          units: 'meters'
        })
        console.log(bufferedLine)
        var res = []
        bufferedLine.geometry.coordinates[0].forEach((element) => {
          res.push(element[0], element[1])
        })
        console.log(res)
        // 通过缓冲后的GeoJSON生成Cesium的多边形
        this.polygonEntity = this.c_viewer.entities.add({
          polygon: {
            hierarchy: Cesium.Cartesian3.fromDegreesArray(
              // bufferedLine.geometry.coordinates[0]
              res
            ),
            material: Cesium.Color.RED.withAlpha(0.5)
          }
        })
        //console.log(polygonEntity)
        this.c_viewer.flyTo(polygonEntity)


      },
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值