This commit is contained in:
dujunming 2024-11-28 23:53:00 +08:00
parent d56749ffee
commit 03ab1cccff
3 changed files with 384 additions and 332 deletions

View File

@ -23,10 +23,11 @@ const drawLine = (type: TreeNode) => {
drawClass.drawDynamicPoint();
break;
case 'lines':
drawClass.drawDynamicLine()
drawClass.drawDynamicLine();
break;
case 'line':
drawClass.drawDynamicSLine()
console.log('here')
drawClass.drawDynamicSLine();
break;
case 'polygon':
drawClass.drawDynamicPolygon();

View File

@ -0,0 +1,194 @@
import * as Cesium from "cesium";
import {
CallbackProperty,
type Cartesian3,
ConstantPositionProperty,
ScreenSpaceEventHandler,
} from "cesium";
export default class DynamicDrawClass {
private readonly viewer: Cesium.Viewer;
private entities: Map<string, Cesium.Entity>;
private handler: Cesium.ScreenSpaceEventHandler | null = null;
private readonly ellipsoid: Cesium.Ellipsoid;
constructor(viewer: Cesium.Viewer) {
this.viewer = viewer;
this.entities = new Map();
this.ellipsoid = viewer.scene.globe.ellipsoid;
}
private removeHandler() {
if (this.handler) {
this.handler.destroy();
this.handler = null;
}
}
private pickPosition(event: Cesium.ScreenSpaceEventHandler.MotionEvent | Cesium.ScreenSpaceEventHandler.PositionedEvent): Cartesian3 | undefined {
let position: Cesium.Cartesian3 | undefined;
if ("endPosition" in event) {
position = this.viewer.scene.camera.pickEllipsoid(event.endPosition, this.ellipsoid);
} else if ("position" in event) {
position = this.viewer.scene.camera.pickEllipsoid(event.position, this.ellipsoid);
}
return position;
}
private addEntity(entityOptions: Cesium.Entity.ConstructorOptions): Cesium.Entity {
return this.viewer.entities.add(entityOptions);
}
private removeEntity(entity: Cesium.Entity): boolean {
return this.viewer.entities.remove(entity);
}
/**
*
*/
drawDynamicPoint(): Cesium.Entity | undefined {
this.removeHandler();
let activePosition: Cartesian3 | undefined;
let dynamicPoint: Cesium.Entity | undefined;
this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction((event:ScreenSpaceEventHandler.PositionedEvent) => {
const position = this.pickPosition(event);
if (position) {
activePosition = position;
if (!dynamicPoint) {
dynamicPoint = this.addEntity({
position: new CallbackProperty(() => activePosition, false),
point: {
color: Cesium.Color.RED,
pixelSize: 10,
outlineColor: Cesium.Color.GREEN,
outlineWidth: 1.5,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction((event:ScreenSpaceEventHandler.PositionedEvent) => {
const position = this.pickPosition(event);
if (position && dynamicPoint) {
activePosition = position;
dynamicPoint.position = new ConstantPositionProperty(activePosition);
this.removeHandler();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
return dynamicPoint;
}
/**
* 线
*/
private drawDynamicShape(isPolygon: boolean=false,isLine:boolean=false,isDynamicLien:boolean=false): Cesium.Entity | undefined {
this.removeHandler();
let activePositions: Cartesian3[] = [];
let dynamicShape: Cesium.Entity | undefined;
let edgeEntity: Cesium.Entity | undefined;
const hierarchy = isPolygon ? new Cesium.PolygonHierarchy() : undefined;
this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction((event:ScreenSpaceEventHandler.MotionEvent) => {
const position = this.pickPosition(event);
if (position) {
if (activePositions.length > 0) {
activePositions[activePositions.length - 1] = position;
if (hierarchy) hierarchy.positions[activePositions.length - 1] = position;
} else {
activePositions.push(position);
if (hierarchy) hierarchy.positions.push(position);
}
if (!edgeEntity) {
edgeEntity = this.addEntity({
polyline: {
positions: new CallbackProperty(() => activePositions, false),
width: 1,
material: Cesium.Color.RED.withAlpha(0.5),
},
});
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction((event:ScreenSpaceEventHandler.PositionedEvent) => {
const position = this.pickPosition(event);
if (position) {
activePositions.push(position);
if (hierarchy) hierarchy.positions.push(position);
if (!dynamicShape) {
dynamicShape = this.addEntity(
isPolygon ? {
polygon: {
hierarchy: new CallbackProperty(() => hierarchy, false),
material: Cesium.Color.WHITESMOKE.withAlpha(0.5),
outlineWidth: 2,
outlineColor:Cesium.Color.RED
},
}
: {
polyline: {
positions: new CallbackProperty(() => activePositions, false),
width: 3,
material: Cesium.Color.BLUE.withAlpha(0.5),
},
}
);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(() => {
if (activePositions.length > 1) {
activePositions.pop();
if (hierarchy) hierarchy.positions.pop();
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
this.handler.setInputAction(() => {
this.removeHandler();
if (isPolygon) activePositions.push(activePositions[0]);
if (edgeEntity) this.removeEntity(edgeEntity);
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
return dynamicShape;
}
drawDynamicLine(): Cesium.Entity | undefined {
return this.drawDynamicShape(false);
}
drawDynamicPolygon(): Cesium.Entity | undefined {
return this.drawDynamicShape(true);
}
/**
*
*/
remove(id: string): boolean {
const entity = this.entities.get(id);
if (entity) {
this.removeEntity(entity);
this.entities.delete(id);
return true;
}
return false;
}
/**
*
*/
clearAll(): void {
this.viewer.entities.removeAll();
this.entities.clear();
}
}
线

View File

@ -1,335 +1,192 @@
import * as Cesium from "cesium";
import {CallbackProperty, type Cartesian3, Property, ScreenSpaceEventHandler, type ScreenSpaceEventType} from "cesium";
import * as Cesium from "cesium";
import {
CallbackProperty,
type Cartesian3,
ConstantPositionProperty,
ScreenSpaceEventHandler,
} from "cesium";
export default class DynamicDrawClass {
private readonly viewer: Cesium.Viewer;
private entities: Map<string, Cesium.Entity>;
private handler: Cesium.ScreenSpaceEventHandler | null = null;
export default class DynamicDrawClass {
private readonly viewer: Cesium.Viewer;
private entities: Map<string, Cesium.Entity>;
private handler: Cesium.ScreenSpaceEventHandler | null = null;
private readonly ellipsoid: Cesium.Ellipsoid;
constructor(viewer: Cesium.Viewer,) {
this.viewer = viewer;
this.entities = new Map();
}
constructor(viewer: Cesium.Viewer) {
this.viewer = viewer;
this.entities = new Map();
this.ellipsoid = viewer.scene.globe.ellipsoid;
}
removeHandler() {
if (this.handler) {
this.handler.destroy();
this.handler = null;
}
}
/**
*
* @returns
*/
drawDynamicPoint(): Cesium.Entity | undefined {
this.removeHandler(); // 清除之前的鼠标事件处理器
if (this.viewer) {
let activePosition: Cesium.Cartesian3 | undefined; // 当前动态位置
let dynamicPoint: Cesium.Entity | undefined; // 动态点实体
const canvas = this.viewer.scene.canvas;
const globe = this.viewer.scene.globe;
const ellipsoid = globe.ellipsoid;
// 初始化鼠标事件处理器
this.handler = new Cesium.ScreenSpaceEventHandler(canvas);
// 鼠标移动时显示动态点
this.handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.MotionEvent) => {
const movePosition = this.viewer.scene.camera.pickEllipsoid(
event.endPosition,
ellipsoid
);
if (movePosition) {
activePosition = movePosition;
// 如果动态点还未创建,则创建一个
if (!dynamicPoint) {
dynamicPoint = this.viewer.entities.add({
position: new Cesium.CallbackProperty(() => activePosition, false), // 动态更新位置
point: {
color: Cesium.Color.RED, // 点的颜色
pixelSize: 10, // 像素大小
outlineColor: Cesium.Color.GREEN, // 边框颜色
outlineWidth: 1.5, // 边框宽度
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 鼠标左键单击时固定点的位置
this.handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
const clickPosition = this.viewer.scene.camera.pickEllipsoid(
event.position,
ellipsoid
);
if (clickPosition && dynamicPoint) {
activePosition = clickPosition;
dynamicPoint.position = clickPosition;
this.removeHandler(); // 清除鼠标事件处理器,防止继续移动
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
return dynamicPoint; // 返回动态点实体
}
return undefined; // 如果 viewer 不存在,返回 undefined
}
/**
* 线
*/
drawDynamicSLine(): Cesium.Entity | undefined {
this.removeHandler(); // 清除之前的鼠标事件处理器
if (this.viewer) {
let activePositions: Cartesian3[] = []; // 当前动态位置
let dynamicLine: Cesium.Entity | undefined; // 动态点实体
const canvas = this.viewer.scene.canvas;
const globe = this.viewer.scene.globe;
const ellipsoid = globe.ellipsoid;
let endPoint: Cesium.Entity; // 动态端点实体
// 初始化鼠标事件处理器
this.handler = new Cesium.ScreenSpaceEventHandler(canvas);
// 鼠标移动时显示动态点
this.handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.MotionEvent) => {
const movePosition = this.viewer.scene.camera.pickEllipsoid(
event.endPosition,
ellipsoid
);
// 动态更新线的最后一个点
if (activePositions.length > 0 && movePosition) {
console.log(activePositions.length)
activePositions[activePositions.length - 1] = movePosition;
} else if (movePosition) {
activePositions.push(movePosition); // 第一个点
}
if (!endPoint) {
endPoint = this.viewer.entities.add({
position: new Cesium.CallbackProperty(() => {
return activePositions[activePositions.length - 1];
}, false),
point: {
pixelSize: 10,
outlineColor: Cesium.Color.RED,
outlineWidth: 1.5,
color: Cesium.Color.WHITE
}
})
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 鼠标左键单击时固定点的位置
this.handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
const clickPosition = this.viewer.scene.camera.pickEllipsoid(
event.position,
ellipsoid
);
if (clickPosition && activePositions.length < 2) {
activePositions.push(clickPosition);
dynamicLine = this.viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(() => {
return activePositions;
}, false),
width: 3,
material: Cesium.Color.BLUE.withAlpha(0.5),
}
})
} else {
this.viewer.entities.remove(endPoint);
this.removeHandler();
return dynamicLine;
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// this.handler.setInputAction((click:Cesium.ScreenSpaceEventHandler.PositionedEvent)=>{
// this.removeHandler(); // 清除鼠标事件处理器
// if (dynamicLine) {
// return dynamicLine; // 返回最终的动态线实体
// }
// },Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
}
return undefined;
}
/**
* 线
*/
drawDynamicLine(): Cesium.Entity | undefined {
this.removeHandler(); // 清除之前的鼠标事件处理器
if (this.viewer) {
let activePositions: Cartesian3[] = []; // 当前动态位置
let dynamicLine: Cesium.Entity | undefined; // 动态点实体
const canvas = this.viewer.scene.canvas;
const globe = this.viewer.scene.globe;
const ellipsoid = globe.ellipsoid;
let endPoint: Cesium.Entity; // 动态端点实体
// 初始化鼠标事件处理器
this.handler = new Cesium.ScreenSpaceEventHandler(canvas);
// 鼠标移动时显示动态点
this.handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.MotionEvent) => {
const movePosition = this.viewer.scene.camera.pickEllipsoid(
event.endPosition,
ellipsoid
);
// 动态更新线的最后一个点
if (activePositions.length > 0 && movePosition) {
activePositions[activePositions.length - 1] = movePosition;
} else if (movePosition) {
activePositions.push(movePosition); // 第一个点
}
// 如果没有端点实体,创建一个新的端点显示
if (!endPoint) {
endPoint = this.viewer.entities.add({
position: new Cesium.CallbackProperty(() => {
return activePositions[activePositions.length - 1]; // 端点位置
}, false),
point: {
color: Cesium.Color.WHITE, // 端点的颜色
pixelSize: 10, // 点的大小
outlineColor: Cesium.Color.RED, // 边框颜色
outlineWidth: 2, // 边框宽度
},
});
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 鼠标左键单击时固定点的位置
this.handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
const clickPosition = this.viewer.scene.camera.pickEllipsoid(
event.position,
ellipsoid
);
if (clickPosition) {
activePositions.push(clickPosition);
dynamicLine = this.viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(() => {
return activePositions;
}, false),
width: 3,
material: Cesium.Color.GREEN.withAlpha(0.5),
}
})
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction((clickPosition: Cesium.ScreenSpaceEventHandler.MotionEvent) => {
activePositions.length > 1 ? activePositions.pop() : null;
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
this.handler.setInputAction((click: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
this.removeHandler(); // 清除鼠标事件处理器
this.viewer.entities.remove(endPoint);
if (dynamicLine) {
return dynamicLine; // 返回最终的动态线实体
}
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
}
return undefined;
}
/**
*
* @returns
*/
drawDynamicPolygon(): Cesium.Entity|undefined {
this.removeHandler();
if (this.viewer) {
let activePositions: Cartesian3[] = []; // 当前动态位置
let hierarchy = new Cesium.PolygonHierarchy(); // 用于存储多边形的点
let myPolygon: Cesium.Entity;
let myPolyline: Cesium.Entity;
const canvas = this.viewer.scene.canvas;
const globe = this.viewer.scene.globe;
const ellipsoid = globe.ellipsoid;
// 初始化鼠标事件处理器
this.handler = new Cesium.ScreenSpaceEventHandler(canvas);
// 鼠标移动时更新动态点
this.handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.MotionEvent) => {
const movePosition = this.viewer.scene.camera.pickEllipsoid(event.endPosition, ellipsoid);
if (movePosition) {
// 动态更新线的最后一个点
if (activePositions.length > 0) {
activePositions[activePositions.length - 1] = movePosition;
hierarchy.positions[activePositions.length - 1] = movePosition;
}else{
activePositions.push(movePosition);
hierarchy.positions.push(movePosition);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 鼠标左键单击时添加点
this.handler.setInputAction((event: Cesium.ScreenSpaceEventHandler.PositionedEvent) => {
const clickPosition = this.viewer.scene.camera.pickEllipsoid(event.position, ellipsoid);
if (clickPosition) {
activePositions.push(clickPosition);
hierarchy.positions.push(clickPosition);
// 动态显示多边形
myPolygon = this.viewer.entities.add({
polygon: {
hierarchy: new CallbackProperty(() => hierarchy, false),
material: Cesium.Color.WHITESMOKE.withAlpha(0.5),
outlineWidth: 2,
}
});
// 动态显示多边形的边界线
myPolyline = this.viewer.entities.add({
name:'123',
polyline: {
width: 1,
material: Cesium.Color.RED.withAlpha(0.5),
positions: new CallbackProperty(() => activePositions, false)
}
});
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// 鼠标右键单击时删除最后一个点
this.handler.setInputAction(() => {
if (activePositions.length > 1) {
activePositions.pop(); // 删除最后一个点
hierarchy.positions.pop(); // 删除多边形最后一个点
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
// 鼠标双击时完成绘制
this.handler.setInputAction((movement:ScreenSpaceEventHandler.PositionedEvent) => {
this.removeHandler(); // 清除事件处理器
activePositions.push(activePositions[0])
// 移除辅助线myPolyline
if (myPolyline) {
let res = this.viewer.entities.remove(myPolyline);
console.log(res)
}
// 移除多边形
if (myPolygon) {
return myPolygon; // 返回多边形实体
}
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
}
return undefined;
}
/**
*
* @param id -
* @returns
*/
remove(id: string): boolean {
const entity = this.entities.get(id);
if (entity) {
this.viewer.entities.remove(entity);
this.entities.delete(id);
return true;
}
return false;
}
/**
*
*/
clearAll(): void {
this.viewer.entities.removeAll();
this.entities.clear();
private removeHandler() {
if (this.handler) {
this.handler.destroy();
this.handler = null;
}
}
private pickPosition(event: Cesium.ScreenSpaceEventHandler.MotionEvent | Cesium.ScreenSpaceEventHandler.PositionedEvent): Cartesian3 | undefined {
let position: Cesium.Cartesian3 | undefined;
if ("endPosition" in event) {
position = this.viewer.scene.camera.pickEllipsoid(event.endPosition, this.ellipsoid);
} else if ("position" in event) {
position = this.viewer.scene.camera.pickEllipsoid(event.position, this.ellipsoid);
}
return position;
}
private addEntity(entityOptions: Cesium.Entity.ConstructorOptions): Cesium.Entity {
return this.viewer.entities.add(entityOptions);
}
private removeEntity(entity: Cesium.Entity): boolean {
return this.viewer.entities.remove(entity);
}
/**
*
*/
drawDynamicPoint(): Cesium.Entity | undefined {
this.removeHandler();
let activePosition: Cartesian3 | undefined;
let dynamicPoint: Cesium.Entity | undefined;
this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction((event:ScreenSpaceEventHandler.PositionedEvent) => {
const position = this.pickPosition(event);
if (position) {
activePosition = position;
if (!dynamicPoint) {
dynamicPoint = this.addEntity({
position: new CallbackProperty(() => activePosition, false),
point: {
color: Cesium.Color.RED,
pixelSize: 10,
outlineColor: Cesium.Color.GREEN,
outlineWidth: 1.5,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction((event:ScreenSpaceEventHandler.PositionedEvent) => {
const position = this.pickPosition(event);
if (position && dynamicPoint) {
activePosition = position;
dynamicPoint.position = new ConstantPositionProperty(activePosition);
this.removeHandler();
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
return dynamicPoint;
}
/**
* 线
*/
private drawDynamicShape(isPolygon: boolean=false,isLine:boolean=false,isDynamicLien:boolean=false): Cesium.Entity | undefined {
this.removeHandler();
let activePositions: Cartesian3[] = [];
let dynamicShape: Cesium.Entity | undefined;
let edgeEntity: Cesium.Entity | undefined;
const hierarchy = isPolygon ? new Cesium.PolygonHierarchy() : undefined;
this.handler = new ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction((event:ScreenSpaceEventHandler.MotionEvent) => {
const position = this.pickPosition(event);
if (position) {
if (activePositions.length > 0) {
activePositions[activePositions.length - 1] = position;
if (hierarchy) hierarchy.positions[activePositions.length - 1] = position;
} else {
activePositions.push(position);
if (hierarchy) hierarchy.positions.push(position);
}
if (!edgeEntity) {
edgeEntity = this.addEntity({
polyline: {
positions: new CallbackProperty(() => activePositions, false),
width: 1,
material: Cesium.Color.RED.withAlpha(0.5),
},
});
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction((event:ScreenSpaceEventHandler.PositionedEvent) => {
const position = this.pickPosition(event);
if (position) {
activePositions.push(position);
if (hierarchy) hierarchy.positions.push(position);
if (!dynamicShape) {
dynamicShape = this.addEntity(
isPolygon ? {
polygon: {
hierarchy: new CallbackProperty(() => hierarchy, false),
material: Cesium.Color.WHITESMOKE.withAlpha(0.5),
outlineWidth: 2,
outlineColor:Cesium.Color.RED
},
}
: {
polyline: {
positions: new CallbackProperty(() => activePositions, false),
width: 3,
material: Cesium.Color.BLUE.withAlpha(0.5),
},
}
);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(() => {
if (activePositions.length > 1) {
activePositions.pop();
if (hierarchy) hierarchy.positions.pop();
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
this.handler.setInputAction(() => {
this.removeHandler();
if (isPolygon) activePositions.push(activePositions[0]);
if (edgeEntity) this.removeEntity(edgeEntity);
}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
return dynamicShape;
}
drawDynamicLine(): Cesium.Entity | undefined {
return this.drawDynamicShape(false);
}
drawDynamicPolygon(): Cesium.Entity | undefined {
return this.drawDynamicShape(true);
}
/**
*
*/
remove(id: string): boolean {
const entity = this.entities.get(id);
if (entity) {
this.removeEntity(entity);
this.entities.delete(id);
return true;
}
return false;
}
/**
*
*/
clearAll(): void {
this.viewer.entities.removeAll();
this.entities.clear();
}
}