一、创作来源
1、cesium的entity绘制圆
2、不使用entity的情况下,使用自定义的primitive来动态绘制圆
3、结合上一篇文章的圆,执行动态圆的更新
二、编写步骤
1、创建绘制线的类
包括构造函数、绘图函数以及销毁函数
import { Viewer, ScreenSpaceEventHandler, ScreenSpaceEventType } from "cesium";
import { pickPosition } from "@/components/MilitaryPlot/utils/PlotUtils";
import CustomPolylinePrimitive from "@/components/entity/CustomPolylinePrimitive";
import CustomCirclePrimitive from "@/components/samples/CustomCirclePrimitive";
export default class DrawCircleTool {/*** 构造函数* @param {Viewer} viewer*/constructor(viewer) {/*** 地球视图* @type {Viewer}* @private*/this._viewer = viewer;/*** 线对象* @type {CustomCirclePrimitive}* @private*/this._primitive = undefined;/*** 事件* @type {ScreenSpaceEventHandler}* @private*/this._handler = undefined;}/*** 绘图*/draw() {}/*** 销毁*/destroy() {if (this._handler) {this._handler.isDestroyed() && this._handler.destroy();this._handler = null;}}
}
2、事件确认
鼠标点击事件、移动事件
/*** 绘图*/draw() {this._handler = new ScreenSpaceEventHandler(this._viewer.canvas);let positions = [];let flag = this;this._handler.setInputAction((event) => {console.log("左键单机事件");}, ScreenSpaceEventType.LEFT_CLICK);this._handler.setInputAction((event) => {console.log("鼠标移动事件");}, ScreenSpaceEventType.MOUSE_MOVE);}
3、点位变动逻辑
=>初始为空的数组
=>点击后当为空时直接push,当有两个点时,结束编辑
=>移动:当只有一个点时直接push,当点位数大于1的时候,先移除后push
4、代码实现
1、屏幕坐标转地球坐标
/*** 获取地图点位* @param {Cartesian2} screenPosition 屏幕坐标* @param {Viewer} viewer 地图* @returns {Cartesian3} 地图三维坐标*/
export const pickPosition = (screenPosition, viewer) => {let ray = viewer.camera.getPickRay(screenPosition);return viewer.scene.globe.pick(ray, viewer.scene);
};
2、鼠标事件代码
/*** 绘图*/draw() {this._handler = new ScreenSpaceEventHandler(this._viewer.canvas);let positions = [];let flag = this;this._handler.setInputAction((event) => {console.log("左键单机事件");let position = pickPosition(event.position, flag._viewer);if (position) {if (positions.length === 0) {positions.push(position);} else {positions.pop();positions.push(position);}}}, ScreenSpaceEventType.LEFT_CLICK);this._handler.setInputAction((event) => {console.log("鼠标移动事件");let position = pickPosition(event.endPosition, flag._viewer);if (position) {if (positions.length === 1) {positions.push(position);} else if (positions.length > 1) {positions.pop();positions.push(position);}}}, ScreenSpaceEventType.MOUSE_MOVE);}
3、渲染线代码
/*** 绘图*/draw() {this._handler = new ScreenSpaceEventHandler(this._viewer.canvas);let positions = [];let flag = this;this._handler.setInputAction((event) => {console.log("左键单机事件");let position = pickPosition(event.position, flag._viewer);if (position) {if (positions.length === 0) {positions.push(position);flag._primitive = new CustomCirclePrimitive({});this._viewer.scene.primitives.add(this._primitive);} else {positions.pop();positions.push(position);flag._primitive.updateProperty({positions: [...positions],complete: false,});this._primitive = undefined;positions = [];}}}, ScreenSpaceEventType.LEFT_CLICK);this._handler.setInputAction((event) => {console.log("鼠标移动事件");let position = pickPosition(event.endPosition, flag._viewer);if (position) {if (positions.length === 1) {positions.push(position);} else if (positions.length > 1) {positions.pop();positions.push(position);}if (flag._primitive) {flag._primitive.updateProperty({positions: [...positions],complete: false,});}}}, ScreenSpaceEventType.MOUSE_MOVE);}
4、测试
let tool = new DrawCircleTool(viewer);
tool.draw();
三、实现效果
四、代码
import { Viewer, ScreenSpaceEventHandler, ScreenSpaceEventType } from "cesium";
import { pickPosition } from "@/components/MilitaryPlot/utils/PlotUtils";
import CustomPolylinePrimitive from "@/components/entity/CustomPolylinePrimitive";
import CustomCirclePrimitive from "@/components/samples/CustomCirclePrimitive";
export default class DrawCircleTool {/*** 构造函数* @param {Viewer} viewer*/constructor(viewer) {/*** 地球视图* @type {Viewer}* @private*/this._viewer = viewer;/*** 线对象* @type {CustomCirclePrimitive}* @private*/this._primitive = undefined;/*** 事件* @type {ScreenSpaceEventHandler}* @private*/this._handler = undefined;}/*** 绘图*/draw() {this._handler = new ScreenSpaceEventHandler(this._viewer.canvas);let positions = [];let flag = this;this._handler.setInputAction((event) => {console.log("左键单机事件");let position = pickPosition(event.position, flag._viewer);if (position) {if (positions.length === 0) {positions.push(position);flag._primitive = new CustomCirclePrimitive({});this._viewer.scene.primitives.add(this._primitive);} else {positions.pop();positions.push(position);flag._primitive.updateProperty({positions: [...positions],complete: false,});this._primitive = undefined;positions = [];}}}, ScreenSpaceEventType.LEFT_CLICK);this._handler.setInputAction((event) => {console.log("鼠标移动事件");let position = pickPosition(event.endPosition, flag._viewer);if (position) {if (positions.length === 1) {positions.push(position);} else if (positions.length > 1) {positions.pop();positions.push(position);}if (flag._primitive) {flag._primitive.updateProperty({positions: [...positions],complete: false,});}}}, ScreenSpaceEventType.MOUSE_MOVE);}/*** 销毁*/destroy() {if (this._handler) {this._handler.isDestroyed() && this._handler.destroy();this._handler = null;}}
}