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.
239 lines
8.7 KiB
JavaScript
239 lines
8.7 KiB
JavaScript
import {Cartesian3, DataSource} from "cesium";
|
|
import * as Cesium from 'cesium'
|
|
|
|
|
|
export default class RouteManageViewer {
|
|
constructor(viewer) {
|
|
this.viewer = viewer
|
|
this.scene = viewer.scene
|
|
this.routeParams = {
|
|
isClose: false,
|
|
height: 0,
|
|
}
|
|
this.positions = []
|
|
this.temPositions = [] // 鼠标移动时产生的临时点
|
|
this.vertexEntities = [] // 节点元素
|
|
this.lineEntity = undefined // 折线元素
|
|
this.lineEntitys = [] // 折线元素数组,每完成一次航线绘制,将折线元素加入此数组
|
|
}
|
|
|
|
/**
|
|
* 显示航线
|
|
* @param line Airline
|
|
*/
|
|
addAirLine(line){
|
|
let res = this.viewer.entities.getById( "航线" + line.unicode)
|
|
if(res!==undefined){
|
|
return res
|
|
}
|
|
|
|
let degreesArr = []
|
|
for (let i = 0; i < line.points.length; i++) {
|
|
let coord = new Cartesian3.fromDegrees(line.points[i].lon,line.points[i].lat,line.points[i].alt)
|
|
degreesArr.push(coord)
|
|
}
|
|
if(line.isClose)
|
|
degreesArr.push(new Cartesian3.fromDegrees(line.points[0].lon,line.points[0].lat,line.points[0].alt))
|
|
|
|
let airlineEntity = new Cesium.Entity({
|
|
name: line.name,
|
|
id: "航线" + line.unicode,
|
|
polyline: {
|
|
positions: degreesArr,
|
|
width: 3,
|
|
material: Cesium.Color.ORANGE,
|
|
clampToGround: false,
|
|
}
|
|
})
|
|
this.viewer.entities.add(airlineEntity)
|
|
degreesArr.forEach((pt,index)=>{
|
|
let vertexEntity = new Cesium.Entity({
|
|
id: line.unicode + "-航点" + (index+1),
|
|
position: pt,
|
|
point: {
|
|
color: Cesium.Color.WHITE,
|
|
pixelSize: 6,
|
|
outlineColor: Cesium.Color.RED,
|
|
outlineWidth: 2,
|
|
disableDepthTestDistance:99000000,
|
|
// heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
},
|
|
label:{
|
|
text: "航点 " + (index+1),
|
|
font: "2.5rem sans-serif",
|
|
fillColor: Cesium.Color.WHITE,
|
|
style: Cesium.LabelStyle.FILL,
|
|
eyeOffset: new Cartesian3(0,0,50),
|
|
horizontalOrigin: Cesium.HorizontalOrigin.RIGHT,
|
|
verticalOrigin: Cesium.VerticalOrigin.TOP,
|
|
scale: 0.4,
|
|
showBackground: true,
|
|
backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.99),
|
|
backgroundPadding: new Cesium.Cartesian2(15, 7),
|
|
}
|
|
});
|
|
this.viewer.entities.add(vertexEntity)
|
|
})
|
|
return airlineEntity
|
|
}
|
|
|
|
/**
|
|
* 删除航线
|
|
* @param line Airline
|
|
*/
|
|
removeRoute(line){
|
|
this.viewer.entities.removeById( "航线" + line.unicode)
|
|
line.points.forEach((_,index)=>{
|
|
this.viewer.entities.removeById(line.unicode + "-航点" + index)
|
|
})
|
|
}
|
|
|
|
// -----------------绘制航线相关功能--------------------------//
|
|
//开始绘制
|
|
start() {
|
|
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
|
|
this.viewer.scene.globe.depthTestAgainstTerrain = true
|
|
|
|
//设置鼠标样式
|
|
this.viewer._element.style.cursor = 'crosshair';
|
|
this.viewer.enableCursorStyle = true;
|
|
this.temPositions = [];
|
|
this.positions = [];
|
|
return new Promise((resolve,reject) => {
|
|
//注册鼠标事件
|
|
//单击鼠标左键画点点击事件
|
|
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);
|
|
}
|
|
//TODO: 海拔高度转Cartesain3 Z 值
|
|
if (position){
|
|
this.positions.push(position);
|
|
}
|
|
if (this.positions.length === 1) { //首次点击
|
|
this.createLineEntity();
|
|
}
|
|
this.createVertex();
|
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
|
|
this.handler.setInputAction(e => {
|
|
if (this.positions.length < 3) {
|
|
this.endDraw();
|
|
this.clearDisEntity()
|
|
reject("航线不得少于三个航点!")
|
|
}
|
|
else {
|
|
this.lineEntity.polyline = {
|
|
positions: this.routeParams.isClose? this.positions.concat(this.positions[0]) : this.positions,
|
|
width: 2,
|
|
material: Cesium.Color.YELLOW,
|
|
depthFailMaterial: Cesium.Color.YELLOW
|
|
}
|
|
this.endDraw();
|
|
resolve(this._Cartesian_degrees(this.positions))
|
|
}
|
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
|
|
|
this.handler.setInputAction(e => {
|
|
let position = this.viewer.scene.pickPosition(e.endPosition);
|
|
if (!position) {
|
|
position = this.viewer.scene.camera.pickEllipsoid(e.startPosition, this.viewer.scene.globe.ellipsoid);
|
|
}
|
|
if (this.positions.length >= 1){
|
|
this.temPositions = this.positions.concat(position);
|
|
}
|
|
this.viewer.scene.requestRender()
|
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
|
})
|
|
}
|
|
|
|
//结束绘制
|
|
endDraw() {
|
|
this.unRegisterEvents();
|
|
this.viewer._element.style.cursor = 'default';
|
|
this.viewer.enableCursorStyle = true;
|
|
this.lineEntitys.push(this.lineEntity)
|
|
|
|
}
|
|
|
|
//清空绘制
|
|
clearDisEntity() {
|
|
//清除折线
|
|
this.lineEntitys.forEach(item => {
|
|
this.viewer.entities.remove(item);
|
|
});
|
|
//清除节点
|
|
this.vertexEntities.forEach(item => {
|
|
this.viewer.entities.remove(item);
|
|
});
|
|
|
|
this.positions = []
|
|
this.temPositions = [] // 鼠标移动时产生的临时点
|
|
this.vertexEntities = [] // 节点元素
|
|
this.lineEntity = undefined // 折线元素
|
|
this.lineEntitys = [] // 折线元素数组,每完成一次航线绘制,将折线元素加入此数组
|
|
}
|
|
|
|
//创建线对象
|
|
createLineEntity() {
|
|
this.lineEntity = this.viewer.entities.add({
|
|
polyline: {
|
|
positions: new Cesium.CallbackProperty(e => {
|
|
return this.temPositions;
|
|
}, false),
|
|
width: 2,
|
|
material: Cesium.Color.YELLOW,
|
|
clampToGround: true,
|
|
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
},
|
|
})
|
|
this.viewer.scene.requestRender()
|
|
}
|
|
//创建线节点
|
|
createVertex() {
|
|
let vertexEntity = new Cesium.Entity({
|
|
id: "Route" + this.positions[this.positions.length - 1],
|
|
position: this.positions[this.positions.length - 1],
|
|
point: {
|
|
color: Cesium.Color.FUCHSIA,
|
|
pixelSize: 8,
|
|
outlineColor: Cesium.Color.WHITE,
|
|
outlineWidth: 2,
|
|
disableDepthTestDistance:99000000,
|
|
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
},
|
|
});
|
|
this.vertexEntities.push(vertexEntity)
|
|
this.viewer.entities.add(vertexEntity)
|
|
}
|
|
|
|
//解除鼠标事件(测距)
|
|
unRegisterEvents() {
|
|
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
|
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
|
}
|
|
|
|
/**
|
|
* 笛卡尔坐标数组转为经纬度坐标数组
|
|
* @param cartesian3Arr 笛卡尔坐标数组
|
|
* @returns {*[]} 经纬度坐标数组
|
|
* @private
|
|
*/
|
|
_Cartesian_degrees(cartesian3Arr){
|
|
let coords = []
|
|
cartesian3Arr.forEach((item) => {
|
|
// 将 Cartesian3 转换为 Cartographic
|
|
let cartographic = Cesium.Cartographic.fromCartesian(item, Cesium.Ellipsoid.WGS84);
|
|
coords.push({
|
|
lon: Cesium.Math.toDegrees(cartographic.longitude),
|
|
lat: Cesium.Math.toDegrees(cartographic.latitude),
|
|
alt: this.routeParams.height
|
|
})
|
|
})
|
|
return coords
|
|
}
|
|
|
|
} |