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

1027 lines
40 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import * as Cesium from 'cesium'
import {Cartesian3} from 'cesium'
import {useStaticStore} from "@/store/staticOptions.js";
export default class MeasureDistance {
constructor(viewer) {
this.viewer = viewer
this.scene = viewer.scene
this.isMeasure = false
this.positions = []
this.temPositions = [] // 距离测量-鼠标移动时产生的临时点
this.vertexEntities = [] // 距离测量-节点元素
this.lineEntity = undefined // 距离测量-折线元素
this.lineEntitys = [] // 距离测量-折线元素数组,每完成一次距离测量,将折线元素加入此数组
this.totalDistance = 0 // 距离测量-总距离
this.activeShapePoints = [] //面积测量-多边形顶点
this.polygon = undefined
this.measAreaStatus = false //是否在测量面积
this.analyseGraphs = [] //分析工具的图形容器
this.graphics = [] //图形绘制容器
this.dynamicData = {
lon: undefined,
lat: undefined,
alt: undefined,
heading: undefined,
};
this.graphicStyle = {
borderColor: Cesium.Color.BLUE,
borderWidth: 1,
material: Cesium.Color.GREEN.withAlpha(0.5),
}
}
profileAnalyse(){
//解绑鼠标事件
if(this.handler) this.unRegisterEvents()
let count = 0
let profilePts = [] //点集合
let line = undefined
let movePoint = undefined
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
// 绑定鼠标左击事件
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;
count++
profilePts.push(position)
let nodeEntity = this._createPointEntity(position, count.toString())
this.viewer.entities.add(nodeEntity)
this.analyseGraphs.push(nodeEntity)
if(!line){
line = this.viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(e => {
return profilePts.concat(movePoint);
}, false),
width: 2,
material: Cesium.Color.YELLOW,
clampToGround: true,
},
})
}
//通视分析仅支持选择两个点
if(useStaticStore().analysisVars.analysisType===2&&profilePts.length===2){
this.unRegisterEvents()
useStaticStore().analysisVars.profilePts = profilePts
}
}, Cesium.ScreenSpaceEventType.LEFT_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 (!position) return;
movePoint = position
this.viewer.scene.requestRender()
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
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;
count++
profilePts.push(position)
let endEntity = this._createPointEntity(position, count.toString())
this.viewer.entities.add(endEntity)
this.analyseGraphs.push(endEntity)
this.analyseGraphs.push(line)
this.unRegisterEvents()
useStaticStore().analysisVars.profilePts = profilePts
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
return false
}
clearProfileEntities(){
this.analyseGraphs.forEach((item)=>{
this.viewer.entities.remove(item)
})
}
updateDynamicData(data){
this.dynamicData.lon = data.lon;
this.dynamicData.lat = data.lat;
this.dynamicData.alt = data.alt;
this.dynamicData.heading = data.heading;
this.viewer.scene.requestRender()
}
addKml(kml_file){
let kmlDataPromise = Cesium.KmlDataSource.load(kml_file, {
camera: this.viewer.scene.camera,
canvas: this.viewer.scene.canvas,
screenOverlayContainer: this.viewer.container,
clampToGround: true,
});
console.log(kmlDataPromise);
kmlDataPromise.then((dataSource)=> {
// console.log(dataSource);
this.viewer.dataSources.add(dataSource);
this.viewer.flyTo(dataSource);
});
}
addJson(js_file){
// 加载geojson数据
let dataGeo = Cesium.GeoJsonDataSource.load(
js_file,
//设置样式
{
stroke: Cesium.Color.RED,
fill: Cesium.Color.SKYBLUE.withAlpha(0.5),
strokeWidth: 4,
}
);
// viewer.dataSources.add(dataGeo);//可直接进行添加数据
//dataGeo Promise对象加载完毕后执行
dataGeo.then((dataSources) => {
console.log(dataSources);
viewer.dataSources.add(dataSources);
// 获取datasources中的实体
let entities = dataSources.entities.values;
//获取每一个实体
// entities.forEach((entity, i) => {
// //设置随机颜色
// entity.polygon.material = new Cesium.ColorMaterialProperty(
// Cesium.Color.fromRandom({
// alpha: 1,
// })
// );
// entity.polygon.outline = false;
// //随机高度5个级别
// let randomNum = parseInt(Math.random() * 5);
// //挤出高度
// entity.polygon.extrudedHeight = 100000 * randomNum;
// });
});
}
/**
* Cesium实体导出Geojson只导出实体中的 polyline polygon rectangle
* @param entity
* @return geojson Object
*/
entity2Geojson(entity){
let geoJson = {
"type": "FeatureCollection",
"features": []
}
if(entity.point && entity.position){
let point = {
"type": "Feature",
"properties": {},
"geometry": {
"coordinates": [entity?.position?.x, entity?.position?.y],
"type": "Point"
}
}
geoJson.features.push(point);
}
if(entity.polyline?.positions){
let polyline = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": []
}
}
let Cartesian3Arr = entity.polyline?.positions.getValue(Cesium.JulianDate.now)
Cartesian3Arr.forEach((p) => {
let cartographic = this.scene.globe.ellipsoid.cartesianToCartographic(p);
polyline.geometry.coordinates.push([Cesium.Math.toDegrees(cartographic.longitude),Cesium.Math.toDegrees(cartographic.latitude)])
})
geoJson.features.push(polyline)
}
if(entity.polygon?.hierarchy){
let polygon = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": []
}
}
let coords = [] //polygon的坐标点
let Cartesian3Arr = entity.polygon?.hierarchy.getValue(Cesium.JulianDate.now).positions
Cartesian3Arr.forEach((p) => {
let cartographic = this.scene.globe.ellipsoid.cartesianToCartographic(p);
coords.push([Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude)])
})
let end = this.scene.globe.ellipsoid.cartesianToCartographic(Cartesian3Arr[0]);
coords.push([Cesium.Math.toDegrees(end.longitude), Cesium.Math.toDegrees(end.latitude)])
polygon.geometry.coordinates.push(coords)
geoJson.features.push(polygon)
}
if(entity.rectangle?.coordinates){
let rectangle = {
"type": "Feature",
"properties": {
"stroke-width": entity.rectangle?.outlineWidth,
"stroke": entity.rectangle?.outlineColor.toCssColorString(),
"fill": entity.rectangle?.material.toCssColorString(),
"fill-opacity": entity.rectangle?.material.alpha
},
"geometry": {
"type": "Polygon",
"coordinates": [[]]
}
}
let coords = [] //rectangle的坐标点
let cesium_Rec = entity.rectangle?.coordinates
let west_north, east_north, east_south,west_south
west_north = Cesium.Cartesian3.fromRadians(cesium_Rec.west,cesium_Rec.north)
east_north = Cesium.Cartesian3.fromRadians(cesium_Rec.east,cesium_Rec.north)
east_south = Cesium.Cartesian3.fromRadians(cesium_Rec.east,cesium_Rec.south)
west_south = Cesium.Cartesian3.fromRadians(cesium_Rec.west,cesium_Rec.south)
coords.push([west_north.x, west_north.y])
coords.push([east_north.x, east_north.y])
coords.push([east_south.x, east_south.y])
coords.push([west_south.x, west_south.y])
rectangle.geometry.coordinates.push(coords)
geoJson.features.push(rectangle)
}
return geoJson
}
/**
* 显示飞行航线
* @param line Airline
*/
showAirLine(line){
let degreesArr = []
for (let i = 0; i < line.points.length; i++) {
degreesArr.push(line.points[i].lon)
degreesArr.push(line.points[i].lat)
degreesArr.push(line.points[i].alt)
}
let airlineEntity = new Cesium.Entity({
name: line.name,
id: line.name+line.totalDistance,
polyline: {
positions:Cesium.Cartesian3.fromDegreesArray(degreesArr),
width: 2,
material: Cesium.Color.ORANGE,
clampToGround: true,
},
})
this.viewer.entities.add(airlineEntity)
}
addAirplaneEntity(modelPath,StrUavTypeID){
let entity = this.viewer.entities.add({
name: StrUavTypeID,
id: "ID: "+StrUavTypeID,
position: new Cesium.CallbackProperty(() => {
return new Cesium.Cartesian3.fromDegrees(this.dynamicData.lon, this.dynamicData.lat, this.dynamicData.alt)
}, false),
//增加模型航向
orientation: new Cesium.CallbackProperty(()=>{
return new Cesium.Transforms.headingPitchRollQuaternion(
new Cesium.Cartesian3.fromDegrees(this.dynamicData.lon, this.dynamicData.lat, this.dynamicData.alt),
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(this.dynamicData.heading-90), // 0是正东顺时针增加
Cesium.Math.toRadians(0),
Cesium.Math.toRadians(0)
))
}, false),
model: {
uri: modelPath,
minimumPixelSize: 100,
maximumScale: 2000,
runAnimations: true,
clampAnimations: true,
color: Cesium.Color.fromAlpha(Cesium.Color.RED, parseFloat(1.0)),
colorBlendMode: Cesium.ColorBlendMode['MIX'],
colorBlendAmount: 0
}
});
this.viewer.trackedEntity = entity;
}
setNoTrack(){
window.viewer.trackedEntity = null;
window.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
}
stopAreaMeasure(){
if (!this.measAreaStatus) return;
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
this.measAreaStatus = false;
this.viewer._element.style.cursor = 'default';
this.viewer.enableCursorStyle = true;
}
//清空绘制多边形和label
clearAreaEntity() {
//清除多边形
this.viewer.entities.removeById('4399');
this.viewer.entities.removeById('4390');
this.polygon = undefined;
this.activeShapePoints = [];
}
activateAreaMeasure(){
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
this.viewer.scene.globe.depthTestAgainstTerrain = true
// 清除可能会用到的监听事件
if (this.handler) {
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
this.measAreaStatus = true;
this.viewer._element.style.cursor = 'crosshair';
this.viewer.enableCursorStyle = true;
//鼠标左键--确定选中点
this.handler.setInputAction((event) => {
let ray = viewer.camera.getPickRay(event.position);
let earthPosition = viewer.scene.globe.pick(ray, viewer.scene)
//鼠标开始点击多边形的第一个点
if (this.activeShapePoints.length === 0) {
//将第一个左击的点添加到多边形顶点集合中
this.activeShapePoints.push(earthPosition)
//多边形的坐标采用回调的形式
//边线顶点
let linePoints = new Cesium.CallbackProperty(() => {
return this.activeShapePoints.concat([this.activeShapePoints[0]]);
}, false)
//多边形顶点
let dynamicPositions = new Cesium.CallbackProperty(() => {
return new Cesium.PolygonHierarchy(this.activeShapePoints)
}, false)
//添加一个多边形
this.polygon = new Cesium.Entity({
name: "area polygon",
id: '4399',
polyline: {
positions: linePoints,
width: 1,
material: Cesium.Color.RED.withAlpha(0.8),
heightReference: Cesium.HeightReference.NONE,
clampToGround: true
},
polygon: {
hierarchy: dynamicPositions,
material: Cesium.Color.ORANGERED.withAlpha(0.8),
heightReference: Cesium.HeightReference.NONE
// outlineColor: Cesium.Color.RED.withAlpha(0.7),
// height: 0
},
})
this.polygon.GeoType = "Polygon"
this.viewer.entities.add(this.polygon)
}
this.viewer.scene.requestRender()
//将鼠标点击的点添加到多边形顶点集合中
this.activeShapePoints.push(earthPosition)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
//鼠标移动--实时绘制多边形
this.handler.setInputAction((movement) => {
//获取鼠标所在的位置
const ray = this.viewer.camera.getPickRay(movement.endPosition)
const newPosition = this.viewer.scene.globe.pick(ray, this.viewer.scene)
//已经定义了polygon
if (Cesium.defined(this.polygon)) {
//删除多边形顶点中最新的一个点
this.activeShapePoints.pop()
//将最新获取到的点添加到多边形顶点集合中
this.activeShapePoints.push(newPosition)
}
if (this.activeShapePoints.length === 3) {
this.polygon.polygon.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//鼠标右键--结束绘制
this.handler.setInputAction((event) => {
//删除最后一个点(重复添加的点)
this.activeShapePoints.pop()
this.polygon.pottingPoint = this.activeShapePoints
this._showResultArea()
this.stopAreaMeasure()
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}
_showResultArea(){
let text = "面积:" + this.getPolygonArea(this.polygon.pottingPoint)
let centerPoint = this._getCenterOfGravityPoint(this.polygon.pottingPoint)
this._addLabel(centerPoint, text)
}
/*角度*/
_Angle(p1, p2, p3) {
let angle =this._Bearing(p2, p1) - this._Bearing(p2, p3);
if (angle < 0) {
angle += 360;
}
return angle;
}
/*方向*/
_Bearing(from, to) {
from = Cesium.Cartographic.fromCartesian(from);
to = Cesium.Cartographic.fromCartesian(to);
let lat1 = from.latitude;
let lon1 = from.longitude;
let lat2 = to.latitude;
let lon2 = to.longitude;
let angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
if (angle < 0) {
angle += Math.PI * 2.0;
}
return Cesium.Math.toDegrees(angle)
}
distance(point1, point2) {
let point1cartographic = Cesium.Cartographic.fromCartesian(point1);
let point2cartographic = Cesium.Cartographic.fromCartesian(point2);
/**根据经纬度计算出距离**/
let geodesic = new Cesium.EllipsoidGeodesic();
geodesic.setEndPoints(point1cartographic, point2cartographic);
let s = geodesic.surfaceDistance;
//返回两点之间的距离
s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
return s;
}
getPolygonArea(points){
let res = 0;
//拆分三角曲面
for (let i = 0; i < points.length - 2; i++) {
let j = (i + 1) % points.length;
let k = (i + 2) % points.length;
let totalAngle = this._Angle(points[i], points[j], points[k]);
let dis_temp1 = this.distance(points[j], points[0]);
let dis_temp2 = this.distance(points[k], points[0]);
res += dis_temp1 * dis_temp2 * Math.sin(totalAngle) / 2;
}
if (res < 1000000) {
res = Math.abs(res).toFixed(4) + " 平方米";
} else {
res = Math.abs(res / 1000000.0).toFixed(4) + " 平方公里";
}
return res
}
_getCenterOfGravityPoint(mPoints){
let centerPoint = mPoints[0];
for (let i = 1; i < mPoints.length; i++) {
centerPoint = Cesium.Cartesian3.midpoint(centerPoint, mPoints[i], new Cesium.Cartesian3());
}
return centerPoint
}
_addLabel(centerPoint, text){
return this.viewer.entities.add(
new Cesium.Entity({
name: 'area label',
id: '4390',
position: centerPoint,
label:{
text: text,
font: "2.5rem sans-serif",
fillColor: Cesium.Color.WHITE,
style: Cesium.LabelStyle.FILL,
eyeOffset: new Cartesian3(0,0,50),
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.CENTER,
scale: 0.4,
showBackground: true,
backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.99),
backgroundPadding: new Cesium.Cartesian2(15, 7),
clampToGround: true,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance:99000000,
},
})
)
}
// -------------------------------------------//
//激活测距
activate() {
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
this.viewer.scene.globe.depthTestAgainstTerrain = true
this.registerEvents(); //注册鼠标事件
this.isMeasure = true;
this.totalDistance = 0 // 总距离
//设置鼠标样式
this.viewer._element.style.cursor = 'crosshair';
this.viewer.enableCursorStyle = true;
this.temPositions = [];
this.positions = [];
}
//禁用测距
deactivate() {
if (!this.isMeasure) return;
this.unRegisterEvents();
this.viewer._element.style.cursor = 'default';
this.viewer.enableCursorStyle = true;
this.isMeasure = false;
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 = [] // 距离测量折线元素数组,每完成一次距离测量,将折线元素加入此数组
this.totalDistance = 0 // 总距离
}
//创建线对象(测距)
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,
},
})
this.viewer.scene.requestRender()
}
//创建线节点(测距)
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),
clampToGround: true,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance:99000000,
},
});
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,
clampToGround: true,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance:99000000,
},
});
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,
scale: 0.4,
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
},
point: {
pixelSize: 10,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 1,
clampToGround: true,
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.clearDisEntity()
} 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);
}
clearDraw(){
if(this.graphics.length<1)
return true;
this._stopDraw();
this.graphics.forEach(graphic => {
this.viewer.entities.remove(graphic)
})
this.graphics = []
}
/********************** 实时图形绘制 ***************************************/
drawGraphics(key){
this.viewer.scene.globe.depthTestAgainstTerrain = true
// 清除可能会用到的监听事件
if (this.handler) {
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
this.handler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas)
this.viewer._element.style.cursor = 'crosshair';
this.viewer.enableCursorStyle = true;
if(key==='polygon'){
this._drawPolygon()
}
else if(key==='rec'){
this._drawRec()
}
else if(key==='circle'){
this._drawCircle()
}
}
_stopDraw(){
this.viewer.scene.globe.depthTestAgainstTerrain = false
// 清除可能会用到的监听事件
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
this.viewer._element.style.cursor = 'default';
this.viewer.enableCursorStyle = true;
}
_drawPolygon(){
let aPolygon;
let drawPolygonPts = []
//鼠标左键--确定选中点
this.handler.setInputAction((event) => {
let ray = this.viewer.camera.getPickRay(event.position);
let earthPosition = this.scene.globe.pick(ray, this.scene)
//鼠标开始点击多边形的第一个点
if (drawPolygonPts.length === 0) {
//将第一个左击的点添加到多边形顶点集合中
drawPolygonPts.push(earthPosition)
//多边形的坐标采用回调的形式
//边线顶点
let linePoints = new Cesium.CallbackProperty(() => {
return drawPolygonPts.concat([drawPolygonPts[0]]);
}, false)
//多边形顶点
let dynamicPositions = new Cesium.CallbackProperty(() => {
return new Cesium.PolygonHierarchy(drawPolygonPts)
}, false)
//添加一个多边形
aPolygon = this.viewer.entities.add({
name: "draw polygon",
polyline: {
positions: linePoints,
width: this.graphicStyle.borderWidth,
material: this.graphicStyle.borderColor,
clampToGround: true
},
polygon: {
hierarchy: dynamicPositions,
material: this.graphicStyle.material,
heightReference: Cesium.HeightReference.NONE
},
})
}
this.viewer.scene.requestRender()
//将鼠标点击的点添加到多边形顶点集合中
drawPolygonPts.push(earthPosition)
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
//鼠标移动--实时绘制多边形
this.handler.setInputAction((movement) => {
//获取鼠标所在的位置
const ray = this.viewer.camera.getPickRay(movement.endPosition)
const newPosition = this.viewer.scene.globe.pick(ray, this.viewer.scene)
//已经定义了polygon
if (Cesium.defined(aPolygon)) {
//删除多边形顶点中最新的一个点
drawPolygonPts.pop()
//将最新获取到的点添加到多边形顶点集合中
drawPolygonPts.push(newPosition)
}
if (drawPolygonPts.length === 3) {
aPolygon.polygon.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
//鼠标右键--结束绘制
this.handler.setInputAction((event) => {
//删除最后一个点(重复添加的点)
drawPolygonPts.pop()
drawPolygonPts.push(drawPolygonPts[0])
aPolygon.polyline.positions = drawPolygonPts;
aPolygon.polygon.hierarchy = new Cesium.PolygonHierarchy(drawPolygonPts);
this.graphics.push(aPolygon)
this._stopDraw()
// geojson2kml(this.entity2Geojson(aPolygon))
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}
_drawRec(){
let aPolygon = undefined;
let westSouthEastNorth = []
let lat1, lng1, lat, lng
let rec_polyline = new Cesium.CallbackProperty(function () {
return Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth, Cesium.Ellipsoid.WGS84,undefined)
}, false)
let rec_polygon = new Cesium.CallbackProperty(function () {
return {
positions: Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth, Cesium.Ellipsoid.WGS84,undefined)
}
}, false)
this.handler.setInputAction(event => {
/**点击位置笛卡尔坐标 */
let cartesian = this.viewer.camera.pickEllipsoid(event.position, this.viewer.scene.globe.ellipsoid)
/**笛卡尔转弧度坐标 */
let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
/**点击位置经度 */
lng1 = Cesium.Math.toDegrees(cartographic.longitude)
/**点击位置维度 */
lat1 = Cesium.Math.toDegrees(cartographic.latitude)
/**边框坐标 */
westSouthEastNorth = [lng1, lat1]
/**面实例对象 */
if(!aPolygon){
aPolygon = this.viewer.entities.add({
name: 'rectangle',
polygon: {
hierarchy: rec_polygon,
height: 0,
// 填充的颜色withAlpha透明度
material: this.graphicStyle.material,
// 是否被提供的材质填充
fill: true,
// 是否显示
show: true,
},
polyline: {
positions: rec_polyline,
material: this.graphicStyle.borderColor,
width: this.graphicStyle.borderWidth,
zIndex: 1
}
})
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
this.handler.setInputAction((move) => {
if(westSouthEastNorth.length > 0){
let cartesian = this.viewer.camera.pickEllipsoid(move.endPosition, this.viewer.scene.globe.ellipsoid)
let cartographic = Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic())
lng = Cesium.Math.toDegrees(cartographic.longitude)
lat = Cesium.Math.toDegrees(cartographic.latitude)
westSouthEastNorth = [lng1, lat1, lng1, lat, lng, lat, lng, lat1, lng1, lat1]
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
this.handler.setInputAction(() => {
if (aPolygon) {
aPolygon.polygon.hierarchy = new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth, Cesium.Ellipsoid.WGS84));
aPolygon.polyline.positions = Cesium.Cartesian3.fromDegreesArray(westSouthEastNorth, Cesium.Ellipsoid.WGS84,undefined)
this.viewer.scene.requestRender()
this.graphics.push(aPolygon)
this._stopDraw()
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}
_drawCircle(){
/**圆半径 */
let centerPoint = null;
let radius = 0.0;
let aPolygon = undefined;
this.handler.setInputAction(event => {
if(centerPoint==null) {
let ray = this.viewer.camera.getPickRay(event.position);
centerPoint = this.scene.globe.pick(ray, this.scene)
aPolygon = this.viewer.entities.add({
position: centerPoint,
name: 'draw circle',
ellipse: {
height: 30,
material: this.graphicStyle.material,
outline: true,
outlineColor: this.graphicStyle.borderColor,
outlineWidth: this.graphicStyle.borderWidth,
fill: true,
semiMajorAxis: new Cesium.CallbackProperty(() => {
return radius
}, false),
semiMinorAxis: new Cesium.CallbackProperty(() => {
return radius
}, false)
}
})
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
this.handler.setInputAction((move) => {
if(centerPoint){
let cartesian2 = this.viewer.camera.pickEllipsoid(move.endPosition, this.viewer.scene.globe.ellipsoid)
radius = Cesium.Cartesian3.distance(centerPoint, cartesian2)
this.viewer.scene.requestRender()
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
this.handler.setInputAction(() => {
if (centerPoint !== null && radius > 0) {
this.viewer.scene.requestRender()
this.graphics.push(aPolygon)
this._stopDraw()
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}
_createPointEntity(position, label=""){
return new Cesium.Entity({
position: position,
point: {
pixelSize: 4,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 1,
disableDepthTestDistance:99000000,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
},
label: {
text: label,
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,
scale: 0.5,
clampToGround: true,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance:99000000,
},
})
}
}