一、创作来源
1、cesium的entity绘制多边形
2、不使用entity的情况下,使用自定义的primitive来绘制多边形
3、同时使用自定义Primitive来执行属性更新,动态绘制多边形
二、创建自定义Primitive
1、CustomPolygonPrimitive
1、创建类CustomPolygonPrimitive
2、编写构造函数,定义该对象的一些私有属性
3、编写更新属性函数updateProperty
4、编写渲染代码
5、编写销毁代码
export default class CustomPolygonPrimitive {
constructor(options) {
this._props = options;
/**
* 渲染列表
* @type {*[]}
* @private
*/
this._primitiveCollection = [];
this._dynamicPrimitive = undefined;
}
/**
* 更新属性
* @param options
*/
updateProperty(options) {}
/**
* 渲染
* @param frameState
*/
update(frameState) {
this._primitiveCollection.forEach((primitive) => {
primitive && !primitive.isDestroyed() && primitive.update(frameState);
});
if (this._dynamicPrimitive) {
this._dynamicPrimitive.update(frameState);
}
}
/**
* 销毁
*/
destroy() {
this._primitiveCollection.forEach((primitive) => {
primitive && !primitive.isDestroyed() && primitive.destroy();
});
this._primitiveCollection = undefined;
if (this._dynamicPrimitive) {
this._dynamicPrimitive.destroy();
}
this._dynamicPrimitive = undefined;
}
}
2、编写更新属性代码
当点位个数大于1个点的时候,开启对象的渲染
/**
* 更新属性
* @param options
*/
updateProperty(options) {
this._props = {
...this._props,
...options,
};
let positions = this._props.positions;
let complete = this._props.complete;
if (positions.length >= 2) {
let dynamicPrimitive = this._dynamicPrimitive;
if (dynamicPrimitive) {
dynamicPrimitive.destroy();
dynamicPrimitive = null;
this._dynamicPrimitive = null;
}
let primitive = this.initPolygonPrimitive(positions);
if (complete) {
this._primitiveCollection.push(primitive);
} else {
this._dynamicPrimitive = primitive;
}
}
}
3、编写多边形线的渲染代码
当点位数大于2的时候,闭合形成多边形
/**
* 初始化渲染对象
* @param positions
* @return {module:cesium.GroundPolylinePrimitive}
*/
initPolygonPrimitive(positions) {
let instance = new GeometryInstance({
geometry: new GroundPolylineGeometry({
positions: positions,
width: 4,
loop: positions.length > 2,
}),
});
return new GroundPolylinePrimitive({
geometryInstances: instance,
appearance: new PolylineMaterialAppearance({
material: new Material({
fabric: {
type: "Color",
uniforms: {
color: Color.fromCssColorString("#ff0000"),
},
},
}),
}),
asynchronous: false,
});
}
二、创建绘制类
1、创建DrawPolygonTool
1、编写构造函数
2、编写绘制方法调用
3、编写销毁代码
import { Viewer, ScreenSpaceEventHandler, ScreenSpaceEventType } from "cesium";
import { pickPosition } from "@/components/MilitaryPlot/utils/PlotUtils";
import CustomPolylinePrimitive from "@/components/entity/CustomPolylinePrimitive";
export default class DrawPolygonTool {
/**
* 构造函数
* @param {Viewer} viewer
*/
constructor(viewer) {
/**
* 地球视图
* @type {Viewer}
* @private
*/
this._viewer = viewer;
/**
* 线对象
* @type {CustomPolygonPrimitive}
* @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、编写鼠标事件
1、鼠标采点事件
2、鼠标移动事件
3、鼠标右键结束事件
/**
* 绘图
*/
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);
this._handler.setInputAction((event) => {
console.log("鼠标右键单机事件");
}, ScreenSpaceEventType.RIGHT_CLICK);
}
3、获取点位并渲染
=>初始为空的数组
=>点击后当为空时直接push,当有两个点时,先pop后push
=>移动:当只有一个点时直接push,当点位数大于1的时候,先移除后push
=>右键直接结束
/**
* 绘图
*/
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 CustomPolygonPrimitive();
this._viewer.scene.primitives.add(this._primitive);
} else {
let moveP = positions.pop();
positions.push(position, moveP);
}
if (flag._primitive) {
flag._primitive.updateProperty({
positions: [...positions],
complete: false,
});
}
}
}, 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);
this._handler.setInputAction((event) => {
console.log("鼠标右键单机事件");
if (flag._primitive) {
flag._primitive.updateProperty({
positions: [...positions],
complete: false,
});
}
this._primitive = undefined;
positions = [];
}, ScreenSpaceEventType.RIGHT_CLICK);
}
4、调用代码
let tool = new DrawPolygonTool(viewer);
tool.draw();
三、显示效果

四、全部代码
1、CustomPolygonPrimitive
import {
Color,
GeometryInstance,
GroundPolylineGeometry,
GroundPolylinePrimitive,
Material,
PolylineMaterialAppearance,
} from "cesium";
export default class CustomPolygonPrimitive {
constructor(options) {
this._props = options;
/**
* 渲染列表
* @type {*[]}
* @private
*/
this._primitiveCollection = [];
this._dynamicPrimitive = undefined;
}
/**
* 更新属性
* @param options
*/
updateProperty(options) {
this._props = {
...this._props,
...options,
};
let positions = this._props.positions;
let complete = this._props.complete;
if (positions.length >= 2) {
let dynamicPrimitive = this._dynamicPrimitive;
if (dynamicPrimitive) {
dynamicPrimitive.destroy();
dynamicPrimitive = null;
this._dynamicPrimitive = null;
}
let primitive = this.initPolygonPrimitive(positions);
if (complete) {
this._primitiveCollection.push(primitive);
} else {
this._dynamicPrimitive = primitive;
}
}
}
/**
* 初始化渲染对象
* @param positions
* @return {module:cesium.GroundPolylinePrimitive}
*/
initPolygonPrimitive(positions) {
let instance = new GeometryInstance({
geometry: new GroundPolylineGeometry({
positions: positions,
width: 4,
loop: positions.length > 2,
}),
});
return new GroundPolylinePrimitive({
geometryInstances: instance,
appearance: new PolylineMaterialAppearance({
material: new Material({
fabric: {
type: "Color",
uniforms: {
color: Color.fromCssColorString("#ff0000"),
},
},
}),
}),
asynchronous: false,
});
}
/**
* 渲染
* @param frameState
*/
update(frameState) {
this._primitiveCollection.forEach((primitive) => {
primitive && !primitive.isDestroyed() && primitive.update(frameState);
});
if (this._dynamicPrimitive) {
this._dynamicPrimitive.update(frameState);
}
}
/**
* 销毁
*/
destroy() {
this._primitiveCollection.forEach((primitive) => {
primitive && !primitive.isDestroyed() && primitive.destroy();
});
this._primitiveCollection = undefined;
if (this._dynamicPrimitive) {
this._dynamicPrimitive.destroy();
}
this._dynamicPrimitive = undefined;
}
}
2、DrawPolygonTool
import { Viewer, ScreenSpaceEventHandler, ScreenSpaceEventType } from "cesium";
import { pickPosition } from "@/components/MilitaryPlot/utils/PlotUtils";
import CustomPolygonPrimitive from "@/components/samples/CustomPolygonPrimitive";
export default class DrawPolygonTool {
/**
* 构造函数
* @param {Viewer} viewer
*/
constructor(viewer) {
/**
* 地球视图
* @type {Viewer}
* @private
*/
this._viewer = viewer;
/**
* 线对象
* @type {CustomPolygonPrimitive}
* @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 CustomPolygonPrimitive();
this._viewer.scene.primitives.add(this._primitive);
} else {
let moveP = positions.pop();
positions.push(position, moveP);
}
if (flag._primitive) {
flag._primitive.updateProperty({
positions: [...positions],
complete: false,
});
}
}
}, 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);
this._handler.setInputAction((event) => {
console.log("鼠标右键单机事件");
if (flag._primitive) {
flag._primitive.updateProperty({
positions: [...positions],
complete: false,
});
}
this._primitive = undefined;
positions = [];
}, ScreenSpaceEventType.RIGHT_CLICK);
}
/**
* 销毁
*/
destroy() {
if (this._handler) {
this._handler.isDestroyed() && this._handler.destroy();
this._handler = null;
}
}
}
本文介绍了如何在Cesium中使用CustomPolygonPrimitive绘制多边形,包括创建自定义primitive,处理属性更新,以及通过DrawPolygonTool实现用户交互式绘制。
288

被折叠的 条评论
为什么被折叠?



