实现鼠标动态绘制多边形的类PolygonDraw
实现思路是:动态绘制多边形实际与动态绘制线区别不大,唯一的区别就是在构建形状时一个是构建线,一个是构建面,这里我在绘制多边形时额外在多边形外围加了一圈线以此来代表多边形的边框,因为Cesium自带的outLine属性设置宽度是无效的。
代码如下:
import CesiumByZh from "../CesiumByZh";
import GlobalListener from "../GlobalListener";
export default class PolygonDraw {
protected positions: any[] = [];
protected position: any = CesiumByZh.Cesium.Cartesian3.fromDegrees(103, 30, 100);
protected dragIconLight: string = "./Images/circle_red.png";
protected shapeEntity: any;
protected okHandler: any;
protected cancelHandler: any;
protected handler: any;
protected modifyHandler: any;
protected mousePosition: any[] = [];
protected result: any;
public pointEntityArray: any[] = [];
public canvas = CesiumByZh.viewer.scene.canvas;
public camera = CesiumByZh.viewer.scene.camera;
public ellipsoid = CesiumByZh.viewer.scene.globe.ellipsoid;
public viewer = CesiumByZh.viewer;
public scene = CesiumByZh.viewer.scene;
lineColor: string = '#002fff';
fillColor: string = '#00ff36';
lineOpacity: number = 50;
fillOpacity: number = 50;
isGround: boolean = true;
lineWidth: number = 2;
beginDraw(drawHandler: any, okHandler: any, cancelHandler: any) {
let that = this;
let floatingPoint: any = null;
function clicka(e: any) {
if (e.button == 0) {
let mouseposition = {
x: e.pageX,
y: e.pageY,
};
that.mousePosition.push(mouseposition)
}
}
this.handler = drawHandler;
this.handler.setInputAction((event: any) => {
let position = event.position;
if (!CesiumByZh.Cesium.defined(position)) {
return;
}
let ray = this.camera.getPickRay(position);
if (!CesiumByZh.Cesium.defined(ray)) {
return;
}
let cartesian = this.scene.globe.pick(ray, this.scene);
if (!CesiumByZh.Cesium.defined(cartesian)) {
return;
}
let num = this.positions.length;
if (num == 0) {
this.positions.push(cartesian);
this.createTemporaryShape();
}
this.positions.push(cartesian);
floatingPoint = this._createPoint(cartesian);
this.pointEntityArray.push(floatingPoint);
}, CesiumByZh.Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction((event: any) => {
let position = event.endPosition;
if (!CesiumByZh.Cesium.defined(position)) {
return;
}
let ray = this.camera.getPickRay(position);
if (!CesiumByZh.Cesium.defined(ray)) {
return;
}
let cartesian = this.scene.globe.pick(ray, this.scene);
if (!CesiumByZh.Cesium.defined(cartesian)) {
return;
}
if (this.positions.length == 0) {
GlobalListener.getInstance().runTipsCallback(['单击开始绘制,右键取消']);
return
} else if (this.positions.length < 3) {
GlobalListener.getInstance().runTipsCallback(['单击增加点,右键删除点']);
} else {
GlobalListener.getInstance().runTipsCallback(['单击增加点,右键删除点', '双击完成绘制']);
}
this.positions.pop();
this.positions.push(cartesian);
}, CesiumByZh.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction((movement: any) => {
if (this.positions.length == 0) {
//重新开始绘制
} else {
if (this.positions.length == 2) {
this.positions = [];
} else {
this.positions.splice(this.positions.length - 2, 1);
}
CesiumByZh.viewer.entities.remove(this.pointEntityArray[this.pointEntityArray.length - 1]);
this.pointEntityArray.pop();
}
}, CesiumByZh.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
this.handler.setInputAction((movement: any) => {
if (this.positions.length < 4) {
return;
}
this.positions.pop();
document.removeEventListener('mousemove', clicka);
}, CesiumByZh.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
document.addEventListener('click', clicka);
this.okHandler = okHandler;
this.cancelHandler = cancelHandler;
}
_createPoint(cartesian: any, oid: number = 0) {
let point = CesiumByZh.viewer.entities.add({
temporary: true,//是否为绘制临时使用
oid: oid,
canSelect: true,
position: cartesian,
billboard: {
image: this.dragIconLight,
eyeOffset: new CesiumByZh.Cesium.ConstantProperty(new CesiumByZh.Cesium.Cartesian3(0, 0, -500)),
heightReference: CesiumByZh.Cesium.HeightReference.CLAMP_TO_GROUND
}
});
return point;
}
//创建临时绘制用的实体
createTemporaryShape() {
let outlineDynamicPositions = new CesiumByZh.Cesium.CallbackProperty(() => {
if (this.positions.length > 1) {
// @ts-ignore
let arr: any = [].concat(this.positions);
let first = this.positions[0];
arr.push(first);
return arr;
} else {
return null;
}
}, false);
this.shapeEntity = CesiumByZh.viewer.entities.add({
polygon: {
hierarchy: new CesiumByZh.Cesium.CallbackProperty(() => {
return new CesiumByZh.Cesium.PolygonHierarchy(this.positions)
}, false),
material: CesiumByZh.Cesium.Color.fromCssColorString(this.fillColor).withAlpha(this.fillOpacity / 100),
height: undefined
},
polyline: {
positions: outlineDynamicPositions,
clampToGround: this.isGround,
width: this.lineWidth,
material: CesiumByZh.Cesium.Color.fromCssColorString(this.lineColor).withAlpha(this.lineOpacity / 100),
}
});
}
}