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