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)
},