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, }, }) } }