You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
GCSGUI/src/assets/js/cesium-map/measureDistance.js

243 lines
9.1 KiB
JavaScript

import * as Cesium from 'cesium'
export default class MeasureDistance {
constructor(viewer) {
this.viewer = viewer
this.isMeasure = false
this.initEvents()
this.positions = []
this.temPositions = [] // 鼠标移动时产生的临时点
this.vertexEntities = [] // 节点元素
this.lineEntity = undefined // 折线元素
this.totalDistance = 0 // 总距离
}
initEvents(){
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
}
//激活
activate() {
this.registerEvents(); //注册鼠标事件
this.isMeasure = true;
this.totalDistance = 0 // 总距离
//设置鼠标样式
this.viewer._element.style.cursor = 'crosshair';
this.viewer.enableCursorStyle = true;
this.temPositions = [];
this.positions = [];
this.viewer.scene.globe.depthTestAgainstTerrain = true
}
//禁用
deactivate() {
if (!this.isMeasure) return;
this.unRegisterEvents();
this.viewer._element.style.cursor = 'default';
this.viewer.enableCursorStyle = true;
this.isMeasure = false;
this.viewer.scene.globe.depthTestAgainstTerrain = false
}
//清空绘制
clear() {
//清除线对象
this.viewer.entities.remove(this.lineEntity);
this.lineEntity = undefined;
//清除节点
this.vertexEntities.forEach(item => {
this.viewer.entities.remove(item);
});
this.vertexEntities = [];
}
//创建线对象
createLineEntity() {
this.lineEntity = this.viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(e => {
return this.temPositions;
}, false),
width: 2,
material: Cesium.Color.YELLOW,
// depthFailMaterial: Cesium.Color.YELLOW,
clampToGround: true,
disableDepthTestDistance:99000000,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND
}
})
}
//创建线节点
createVertex() {
let vertexEntity = new Cesium.Entity({
id: "MeasureDistanceVertex" + this.positions[this.positions.length - 1],
position: this.positions[this.positions.length - 1],
point: {
color: Cesium.Color.FUCHSIA,
pixelSize: 6,
disableDepthTestDistance:99000000,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
},
label:{
text: this.spaceDistance(this.positions) + "km",
font: "2rem sans-serif",
fillColor: Cesium.Color.WHITE,
style: Cesium.LabelStyle.FILL,
pixelOffset: new Cesium.Cartesian2(20, -10),
eyeOffset: new Cesium.Cartesian3(0, 0, 0),
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 20000),
scale: 0.5,
showBackground: true,
backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.5),
backgroundPadding: new Cesium.Cartesian2(10, 10),
disableDepthTestDistance:99000000,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND
},
});
this.vertexEntities.push(vertexEntity)
this.viewer.entities.add(vertexEntity)
}
//创建起点
createStartEntity() {
let vertexEntity = this.viewer.entities.add({
position: this.positions[0],
type: "MeasureDistanceVertex",
point: {
show: true,
pixelSize: 10,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 1,
disableDepthTestDistance:99000000,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
},
});
this.vertexEntities.push(vertexEntity)
}
//创建终点节点
createEndEntity() {
let vertexEntity = this.viewer.entities.add({
position: this.positions[this.positions.length - 1],
type: "MeasureDistanceVertex",
label:{
text: "总距离:" + this.totalDistance.toFixed(3) + "km",
font: "2.5rem sans-serif",
fillColor: Cesium.Color.WHITE,
style: Cesium.LabelStyle.FILL,
pixelOffset: new Cesium.Cartesian2(20, -60),
eyeOffset: new Cesium.Cartesian3(0, 0, 30),
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 20000),
scale: 0.5,
showBackground: true,
backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.99),
backgroundPadding: new Cesium.Cartesian2(10, 10),
disableDepthTestDistance:99000000,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND
},
// billboard: {
// // image: "../../static/images/end.png",
// scaleByDistance: new Cesium.NearFarScalar(300, 1, 1200, 0.4), //设置随图缩放距离和比例
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 20000), //设置可见距离 10000米可见
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM
// },
point: {
pixelSize: 10,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 1,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance:99000000
},
});
this.vertexEntities.push(vertexEntity)
}
//注册鼠标事件
registerEvents() {
this.leftClickEvent();
this.rightClickEvent();
this.mouseMoveEvent();
}
//左键点击事件
leftClickEvent() {
//单击鼠标左键画点点击事件
this.handler.setInputAction(e => {
let position = this.viewer.scene.pickPosition(e.position);
if (!position) {
const ellipsoid = this.viewer.scene.globe.ellipsoid;
position = this.viewer.scene.camera.pickEllipsoid(e.position, ellipsoid);
}
if (!position) return;
this.positions.push(position);
if (this.positions.length === 1) { //首次点击
this.createLineEntity();
this.createStartEntity();
return;
}
this.createVertex();
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
//鼠标移动事件
mouseMoveEvent() {
this.handler.setInputAction(e => {
if (!this.isMeasure) return;
let position = this.viewer.scene.pickPosition(e.endPosition);
if (!position) {
position = this.viewer.scene.camera.pickEllipsoid(e.startPosition, this.viewer.scene.globe.ellipsoid);
}
if (!position) return;
this.handleMoveEvent(position);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
//处理鼠标移动
handleMoveEvent(position) {
if (this.positions.length < 1) return;
this.temPositions = this.positions.concat(position);
}
//右键事件
rightClickEvent() {
this.handler.setInputAction(e => {
if (!this.isMeasure || this.positions.length < 1) {
this.deactivate();
this.clear()
} else {
this.createEndEntity();
this.lineEntity.polyline = {
positions: this.positions,
width: 2,
material: Cesium.Color.YELLOW,
depthFailMaterial: Cesium.Color.YELLOW
};
this.deactivate();
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
//解除鼠标事件
unRegisterEvents() {
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
}
/**
* 计算距离
* @param positions 长度大于1的Cartesian3数组
*/
spaceDistance(positions) {
let l = positions.length
let point1cartographic = Cesium.Cartographic.fromCartesian(positions[l-1]);
let point2cartographic = Cesium.Cartographic.fromCartesian(positions[l-2]);
/**根据经纬度计算出距离**/
let geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(point1cartographic, point2cartographic);
this.totalDistance += geodesic.surfaceDistance/1000
return (geodesic.surfaceDistance/1000).toFixed(3);
}
}