使用
const drawEntities = new CesiumEntityDraw(viewer!, {});
drawEntities.startDraw('需要绘制的类型');
CesiumEntityDraw.ts文件
import Cesium from 'cesium';
import CesiumEntityEdit from './entityMove';
class CesiumEntityDraw {
private viewer: any;
private config: any;
private infoDetail: any;
private handler: any;
private entityEdit: any;
constructor(
viewer: Cesium.Viewer,
config: { borderColor?: Cesium.Color; borderWidth?: number; material?: Cesium.Color }
) {
/**cesium实例对象 */
this.viewer = viewer;
this.entityEdit = new CesiumEntityEdit(viewer, {});
/**绘制要素的相关配置
* 默认配置
* {
borderColor: Cesium.Color.BLUE, 边框颜色
borderWidth: 2, 边框宽度
material: Cesium.Color.GREEN.withAlpha(0.5),填充材质
}
*/
this.config = config || {
borderColor: Cesium.Color.BLUE,
borderWidth: 2
// material: Cesium.Color.GREEN.withAlpha(0.5),
};
/**存贮绘制的数据 坐标 */
this.infoDetail = {
point: [],
line: [],
rectangle: [],
circle: [],
planeSelf: []
};
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
}
startDraw(type: string) {
switch (type) {
case 'point':
this.drawPoint();
break;
case 'rectangle':
this.drawRectangle();
break;
case 'circle':
this.drawCircle();
break;
case 'polygon':
this.drawPolygon();
break;
case 'line':
this.drawLine();
break;
default:
this.drawPoint();
break;
}
this.entityEdit.start();
}
/*******
* @function: function
* @return {*}
* @description: 绘制点数据
*/
drawPoint() {
this.stopDraw();
// 设置鼠标样式为crosshair
document.body.style.cursor = 'crosshair';
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction((click: { position: any }) => {
/**点击位置笛卡尔坐标 */
const cartesian = this.viewer.camera.pickEllipsoid(
click.position,
this.viewer.scene.globe.ellipsoid
);
/**笛卡尔转弧度坐标 */
const cartographic = Cesium.Cartographic.fromCartesian(
cartesian,
this.viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
/**点击位置经度 */
const lng = Cesium.Math.toDegrees(cartographic.longitude);
/**点击位置维度 */
const lat = Cesium.Math.toDegrees(cartographic.latitude);
/**实体的唯一标注 */
const id = new Date().getTime();
this.viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(lng, lat, 0),
name: 'point',
id: id,
point: {
color: Cesium.Color.BLUE,
pixelSize: 13,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 1
}
});
this.infoDetail.point.push({ id: id, position: [lng, lat] });
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction((click: any) => {
this.stopDraw();
// 添加操作完成后恢复鼠标样式为默认箭头
document.body.style.cursor = 'default';
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
/*******
* @function: function
* @description: 绘制矩形区域
*/
drawRectangle() {
this.stopDraw();
// 设置鼠标样式为crosshair
document.body.style.cursor = 'crosshair';
const positions: any = [];
let rectangle = null;
const canvas = this.viewer.scene.canvas;
this.handler = new Cesium.ScreenSpaceEventHandler(canvas);
this.handler.setInputAction((click: { position: any }) => {
if (positions.length) return;
const cartesian = this.getCatesian3FromPX(click.position);
positions.push(cartesian, cartesian);
rectangle = this.viewer.entities.add({
name: 'rectangle',
rectangle: {
coordinates: new Cesium.CallbackProperty(() => {
const obj = Cesium.Rectangle.fromCartesianArray(positions);
return obj;
}, false),
height: 0.1,
material: this.config.material,
zIndex: 100
}
});
this.handler.setInputAction((move: { endPosition: any }) => {
const cartesian = this.getCatesian3FromPX(move.endPosition);
if (rectangle) {
positions[positions.length - 1] = cartesian;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction((click: any) => {
this.stopDraw();
// 添加操作完成后恢复鼠标样式为默认箭头
document.body.style.cursor = 'default';
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
/*******
* @function: function
* @description: 绘制矩形区域
*/
drawRectangleByPolygon() {
this.stopDraw();
// 设置鼠标样式为crosshair
document.body.style.cursor = 'crosshair';
/**
* 矩形四点坐标
*/
let westSouthEastNorth: number[] = [];
/**实体的唯一标注 */
let id: any = null;
/**地图点击对象 */
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction((click: { position: any }) => {
this.viewer.scene.screenSpaceCameraController.enableRotate = false; //锁定相机
/**点击位置笛卡尔坐标 */
const cartesian = this.viewer.camera.pickEllipsoid(
click.position,
this.viewer.scene.globe.ellipsoid
);
/**笛卡尔转弧度坐标 */
const cartographic = Cesium.Cartographic.fromCartesian(
cartesian,
this.viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
/**点击位置经度 */
const lng1 = Cesium.Math.toDegrees(cartographic.longitude);
/**点击位置维度 */
const lat1 = Cesium.Math.toDegrees(cartographic.latitude);
/**边框坐标 */
westSouthEastNorth = [lng1, lat1];
id = new Date().getTime();
if (westSouthEastNorth) {
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
/**面实例对象 */
this.viewer.entities.add({
name: 'rectangle',
id: id,
polygon: {
hierarchy: new Cesium.CallbackProperty(function () {
return {
positions: Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth)
};
}, false),
height: 0,
// 填充的颜色,withAlpha透明度
material: this.config.material,
// 是否被提供的材质填充
fill: true,
// 是否显示
show: true
}
// polyline: {
// positions: new Cesium.CallbackProperty(function() {
// return Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth);
// }),
// material: this.config.borderColor,
// width: this.config.borderWidth,
// zIndex: 1
// }
});
this.handler.setInputAction((move: { endPosition: any }) => {
const cartesian = this.viewer.camera.pickEllipsoid(
move.endPosition,
this.viewer.scene.globe.ellipsoid
);
const cartographic = Cesium.Cartographic.fromCartesian(
cartesian,
this.viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
const lng = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
westSouthEastNorth = [lng1, lat1, lng1, lat, lng, lat, lng, lat1, lng1, lat1];
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(() => {
this.stopDraw();
// 添加操作完成后恢复鼠标样式为默认箭头
document.body.style.cursor = 'default';
this.infoDetail.rectangle.push({ id: id, position: westSouthEastNorth });
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
/*******
* @function: function
* @description: 绘制圆形区域
* @return {*}
*/
drawCircle() {
this.stopDraw();
// 设置鼠标样式为crosshair
document.body.style.cursor = 'crosshair';
/**实体的唯一标注 */
let id: any = null;
/**圆半径 */
let radius: number = 0;
/**圆心 */
let lngLat: any = [];
/**鼠标事件 */
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction((click: { position: any }) => {
id = new Date().getTime();
const cartesian = this.viewer.camera.pickEllipsoid(
click.position,
this.viewer.scene.globe.ellipsoid
);
const cartographic = Cesium.Cartographic.fromCartesian(
cartesian,
this.viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
const lng = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
lngLat = [lng, lat];
const entity = this.viewer.entities.add({
position: new Cesium.CallbackProperty(function () {
return Cesium.Cartesian3.fromDegrees(lng, lat);
}, false),
name: 'circle',
id: id,
ellipse: {
height: 0,
outline: true,
material: this.config.material,
outlineColor: this.config.borderColor,
outlineWidth: this.config.borderWidth
}
});
entity.ellipse.semiMajorAxis = new Cesium.CallbackProperty(function () {
return radius;
}, false);
entity.ellipse.semiMinorAxis = new Cesium.CallbackProperty(function () {
return radius;
}, false);
if (lngLat) {
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
this.handler.setInputAction((move: { endPosition: any }) => {
const cartesian2 = this.viewer.camera.pickEllipsoid(
move.endPosition,
this.viewer.scene.globe.ellipsoid
);
radius = Cesium.Cartesian3.distance(cartesian, cartesian2);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(() => {
this.infoDetail.circle.push({ id: id, center: lngLat, radius: radius });
this.stopDraw();
// 添加操作完成后恢复鼠标样式为默认箭头
document.body.style.cursor = 'default';
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
/*******
* @function: function
* @description: 自定义区域绘制
*/
drawPolygon() {
this.stopDraw();
// 设置鼠标样式为crosshair
document.body.style.cursor = 'crosshair';
/**实体的唯一标注 */
const id = new Date().getTime();
/**记录拐点坐标 */
const positions: any = [];
/**记录返回结果 */
const codeInfo: any = [];
/**面的hierarchy属性 */
const polygon = new Cesium.PolygonHierarchy();
const _polygonEntity: any = new Cesium.Entity();
/**面对象配置 */
let polyObj = null;
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
// left
this.handler.setInputAction((movement: { position: any }) => {
const cartesian = this.viewer.camera.pickEllipsoid(
movement.position,
this.viewer.scene.globe.ellipsoid
);
const cartographic = Cesium.Cartographic.fromCartesian(
cartesian,
this.viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
const lng = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
if (cartesian && cartesian.x) {
if (positions.length == 0) {
positions.push(cartesian.clone());
}
codeInfo.push([lng, lat]);
positions.push(cartesian.clone());
polygon.positions.push(cartesian.clone());
if (!polyObj) {
// _polygonEntity.polyline = {
// width: this.config.borderWidth,
// material: this.config.borderColor,
// clampToGround: false
// };
// _polygonEntity.polyline.positions = new Cesium.CallbackProperty(
// function() {
// return positions;
// },
// false
// );
_polygonEntity.polygon = {
hierarchy: new Cesium.CallbackProperty(function () {
return polygon;
}, false),
zIndex: 100,
height: 0.1,
material: Cesium.Color.BLUE.withAlpha(0.8),
clampToGround: false
};
_polygonEntity.name = 'polygon';
_polygonEntity._id = id;
polyObj = this.viewer.entities.add(_polygonEntity);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// mouse
this.handler.setInputAction((movement: { endPosition: any }) => {
const cartesian = this.viewer.camera.pickEllipsoid(
movement.endPosition,
this.viewer.scene.globe.ellipsoid
);
const cartographic = Cesium.Cartographic.fromCartesian(
cartesian,
this.viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
const lng = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
if (positions.length >= 0) {
if (cartesian && cartesian.x) {
positions.pop();
positions.push(cartesian);
polygon.positions.pop();
polygon.positions.push(cartesian);
codeInfo.pop();
codeInfo.push([lng, lat]);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// right
this.handler.setInputAction((movement: any) => {
this.stopDraw();
// 添加操作完成后恢复鼠标样式为默认箭头
document.body.style.cursor = 'default';
this.infoDetail.planeSelf.push({ id: id, positions: codeInfo });
positions.push(positions[0]);
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
/*******
* @function: function
* @return {*}
* @description: 绘制线段
*/
drawLine() {
this.stopDraw();
// 设置鼠标样式为crosshair
document.body.style.cursor = 'crosshair';
/**实体的唯一标注 */
const id = new Date().getTime();
/**记录拐点坐标 */
const positions: any = [],
/**记录返回结果 */
codeInfo: any = [],
/**面的hierarchy属性 */
polygon = new Cesium.PolygonHierarchy(),
_polygonEntity: any = new Cesium.Entity();
/**面对象配置 */
let polyObj = null;
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
// left
this.handler.setInputAction((movement: { position: any }) => {
const cartesian = this.viewer.camera.pickEllipsoid(
movement.position,
this.viewer.scene.globe.ellipsoid
);
const cartographic = Cesium.Cartographic.fromCartesian(
cartesian,
this.viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
const lng = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
if (cartesian && cartesian.x) {
if (positions.length == 0) {
positions.push(cartesian.clone());
}
codeInfo.push([lng, lat]);
positions.push(cartesian.clone());
polygon.positions.push(cartesian.clone());
if (!polyObj) {
_polygonEntity.polyline = {
width: 4,
material: Cesium.Color.BLUE.withAlpha(0.8),
clampToGround: true
};
_polygonEntity.polyline.positions = new Cesium.CallbackProperty(function () {
return positions;
}, false);
_polygonEntity.name = 'line';
_polygonEntity._id = id;
polyObj = this.viewer.entities.add(_polygonEntity);
// this.entityEdit = new CesiumEntityEdit(this.viewer, polyObj);
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// mouse
this.handler.setInputAction((movement: { endPosition: any }) => {
const cartesian = this.viewer.camera.pickEllipsoid(
movement.endPosition,
this.viewer.scene.globe.ellipsoid
);
const cartographic = Cesium.Cartographic.fromCartesian(
cartesian,
this.viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
const lng = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
if (positions.length >= 0) {
if (cartesian && cartesian.x) {
positions.pop();
positions.push(cartesian);
codeInfo.pop();
codeInfo.push([lng, lat]);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// right
this.handler.setInputAction((movement: any) => {
this.infoDetail.line.push({ id: id, positions: codeInfo });
this.stopDraw();
// 添加操作完成后恢复鼠标样式为默认箭头
document.body.style.cursor = 'default';
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
/*******
* @function: function
* @description: 移除实体对象
* @return {*}
*/
removeEntity() {
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction((move: { endPosition: any }) => {
/**实体对象信息 {id:entities,primitive:。。} */
const pick = this.viewer.scene.pick(move.endPosition);
this.entityEdit.removeStretchPoint();
if (pick && pick.id && pick.id.id) {
document.body.style.cursor = 'pointer';
this.handler.setInputAction((click: any) => {
let newPoint: any;
switch (pick.id.name) {
case 'point':
/**删除某一条数据 */
newPoint = this.infoDetail.point.filter(
(item: { id: any }) => item.id != pick.id._id
);
this.infoDetail.point = newPoint;
break;
case 'line':
/**删除某一条数据 */
newPoint = this.infoDetail.line.filter((item: { id: any }) => item.id != pick.id._id);
this.infoDetail.line = newPoint;
break;
case 'rectangle':
/**删除某一条数据 */
newPoint = this.infoDetail.rectangle.filter(
(item: { id: any }) => item.id != pick.id._id
);
this.infoDetail.rectangle = newPoint;
break;
case 'planeSelf':
/**删除某一条数据 */
newPoint = this.infoDetail.planeSelf.filter(
(item: { id: any }) => item.id != pick.id._id
);
this.infoDetail.planeSelf = newPoint;
break;
case 'circle':
/**删除某一条数据 */
newPoint = this.infoDetail.circle.filter(
(item: { id: any }) => item.id != pick.id._id
);
this.infoDetail.circle = newPoint;
break;
default:
break;
}
this.viewer.entities.remove(pick.id);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
} else {
document.body.style.cursor = 'default';
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
/**
*
*/
removeAllEntity() {
this.entityEdit.removeStretchPoint();
Object.keys(this.infoDetail).map((name) => {
this.infoDetail[name].map((item: { id: any }) => {
this.viewer.entities.removeById(item.id);
});
});
}
/*******
* @function: function
* @return {*}
* @description: 返回绘制数据
*/
backInfoDetail() {
return this.infoDetail;
}
stopDraw() {
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
// this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOWN);
// this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_UP);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// this.handler && this.handler.destroy();
// this.entityEdit.stop();
}
stopEdit() {
this.entityEdit.stop();
}
getMousePostion(position: any) {
if (!position) return;
/**点击位置笛卡尔坐标 */
const cartesian = this.viewer.camera.pickEllipsoid(position, this.viewer.scene.globe.ellipsoid);
/**笛卡尔转弧度坐标 */
const cartographic = Cesium.Cartographic.fromCartesian(
cartesian,
this.viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
/**点击位置经度 */
const lng1 = Cesium.Math.toDegrees(cartographic.longitude);
/**点击位置维度 */
const lat1 = Cesium.Math.toDegrees(cartographic.latitude);
return [lng1, lat1];
}
getCatesian3FromPX(px: any) {
const ray = this.viewer.camera.getPickRay(px);
if (!ray) return null;
const cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
return cartesian;
}
}
export default CesiumEntityDraw;
CesiumEntityEdit .ts文件
/**
* cesium 实体编辑:拖拽、旋转、修改
*/
import * as turf from '@turf/turf';
import Cesium from 'cesium';
class CesiumEntityEdit {
private viewer: any;
private options: any;
private selectedEntity: any; // 被选择的实体对象
private handler: any; // 事件捕获
private mouseStatus: any; // 当前鼠标状态 LEFT_DOWN:左键按下;LEFT_UP: 左键抬起;MOVE: 鼠标移动
private coordinates: any; // 当前被选中的实体组成的点集合
private entityType: any; // 当前被选中实体的类型
private entityCenter: any; // 多边形中心点
private strecthPointIds: any; // 拉伸点Id集合
private strecthObj: any; // 被选中的拉伸点
private isStrecth: any; // 当前是否点击拉伸点
private strecthObjId_index: any;
constructor(viewer: any, options: {} | null) {
this.viewer = viewer;
this.options = options || {};
this.selectedEntity = null; // 被选择的实体对象
this.handler = null; // 事件捕获
this.mouseStatus = null; // 当前鼠标状态 LEFT_DOWN:左键按下;LEFT_UP: 左键抬起;MOVE: 鼠标移动
this.coordinates = []; // 当前被选中的实体组成的点集合
this.entityType = 'polygon'; // 当前被选中实体的类型
this.entityCenter = []; // 多边形中心点
this.strecthPointIds = []; // 拉伸点Id集合
this.strecthObj = null; // 被选中的拉伸点
this.isStrecth = false; // 当前是否点击拉伸点
}
start() {
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
// 监听鼠标左键按下事件
this.handler.setInputAction(
(e: any) => this.handleLeftDown(e),
Cesium.ScreenSpaceEventType.LEFT_DOWN
);
// 监听鼠标左键抬起事件
this.handler.setInputAction(
(e: any) => this.handleLeftUp(e),
Cesium.ScreenSpaceEventType.LEFT_UP
);
// 监听鼠标移动事件
this.handler.setInputAction(
(e: any) => this.handleMouseMove(e),
Cesium.ScreenSpaceEventType.MOUSE_MOVE
);
}
handleLeftDown(e: { position: any }) {
// 更新鼠标状态
this.mouseStatus = 'LEFT_DOWN';
// 获取当前点击位置的实体对象
const obj = this.viewer.scene.pick(e.position);
if (!obj) {
this.strecthObj = null;
this.selectedEntity = null;
this.viewer.scene.screenSpaceCameraController.enableRotate = true;
this.removeStretchPoint();
return;
}
if (obj && obj.id.name === 'stretch_point') {
const index = this.strecthPointIds.findIndex((p: any) => p === obj.id.id);
this.strecthObjId_index = index;
this.strecthObj = obj;
this.isStrecth = true;
} else {
this.removeStretchPoint();
this.strecthObj = null;
this.selectedEntity = obj;
}
//锁定相机
this.viewer.scene.screenSpaceCameraController.enableRotate = false;
if (obj.id.polygon) {
this.entityType = 'polygon';
this.coordinates = this.selectedEntity.id.polygon.hierarchy.getValue().positions;
this.entityCenter = this.getEntityCenter();
this.addStrecthPoint(this.selectedEntity.id.polygon);
}
if (obj.id.rectangle) {
this.entityType = 'rectangle';
this.coordinates = this.selectedEntity.id.rectangle.coordinates.getValue();
this.addStrecthPoint(this.selectedEntity.id.rectangle);
}
if (obj.id.point) {
this.entityType = 'point';
}
if (obj.id.polyline) {
this.entityType = 'polyline';
this.coordinates = this.selectedEntity.id.polyline.positions.getValue();
// this.entityCenter = this.getEntityCenter()
this.addStrecthPoint(this.selectedEntity.id.polyline);
}
}
handleLeftUp(e: any) {
// 更新鼠标状态
this.mouseStatus = 'LEFT_UP';
}
handleMouseMove(e: any) {
if (this.mouseStatus === 'LEFT_DOWN' && this.selectedEntity) {
// 拖拽实体
if (this.strecthObj) {
this.handleDrag(e, this.strecthObj);
this.handleStretch(this.selectedEntity);
return;
}
this.removeStretchPoint();
this.handleDrag(e, this.selectedEntity);
}
}
/**
* 拖拽移动实体
* @param {*} e
*/
handleDrag(
e: { startPosition: any; endPosition: any },
selectedEntity: {
id: {
position: Cesium.CallbackProperty;
polygon: { hierarchy: Cesium.CallbackProperty };
rectangle: { coordinates: Cesium.CallbackProperty };
polyline: { positions: Cesium.CallbackProperty };
};
}
) {
if (!selectedEntity) return;
const coordinates = this.coordinates;
// 获取开始位置坐标
const startPosition = this.viewer.scene.camera.pickEllipsoid(
e.startPosition,
this.viewer.scene.globe.ellipsoid
);
// 获取结束位置坐标
const endPosition = this.viewer.scene.camera.pickEllipsoid(
e.endPosition,
this.viewer.scene.globe.ellipsoid
);
selectedEntity.id.position = new Cesium.CallbackProperty(function () {
return endPosition;
}, false);
const changed_x = endPosition.x - startPosition.x;
const changed_y = endPosition.y - startPosition.y;
const changed_z = endPosition.z - startPosition.z;
if (this.entityType === 'point') {
const ray = this.viewer.camera.getPickRay(e.endPosition);
const cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
selectedEntity.id.position = new Cesium.CallbackProperty(() => {
return cartesian;
}, false);
}
if (this.entityType === 'polygon' || this.entityType === 'polyline') {
const currentsPoint: any = [];
for (let i = 0; i < coordinates.length; i++) {
coordinates[i].x = coordinates[i].x + changed_x;
coordinates[i].y = coordinates[i].y + changed_y;
coordinates[i].z = coordinates[i].z + changed_z;
currentsPoint.push(coordinates[i]);
}
if (this.entityType === 'polygon') {
selectedEntity.id.polygon.hierarchy = new Cesium.CallbackProperty(() => {
return { positions: currentsPoint };
}, false); // 防止闪烁
} else {
selectedEntity.id.polyline.positions = new Cesium.CallbackProperty(() => {
return currentsPoint;
}, false); // 防止闪烁
}
}
if (this.entityType === 'rectangle') {
const position_start = startPosition;
const cartographic_start = Cesium.Cartographic.fromCartesian(position_start);
const longitude_start = Cesium.Math.toDegrees(cartographic_start.longitude);
const latitude_start = Cesium.Math.toDegrees(cartographic_start.latitude);
const position_end = endPosition;
const cartographic_end = Cesium.Cartographic.fromCartesian(position_end);
const longitude_end = Cesium.Math.toDegrees(cartographic_end.longitude);
const latitude_end = Cesium.Math.toDegrees(cartographic_end.latitude);
const changer_lng = longitude_end - longitude_start;
const changer_lat = latitude_end - latitude_start;
coordinates.west = Cesium.Math.toRadians(
Cesium.Math.toDegrees(coordinates.west) + changer_lng
);
coordinates.east = Cesium.Math.toRadians(
Cesium.Math.toDegrees(coordinates.east) + changer_lng
);
coordinates.south = Cesium.Math.toRadians(
Cesium.Math.toDegrees(coordinates.south) + changer_lat
);
coordinates.north = Cesium.Math.toRadians(
Cesium.Math.toDegrees(coordinates.north) + changer_lat
);
selectedEntity.id.rectangle.coordinates = new Cesium.CallbackProperty(() => {
return coordinates;
}, false);
}
}
/**
* 旋转实体
* @param {*} angle
*/
handleRotation(angle: number) {
if (!this.selectedEntity) return;
// 旋转时清除辅助拉伸的点
if (this.strecthPointIds.length) {
this.removeStretchPoint();
}
if (this.entityType === 'rectangle') {
// 旋转图形
this.selectedEntity.id.rectangle.rotation = new Cesium.CallbackProperty(function () {
return angle;
}, false);
// 旋转图形材质
this.selectedEntity.id.rectangle.stRotation = new Cesium.CallbackProperty(function () {
return angle;
}, false);
}
if (this.entityType === 'polygon') {
// let previousCoordinates = this.selectedEntity.id.polygon.hierarchy.getValue().positions
// let coors = this.getWGS84FromDKR(previousCoordinates)
// console.log(coors)
// let poly = turf.polygon([coors])
// let centroid = turf.centroid(poly)
// let rotatedPoly = turf.transformRotate(poly, angle, { pivot: centroid.geometry.coordinates})
// let newCoors = rotatedPoly.geometry.coordinates[0]
// let positions = []
// newCoors.forEach(item => {
// positions.push(item[0], item[1])
// })
this.selectedEntity.id.polygon.stRotation = new Cesium.CallbackProperty(function () {
return Cesium.Math.toRadians(angle);
}, false);
// this.selectedEntity.id.polygon.hierarchy = new Cesium.CallbackProperty(function () {
// return { positions: Cesium.Cartesian3.fromDegreesArray(positions) }
// }, false)
}
}
/**
* 拉伸实体
*/
handleStretch(selectedEntity: {
id: {
polygon: { hierarchy: Cesium.CallbackProperty };
rectangle: { coordinates: Cesium.CallbackProperty };
polyline: { positions: Cesium.CallbackProperty };
};
}) {
const positions: any = [];
// 更新polygon的位置数组
if (selectedEntity.id.polygon) {
for (let i = 0; i < this.strecthPointIds.length; i++) {
const id = this.strecthPointIds[i];
positions.push(this.viewer.entities.getById(id).position.getValue());
}
selectedEntity.id.polygon.hierarchy = new Cesium.CallbackProperty(() => {
return { positions: positions };
}, false);
}
// 更新polyline的位置数组
if (selectedEntity.id.polyline) {
for (let i = 0; i < this.strecthPointIds.length; i++) {
const id = this.strecthPointIds[i];
positions.push(this.viewer.entities.getById(id).position.getValue());
}
selectedEntity.id.polyline.positions = new Cesium.CallbackProperty(() => {
return positions;
}, false);
}
// 更新rectangle的位置数组
if (selectedEntity.id.rectangle) {
const index = this.strecthPointIds.findIndex((item: any) => item === this.strecthObj.id.id);
for (let i = 0; i < this.strecthPointIds.length; i++) {
const id = this.strecthPointIds[i];
// 矩形由两个对角的点组成的区域,因此先判断用户点击的是哪一个点,即奇偶判断
if (index % 2 === 0) {
if (i % 2 === 0) {
positions.push(this.viewer.entities.getById(id).position.getValue());
} else {
// 将另外一半点隐藏
this.viewer.entities.getById(id).show = false;
}
} else {
if (i % 2 != 0) {
positions.push(this.viewer.entities.getById(id).position.getValue());
} else {
this.viewer.entities.getById(id).show = false;
}
}
}
selectedEntity.id.rectangle.coordinates = new Cesium.CallbackProperty(() => {
const obj = Cesium.Rectangle.fromCartesianArray(positions);
return obj;
}, false);
}
}
/**
* 添加拉伸点
* @param {*} entity
*/
addStrecthPoint(entity: {
hierarchy: { getValue: () => { (): any; new (): any; positions: never[] } };
coordinates: { getValue: () => any };
positions: { getValue: () => any };
}) {
let points = [];
if (this.entityType === 'polygon') {
points = entity.hierarchy.getValue().positions;
} else if (this.entityType === 'rectangle') {
const rectangle = entity.coordinates.getValue();
Cesium.Rectangle.subsample(rectangle, Cesium.Ellipsoid.WGS84, rectangle.height, points);
} else if (this.entityType === 'polyline') {
points = entity.positions.getValue();
}
// const id = new Date().getTime();
for (const position of points) {
const point = this.viewer.entities.add({
name: 'stretch_point',
position: position,
// id:new Date().getTime()
point: {
color: Cesium.Color.WHITE,
pixelSize: 10,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 1
}
});
this.strecthPointIds.push(point.id);
}
}
/**
* 清除拉伸点
*/
removeStretchPoint() {
for (const id of this.strecthPointIds) {
this.viewer.entities.removeById(id);
}
this.strecthPointIds = [];
this.strecthObj = null;
this.isStrecth = false;
}
/**
* 获取多边形图形中心点
*/
getEntityCenter() {
const previousCoordinates = this.selectedEntity.id.polygon.hierarchy.getValue().positions;
const coors = this.getWGS84FromDKR(previousCoordinates);
coors.push(coors[0]);
const poly = turf.polygon([coors]);
const centroid = turf.centroid(poly);
return centroid.geometry.coordinates;
}
/**
* 将笛卡尔坐标转换成国际坐标
* @param {*} coors
* @returns
*/
getWGS84FromDKR(coors: string | any[]) {
const newCoors: any = [];
for (let i = 0; i < coors.length; i++) {
const coor = coors[i];
const cartographic = Cesium.Cartographic.fromCartesian(coor);
const x = Cesium.Math.toDegrees(cartographic.longitude);
const y = Cesium.Math.toDegrees(cartographic.latitude);
newCoors.push([x, y]);
}
return newCoors;
}
stop() {
this.handler && this.handler.destroy();
this.removeStretchPoint();
this.viewer.scene.screenSpaceCameraController.enableRotate = true;
}
}
export default CesiumEntityEdit;