实现效果
编辑
绘制
RailMange.js 全内容
import * as Cesium from 'cesium';
import PlotDrawTip from './PlotDrawTip';
export class RailManage {
constructor() {
this.viewer = window.mapViewer;
this.entityCollection = [];
this.labelEntity = null;
this.pointsId = [];
this.editPolygonShow = false;
this.primitive = null;
this.echEntites = null; //回显围栏
this.plotDrawTip = null;
this.entityPointList = [];
this.handler = window.mapViewer.screenSpaceEventHandler;
}
flyToOverall() {
this.viewer.scene.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(106.53873959614215, 37.730160351329395, 2000.9778139644488),
orientation: new Cesium.HeadingPitchRange(Cesium.Math.toRadians(-17.0), Cesium.Math.toRadians(-90.0), 1),
});
}
removeEchPolyGon() {
if (this.echEntites) {
this.viewer.entities.remove(this.echEntites);
}
}
/**
* 清除
*/
destroy(callback) {
for (let i = 0; i < this.entityCollection?.length; i++) {
this.viewer.entities.remove(this.entityCollection[i]);
}
this.destoryAddPoint();
this.destoryHandler();
this.entityCollection = [];
this.viewer.entities.remove(this.labelEntity);
if (callback) {
callback();
}
if (this.plotDrawTip != null) {
this.plotDrawTip.remove();
this.plotDrawTip = null;
}
}
destoryHandler() {
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
if (this.pointsId) {
for (let id of this.pointsId) {
this.viewer.entities.removeById(id);
}
}
}
destoryAddPoint() {
if (this.entityPointList.length) {
for (let i = 0; i < this.entityPointList.length; i++) {
this.viewer.entities.remove(this.entityPointList[i]);
}
}
}
// 添加wl
addWLPolygon(callback) {
let positions = [];
let xyzPosition = [];
let clickStatus = false;
this.plotDrawTip = new PlotDrawTip(this.viewer);
this.plotDrawTip.setContent([
'当前绘制类型:普通墙体,最少需要2个点',
'按下鼠标左键确定第1个点',
'按下鼠标右键取消绘制',
]);
// this.viewer.enableCursorStyle = false;
// this.viewer._element.style.cursor = 'point';
this.viewer.scene.globe.depthTestAgainstTerrain = false;
this.handler.setInputAction((clickEvent) => {
clickStatus = true;
// 返回cartesian3坐标
const { scene, camera } = this.viewer;
let _cartesian = undefined;
// if (scene.pickPosition(clickEvent.position)) {
_cartesian = scene.pickPosition(clickEvent.position);
// } else {
// _cartesian = camera.pickEllipsoid(clickEvent.position);
// }
// const _cartographic = Cesium.Cartographic.fromCartesian(
// _cartesian,
// scene.globe.ellipsoid,
// new Cesium.Cartographic()
// )
if (!_cartesian) {
return false;
}
if (positions.length == 0) {
positions.push(_cartesian.clone()); //鼠标左击 添加第1个点
this.addPoint(_cartesian.clone());
xyzPosition.push({
x: _cartesian.x,
y: _cartesian.y,
z: _cartesian.z,
});
this.plotDrawTip.updatePosition(_cartesian.clone());
this.setTipContent(xyzPosition);
this.handler.setInputAction((moveEvent) => {
let _moveEvent = undefined;
_moveEvent = scene.pickPosition(moveEvent.endPosition);
if (!_moveEvent) {
return false;
}
var screenPosition = new Cesium.Cartesian2(moveEvent.endPosition.x, moveEvent.endPosition.y);
// 获取屏幕坐标对应的地理坐标(笛卡尔坐标)
var ray = this.viewer.camera.getPickRay(screenPosition);
var cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
this.plotDrawTip.updatePosition(cartesian);
this.setTipContent(xyzPosition);
if (positions.length == 1) {
positions.push(_moveEvent);
} else {
if (clickStatus) {
positions.push(_moveEvent);
} else {
positions.pop();
positions.push(_moveEvent);
}
}
clickStatus = false;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
} else if (positions.length == 2) {
if (!_cartesian) {
return false;
}
positions.pop();
positions.push(_cartesian.clone()); // 鼠标左击 添加第2个点
xyzPosition.push({
x: _cartesian.x,
y: _cartesian.y,
z: _cartesian.z,
});
this.plotDrawTip.updatePosition(_cartesian.clone());
this.setTipContent(xyzPosition);
this.addPoint(_cartesian);
this.addPolyGon(positions);
// 右击结束
this.handler.setInputAction((clickEvent) => {
let _clickEvent = undefined;
_clickEvent = scene.pickPosition(clickEvent.position);
if (!_clickEvent) {
return false;
}
positions.pop();
positions.push(_clickEvent);
xyzPosition.push({
x: _clickEvent.x,
y: _clickEvent.y,
z: _clickEvent.z,
});
this.addPoint(_clickEvent);
this.viewer.scene.globe.depthTestAgainstTerrain = true;
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
this.viewer.entities.remove(this.labelEntity);
if (this.plotDrawTip) {
this.plotDrawTip.remove();
this.plotDrawTip = null;
}
this.destoryAddPoint();
if (callback) {
let res = tranformXyztoLonLat(this.viewer, xyzPosition);
callback(res, this.entityCollection);
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
} else if (positions.length >= 3) {
if (!_cartesian) {
return false;
}
positions.pop();
positions.push(_cartesian.clone()); // 鼠标左击 添加第3个点
xyzPosition.push({
x: _cartesian.x,
y: _cartesian.y,
z: _cartesian.z,
});
this.plotDrawTip.updatePosition(_cartesian.clone());
this.setTipContent(xyzPosition);
this.addPoint(_cartesian);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
setTipContent(positions) {
this.plotDrawTip.setContent([
'当前绘制类型:面,最少需要3个点。',
'已有' + positions.length + '个点,' + '按下鼠标左键确定第' + (positions.length + 1) + '个点',
positions.length < 2 ? '' : '按下鼠标右键结束绘制',
]);
// 按下鼠标右键取消绘制;
}
/**
* 添加点
* @param position
*/
addPoint(position) {
this.entityPointList.push(
this.viewer.entities.add(
new Cesium.Entity({
position: position,
point: {
color: Cesium.Color.fromCssColorString('#139e96'),
pixelSize: 15,
heightReference: Cesium.ClassificationType.CLAMP_TO_GROUND,
disableDepthTestDistance: position.z,
},
})
)
);
}
/**
* 添加面
* @param positions
*/
addPolyGon(positions) {
let dynamicPositions = new Cesium.CallbackProperty(() => {
return new Cesium.PolygonHierarchy(positions);
}, false);
let entities = this.viewer.entities.add(
new Cesium.Entity({
name: 'geopolygon',
polygon: {
hierarchy: dynamicPositions,
material: Cesium.Color.BLUE.withAlpha(0.4),
// classificationType: Cesium.ClassificationType.BOTH, // 贴地表和贴模型,如果设置了,这不能使用挤出高度
},
})
);
this.entityCollection.push(entities);
this.echEntites = entities;
}
echoPolyGon(positions, positionList) {
if (!positions.length) return;
let data = positions.flat().map((i) => {
return Number(i);
});
this.echEntites = this.viewer.entities.add(
new Cesium.Entity({
name: 'geopolygon',
polygon: {
// hierarchy: Cesium.Cartesian3.fromDegreesArray(positions),
hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights(data),
material: Cesium.Color.BLUE.withAlpha(0.4),
classificationType: Cesium.ClassificationType.BOTH, // 贴地表和贴模型,如果设置了,这不能使用挤出高度
},
})
);
let center = getCenter(positions);
// console.log(center);
this.viewer.scene.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(...center, 1400),
});
}
// 重绘
resetDraw(callback) {
this.viewer.scene.screenSpaceCameraController.enableRotate = true;
this.viewer.scene.screenSpaceCameraController.enableZoom = true;
this.destroy();
this.removeEchPolyGon();
this.addWLPolygon((res) => {
callback(res);
});
}
// 退出编辑
endEditPolygon(callback) {
this.editPolygonShow = false;
// 获取多边形的层次结构信息
var hierarchy = this.echEntites.polygon.hierarchy.getValue(Cesium.JulianDate.now());
// 遍历多边形的坐标点
let arr = [];
var positions = hierarchy.positions;
for (var i = 0; i < positions.length; i++) {
var position = positions[i];
// 获取坐标点的地理信息
var cartographic = Cesium.Cartographic.fromCartesian(position);
// 获取地理坐标的经度、纬度、高度
var longitude = Cesium.Math.toDegrees(cartographic.longitude);
var latitude = Cesium.Math.toDegrees(cartographic.latitude);
var height = cartographic.height;
arr.push([longitude, latitude, height]);
}
// arr.push(arr[0])
this.viewer.scene.screenSpaceCameraController.enableRotate = true;
this.viewer.scene.screenSpaceCameraController.enableZoom = true;
for (let id of this.pointsId) {
this.viewer.entities.removeById(id);
}
this.pointsId = [];
callback(arr);
}
createPointEdit() {
this.viewer.scene.globe.depthTestAgainstTerrain = true;
let _this = this;
if (this.echEntites) {
this.pointsId = [];
let hierarchy = this.echEntites.polygon.hierarchy;
var positions = hierarchy.getValue(Cesium.JulianDate.now()).positions;
let positionsList = positions.map((i) => {
return {
x: Number(i.x),
y: Number(i.y),
z: Number(i.z) + 1,
};
});
// 生成编辑点
if (positionsList.length) {
for (let i = 0; i < positionsList.length; i++) {
let cartesian3 = new Cesium.Cartesian3(positionsList[i].x, positionsList[i].y, positionsList[i].z);
let pointEntity = this.viewer.entities.add({
name: 'gon_point',
position: cartesian3,
point: {
color: Cesium.Color.WHITE,
pixelSize: 20,
outlineColor: Cesium.Color.BLACK.withAlpha(0.5),
outlineWidth: 5,
disableDepthTestDistance: positionsList[i].z,
// disableDepthTestDistance: 1000,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, positionsList[i].z + 2500),
// height: 0,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
},
// viewFrom: new Cesium.Cartesian3(-100, 0, 100),
});
this.pointsId.push(pointEntity.id);
}
}
}
}
// 编辑面
editWlPolygon() {
this.viewer.scene.globe.depthTestAgainstTerrain = true;
let currentPoint = undefined;
this.editPolygonShow = true;
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
let { scene } = this.viewer;
this.viewer.scene.screenSpaceCameraController.enableRotate = false;
// this.viewer.scene.screenSpaceCameraController.enableZoom = false;
// 对鼠标按下事件的监听
this.handler.setInputAction((event) => {
let windowPosition = event.position;
let pickedObject = this.viewer.scene.pick(windowPosition);
if (Cesium.defined(pickedObject)) {
let entity = pickedObject.id;
if (entity?.name === 'gon_point') {
currentPoint = entity;
}
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
// 对鼠标移动事件的监听
this.handler.setInputAction((moveEnd) => {
if (currentPoint) {
let _cartesian = undefined;
_cartesian = scene.pickPosition(moveEnd.endPosition);
let points = [];
if (!_cartesian) {
return;
}
currentPoint.position = _cartesian;
for (let id of this.pointsId) {
let ent = this.viewer.entities.getById(id);
let pos = ent.position._value;
points.push(pos);
}
this.echEntites.polygon.hierarchy = new Cesium.CallbackProperty(() => {
return new Cesium.PolygonHierarchy([...points]);
}, false);
return;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 对鼠标抬起事件的监听
this.handler.setInputAction((event) => {
currentPoint = undefined;
}, Cesium.ScreenSpaceEventType.LEFT_UP);
}
removePrimitive() {
if (this.primitive) {
this.viewer.scene.primitives.remove(this.primitive);
}
}
}
// xyz转经纬度
function tranformXyztoLonLat(viewer, positions) {
let arr = [];
for (let i = 0; i < positions?.length; i++) {
let cartesian3 = new Cesium.Cartesian3(positions[i].x, positions[i].y, positions[i].z);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
let lat = Cesium.Math.toDegrees(cartographic.latitude);
let lng = Cesium.Math.toDegrees(cartographic.longitude);
// console.log(cartographic, 'cartographic')
arr.push([lng, lat, cartographic.height]);
}
return arr;
}
export function getCenter(arr) {
let centerLonLat = [];
if (arr.length) {
const lon = [];
const lat = [];
const poly = [];
for (let i = 0, len = arr.length; i < len; i++) {
lon.push(arr[i][0]);
lat.push(arr[i][1]);
}
for (let i = 0, len = lon.length; i < len; i++) {
poly.push({
x: parseFloat(lon[i]),
y: parseFloat(lat[i]),
z: 0,
});
}
const sortedLongitudeArray = poly.map((item) => item.x).sort();
const sortedLatitudeArray = poly.map((item) => item.y).sort();
const centerLongitude = (
(parseFloat(sortedLongitudeArray[0]) + parseFloat(sortedLongitudeArray[sortedLongitudeArray.length - 1])) /
2
).toFixed(14);
const centerLatitude = (
(parseFloat(sortedLatitudeArray[0]) + parseFloat(sortedLatitudeArray[sortedLatitudeArray.length - 1])) /
2
).toFixed(14);
centerLonLat = [Number(centerLongitude), Number(centerLatitude)];
}
return centerLonLat;
}
Tip.vue 样式文件 vue2适用 vue3不适用可以去除弹框