import * as DT from 'dt-sdk' import * as turf from '@turf/turf' export default class LineTargetBack { polyline = null pointCollection = {} uavEntity = null moveActive = false moveStartActive = false moveEndActive = false showTemp = true tempCollection = [] labelPixelOffset = new DT.Cesium.Cartesian2(10, 0) constructor (info) { this.viewer = info.viewer this.name = info.name this.id = info.id ? info.id : new Date().getTime() this.duringDraw = false this.hasMove = false this.positions = [] this.callback = info.callback this.endCallback = info.endCallback this.baseHeight = info.baseHeight ? info.baseHeight : 250 this.angle = info.angle ? info.angle : 20 this.rotation = info.rotation ? info.rotation : 20 } startPick() { if (this.duringDraw) return if (!this.handler) { this.handler = new DT.Cesium.ScreenSpaceEventHandler( this.viewer.cesiumViewer.scene.canvas ) } let that = this this.handler.setInputAction(evt => { let cartesian = that.getCartesian3FromPXHeight(evt.position) if (cartesian) { if (that.positions.length === 0) { that.positions.push(cartesian.clone()) that.positions.push(cartesian.clone()) that.createMark(cartesian.clone(), true) if (that.callback) { that.callback(cartesian.clone()) } that.hasMove = false } else { that.handler.removeInputAction(DT.Cesium.ScreenSpaceEventType.MOUSE_MOVE) that.handler.removeInputAction(DT.Cesium.ScreenSpaceEventType.LEFT_CLICK) that.handler.removeInputAction(DT.Cesium.ScreenSpaceEventType.RIGHT_CLICK) if (that.hasMove) { that.positions.pop() } that.positions.push(cartesian.clone()) that.createMark(cartesian.clone(), false) that.addUav() that.addWave() that.endPick() that.addMoveHandler() } } }, DT.Cesium.ScreenSpaceEventType.LEFT_CLICK) this.handler.setInputAction(evt => { //移动时绘制线 if (that.positions.length < 1) return let cartesian = that.getCartesian3FromPXHeight(evt.endPosition) if (cartesian) { that.hasMove = true if (!that.polyline) { that.createPolyline() } else { that.positions.pop() that.positions.push(cartesian.clone()) } that.tempPositions = cartesian.clone() // that.createTempMark(cartesian.clone()) } }, DT.Cesium.ScreenSpaceEventType.MOUSE_MOVE) this.handler.setInputAction(evt => { }, DT.Cesium.ScreenSpaceEventType.RIGHT_CLICK) this.duringDraw = true } endPick() { this.duringDraw = false this.hasMove = false if (this.endCallback) { // this.endCallback([].concat(this.positions)) this.dealEndCallback() } } dealEndCallback() { let distanceOne = 100 // 航线点到开机点距离 let distanceTwo = 100 // 开机点到拍摄点 let lineLength = this.baseHeight / Math.cos(this.rotation * Math.PI / 180) distanceTwo = 13 * Math.PI * lineLength / 180 // 求开机点 let endToStartDirection = new DT.Cesium.Cartesian3(1, 0, 0) DT.Cesium.Cartesian3.subtract(this.positions[0], this.positions[1], endToStartDirection) DT.Cesium.Cartesian3.normalize(endToStartDirection, endToStartDirection) let openToStart = new DT.Cesium.Cartesian3() // 开机点 let flyToStart = new DT.Cesium.Cartesian3() // 航线起点 DT.Cesium.Cartesian3.multiplyByScalar(endToStartDirection, distanceTwo, openToStart) DT.Cesium.Cartesian3.multiplyByScalar(endToStartDirection, distanceOne + distanceTwo, flyToStart) DT.Cesium.Cartesian3.add(openToStart, this.positions[0], openToStart) DT.Cesium.Cartesian3.add(flyToStart, this.positions[0], flyToStart) // console.log('开机点', openToStart) // let cat1 = DT.Cesium.Cartographic.fromCartesian(openToStart) // let cat2 = DT.Cesium.Cartographic.fromCartesian(flyToStart) // console.log('开机点高度', cat1.height , cat2.height) // 求关机点 let startToEndDirection = new DT.Cesium.Cartesian3(1, 0, 0) DT.Cesium.Cartesian3.subtract(this.positions[1], this.positions[0], startToEndDirection) DT.Cesium.Cartesian3.normalize(startToEndDirection, startToEndDirection) let openToEnd = new DT.Cesium.Cartesian3() // 开机点 let flyToEnd = new DT.Cesium.Cartesian3() // 航线起点 DT.Cesium.Cartesian3.multiplyByScalar(startToEndDirection, distanceTwo, openToEnd) DT.Cesium.Cartesian3.multiplyByScalar(startToEndDirection, distanceOne + distanceTwo, flyToEnd) DT.Cesium.Cartesian3.add(openToEnd, this.positions[1], openToEnd) DT.Cesium.Cartesian3.add(flyToEnd, this.positions[1], flyToEnd) // console.log('关机点', openToEnd) // 求成像区域中心经度,成像区域中心维度 let boundaryLonLat = [] if (this.wave.crossPositions.length > 3) { this.wave.crossPositions.forEach((item, index) => { if (index < 4) { let cat = DT.Cesium.Cartographic.fromCartesian(item) boundaryLonLat.push({ longitude: DT.Cesium.Math.toDegrees(cat.longitude), latitude: DT.Cesium.Math.toDegrees(cat.latitude) }) // boundaryLonLat.push([DT.Cesium.Math.toDegrees(cat.longitude), DT.Cesium.Math.toDegrees(cat.latitude)]) } }) let lon = 0 let lat = 0 boundaryLonLat.forEach(item => { lon += item.longitude lat += item.latitude }) let center = [lon / 4, lat / 4] // 中心点坐标 // console.log('中心区域', center) let areaEndCenter = DT.Cesium.Cartesian3.fromDegrees( (boundaryLonLat[0].longitude + boundaryLonLat[1].longitude) / 2, (boundaryLonLat[0].latitude + boundaryLonLat[1].latitude) / 2) let areaStartCenter = DT.Cesium.Cartesian3.fromDegrees( (boundaryLonLat[2].longitude + boundaryLonLat[3].longitude) / 2, (boundaryLonLat[2].latitude + boundaryLonLat[3].latitude) / 2) // 求地面开机点 let groundEndToStartDirection = new DT.Cesium.Cartesian3(1, 0, 0) DT.Cesium.Cartesian3.subtract(areaStartCenter, areaEndCenter, groundEndToStartDirection) DT.Cesium.Cartesian3.normalize(groundEndToStartDirection, groundEndToStartDirection) let groundOpenToStart = new DT.Cesium.Cartesian3() // 开机点 DT.Cesium.Cartesian3.multiplyByScalar(groundEndToStartDirection, distanceTwo, groundOpenToStart) DT.Cesium.Cartesian3.add(groundOpenToStart, areaStartCenter, groundOpenToStart) // console.log('地面开机', groundOpenToStart) // 求地面关机点 // let groundStartToEndDirection = new DT.Cesium.Cartesian3(1, 0, 0) // DT.Cesium.Cartesian3.subtract(areaEndCenter, areaStartCenter, groundStartToEndDirection) // DT.Cesium.Cartesian3.normalize(groundStartToEndDirection, groundStartToEndDirection) // let groundOpenToEnd = new DT.Cesium.Cartesian3() // 开机点 // DT.Cesium.Cartesian3.multiplyByScalar(groundStartToEndDirection, distanceTwo, groundOpenToEnd) // DT.Cesium.Cartesian3.add(groundOpenToEnd, areaEndCenter, groundOpenToEnd) // console.log('地面关机', groundOpenToEnd) // 成像区域幅宽和方位长度 let width = DT.Cesium.Cartesian3.distance(this.wave.crossPositions[0], this.wave.crossPositions[1]) let length = DT.Cesium.Cartesian3.distance(this.wave.crossPositions[1], this.wave.crossPositions[2]) // console.log('幅宽', width, length) // 轴向角度 let point1 = turf.point([boundaryLonLat[1].longitude, boundaryLonLat[1].latitude]); let point2 = turf.point([boundaryLonLat[2].longitude, boundaryLonLat[2].latitude]); let bearing = turf.bearing(point1, point2) + 180 // console.log('角度12', bearing) // console.log('高度123', this.viewer.cesiumViewer.terrainProvider) // DT.Cesium.sampleTerrainMostDetailed(this.viewer.cesiumViewer.terrainProvider, [DT.Cesium.Cartographic.fromDegrees(center[0], center[1])]).then(res => { // console.log('海拔', res) // }) let startCat = DT.Cesium.Cartographic.fromCartesian(flyToStart) let endCat = DT.Cesium.Cartographic.fromCartesian(flyToEnd) let sarStartCat = DT.Cesium.Cartographic.fromCartesian(openToStart) let sarEndCat = DT.Cesium.Cartographic.fromCartesian(openToEnd) let groundOpenToStartCat = DT.Cesium.Cartographic.fromCartesian(groundOpenToStart) let info = { flightStartLon: DT.Cesium.Math.toDegrees(sarStartCat.longitude), flightStartLat: DT.Cesium.Math.toDegrees(sarStartCat.latitude), flightStartHeight: this.baseHeight, flightEndLon: DT.Cesium.Math.toDegrees(sarEndCat.longitude), flightEndLat: DT.Cesium.Math.toDegrees(sarEndCat.latitude), flightEndHeight: this.baseHeight, groundStartLon: DT.Cesium.Math.toDegrees(groundOpenToStartCat.longitude), groundStartLat: DT.Cesium.Math.toDegrees(groundOpenToStartCat.latitude), groundStartHeight: 0, startLon: DT.Cesium.Math.toDegrees(startCat.longitude), startLat: DT.Cesium.Math.toDegrees(startCat.latitude), startHeight: this.baseHeight, endLon: DT.Cesium.Math.toDegrees(endCat.longitude), endLat: DT.Cesium.Math.toDegrees(endCat.latitude), endHeight: this.baseHeight, targetCentroidLon: center[0], targetCentroidLat: center[1], targetCentroidHeight: 0, targetWidth: width, targetLength: length, targetHeading: bearing, squintAngle: 0, grazingAngle: 90 - this.rotation, flightType: '0', // 航线类型 polarization: '4', // 极化方式 id: this.id, boundaryLonLat: boundaryLonLat, } console.log('最后参数', info) if (this.showTemp) { this.tempCollection.forEach(temp => { viewer.entities.remove(temp) }) this.tempCollection = [] let openToStartEntity = this.viewer.entities.add({ position: openToStart, point: { pixelSize: 8, disableDepthTestDistance: 20000 }, label: { show: true, text: '开机点', font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 } }) let flyToStartEntity = this.viewer.entities.add({ position: flyToStart, point: { pixelSize: 8, disableDepthTestDistance: 20000 }, label: { show: true, text: '航线起点', font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 } }) this.tempCollection.push(openToStartEntity) this.tempCollection.push(flyToStartEntity) let openToEndEntity = this.viewer.entities.add({ position: openToEnd, point: { pixelSize: 8, disableDepthTestDistance: 20000 }, label: { show: true, text: '关机点', font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 } }) let flyToEndEntity = this.viewer.entities.add({ position: flyToEnd, point: { pixelSize: 8, disableDepthTestDistance: 20000 }, label: { show: true, text: '航线终点', font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 } }) this.tempCollection.push(openToEndEntity) this.tempCollection.push(flyToEndEntity) let centerEntity = this.viewer.entities.add({ position: DT.Cesium.Cartesian3.fromDegrees(center[0], center[1]), point: { pixelSize: 8, disableDepthTestDistance: 20000 }, label: { show: true, text: '中心点', font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 } }) this.tempCollection.push(centerEntity) let groundOpenToStartEntity = this.viewer.entities.add({ position: groundOpenToStart, point: { pixelSize: 8, disableDepthTestDistance: 20000 }, label: { show: true, text: '地面开机点', font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 } }) this.tempCollection.push(groundOpenToStartEntity) let areaStartCenterEntity = this.viewer.entities.add({ position: areaStartCenter, point: { pixelSize: 8, disableDepthTestDistance: 20000 }, label: { show: true, text: '地面中心点1', font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 } }) this.tempCollection.push(areaStartCenterEntity) let areaEndCenterEntity = this.viewer.entities.add({ position: areaEndCenter, point: { pixelSize: 8, disableDepthTestDistance: 20000 }, label: { show: true, text: '地面中心点2', font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 } }) this.tempCollection.push(areaEndCenterEntity) } this.endCallback(info) } } createMark(position, start = true) { let cat = DT.Cesium.Cartographic.fromCartesian(position) let lon = Math.round(DT.Cesium.Math.toDegrees(cat.longitude) * 10000000000000) / 10000000000000 let lat = Math.round(DT.Cesium.Math.toDegrees(cat.latitude) * 10000000000000) / 10000000000000 let text = start ? '起点' : '终点' let idName = start ? 'start' : 'end' let index = start ? 0 : 1 let that = this let entity = new DT.Cesium.Entity({ id: `${this.id}-${idName}`, position: new DT.Cesium.CallbackProperty(function () { return that.positions[index] }, false), // billboard: { // show: true, // image: this.markImage, // width: this.markImageWidth, // height: this.markImageHeight, // disableDepthTestDistance: 20000, // verticalOrigin: DT.Cesium.VerticalOrigin.BASELINE, // pixelOffset: this.billboardPixelOffset // }, label: { show: true, text: text, font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 }, point: { pixelSize: 10, color: DT.Cesium.Color.WHITE, disableDepthTestDistance: 20000 } }) this.viewer.entities.add(entity) let key = start ? 'start' : 'end' this.pointCollection[key] = entity } createPolyline() { if (this.polyline) { this.viewer.entities.remove(this.polyline) this.polyline = null } let that = this this.polyline = this.viewer.entities.add({ polyline: { //使用cesium的peoperty positions: new DT.Cesium.CallbackProperty(function () { return that.positions }, false), show: true, material: DT.Cesium.Color.WHITE, width: 2, } }) } addUav() { let middlePosition = new DT.Cesium.Cartesian3() DT.Cesium.Cartesian3.midpoint(this.positions[0], this.positions[1], middlePosition) this.middlePosition = middlePosition this.uavEntity = this.viewer.entities.add({ id: `${this.id}-uav`, position: middlePosition, label: { text: this.name, font: '24px', showBackground: true, backgroundColor: DT.Cesium.Color.fromCssColorString('rgba(0,0,0,0.7)'), fillColor: DT.Cesium.Color.WHITE, horizontalOrigin: DT.Cesium.HorizontalOrigin.LEFT, pixelOffset: this.labelPixelOffset, disableDepthTestDistance: 20000 }, model: { uri: process.env.BASE_URL + 'model/uav.gltf', // scale: 1, minimumPixelSize: 64, maximumScale: 128, shadows: DT.Cesium.ShadowMode.DISABLED }, }) } changeWaveAngle(value) { this.angle = value if (this.wave) { this.viewer.primitives.remove(this.wave.primitive) this.viewer.entities.remove(this.wave.crossLine) } // this.addWave() } updateHeightAndAngle(options) { // 高度改变了 if (this.baseHeight !== options.baseHeight) { this.baseHeight = options.baseHeight let arr = [] this.positions.forEach(position => { let cat = DT.Cesium.Cartographic.fromCartesian(position) arr.push(DT.Cesium.Cartesian3.fromRadians(cat.longitude, cat.latitude, this.baseHeight)) }) this.positions = arr // this.endCallback([].concat(this.positions)) let middlePosition = new DT.Cesium.Cartesian3() DT.Cesium.Cartesian3.midpoint(this.positions[0], this.positions[1], middlePosition) this.uavEntity.position = middlePosition } this.rotation = options.rotation this.angle = options.angle if (this.wave) { this.viewer.primitives.remove(this.wave.primitive) this.viewer.entities.remove(this.wave.crossLine) } // this.addWave() if (this.endCallback) { this.dealEndCallback() } } changeWaveRotation(value) { this.rotation = value if (this.wave) { this.viewer.primitives.remove(this.wave.primitive) this.viewer.entities.remove(this.wave.crossLine) } // this.addWave() if (this.endCallback) { this.dealEndCallback() } } addWave() { this.wave = new LineWave({viewer: this.viewer, startPosition: this.positions[0], endPosition: this.positions[1], angle: this.angle, rotation: this.rotation}) this.viewer.primitives.add(this.wave.primitive) this.viewer.entities.add(this.wave.crossLine) } addMoveHandler() { if (!this.moveHandler) { this.moveHandler = new DT.Cesium.ScreenSpaceEventHandler( this.viewer.cesiumViewer.scene.canvas ) } this.moveHandler.setInputAction(evt => { let pick = this.viewer.cesiumViewer.scene.pick(evt.position) if (pick && pick.id && pick.id.id && pick.id.id === `${this.id}-uav`) { this.moveActive = true this.viewer.cesiumViewer.scene.screenSpaceCameraController.enableRotate = false;//锁定相机 } if (pick && pick.id && pick.id.id && pick.id.id === `${this.id}-start`) { this.moveStartActive = true this.viewer.cesiumViewer.scene.screenSpaceCameraController.enableRotate = false;//锁定相机 } if (pick && pick.id && pick.id.id && pick.id.id === `${this.id}-end`) { this.moveEndActive = true this.viewer.cesiumViewer.scene.screenSpaceCameraController.enableRotate = false;//锁定相机 } }, DT.Cesium.ScreenSpaceEventType.LEFT_DOWN) this.moveHandler.setInputAction(evt => { if (this.moveActive) { let cartesian = this.getCartesian3FromPXHeight(evt.endPosition) if (cartesian) { this.updatePosition(cartesian.clone()) } } if (this.moveStartActive) { let cartesian = this.getCartesian3FromPXHeight(evt.endPosition) if (cartesian) { this.updatePointPosition(cartesian.clone(), 0) } } if (this.moveEndActive) { let cartesian = this.getCartesian3FromPXHeight(evt.endPosition) if (cartesian) { this.updatePointPosition(cartesian.clone(), 1) } } }, DT.Cesium.ScreenSpaceEventType.MOUSE_MOVE) this.moveHandler.setInputAction(evt => { if (this.moveActive || this.moveEndActive || this.moveStartActive) { if (this.endCallback) { this.dealEndCallback() } } if (this.moveActive) { // let cartesian = this.getCartesian3FromPXHeight(evt.position) // if (cartesian) { // this.updatePosition(cartesian.clone()) // } this.moveActive = false this.viewer.cesiumViewer.scene.screenSpaceCameraController.enableRotate = true;//锁定相机 } if (this.moveStartActive) { // let cartesian = this.getCartesian3FromPXHeight(evt.position) // if (cartesian) { // this.updatePointPosition(cartesian.clone(), 0) // } this.moveStartActive = false this.viewer.cesiumViewer.scene.screenSpaceCameraController.enableRotate = true;//锁定相机 } if (this.moveEndActive) { // let cartesian = this.getCartesian3FromPXHeight(evt.position) // if (cartesian) { // this.updatePointPosition(cartesian.clone(), 0) // } this.moveEndActive = false this.viewer.cesiumViewer.scene.screenSpaceCameraController.enableRotate = true;//锁定相机 } }, DT.Cesium.ScreenSpaceEventType.LEFT_UP) } updatePosition(cartesian) { let oldPosition = this.uavEntity.position._value.clone() let modify = new DT.Cesium.Cartesian3(0,0,0) DT.Cesium.Cartesian3.subtract(cartesian, oldPosition, modify) this.uavEntity.position = cartesian.clone() let oldPositions = [this.positions[0].clone(), this.positions[1].clone()] DT.Cesium.Cartesian3.add(oldPositions[0], modify, this.positions[0]) DT.Cesium.Cartesian3.add(oldPositions[1], modify, this.positions[1]) if (this.wave) { this.viewer.primitives.remove(this.wave.primitive) this.viewer.entities.remove(this.wave.crossLine) } this.addWave() } updatePointPosition(cartesian, index) { this.positions[index] = cartesian.clone() let middlePosition = new DT.Cesium.Cartesian3() DT.Cesium.Cartesian3.midpoint(this.positions[0], this.positions[1], middlePosition) this.uavEntity.position = middlePosition if (this.wave) { this.viewer.primitives.remove(this.wave.primitive) this.viewer.entities.remove(this.wave.crossLine) } this.addWave() } getCartesian3FromPX(px) { let cartesian let ray = this.viewer.cesiumViewer.camera.getPickRay(px) if (!ray) return null cartesian = this.viewer.cesiumViewer.scene.globe.pick(ray, this.viewer.cesiumViewer.scene) if (!cartesian) { cartesian = this.viewer.cesiumViewer.camera.pickEllipsoid(px, this.viewer.cesiumViewer.scene.globe.ellipsoid) } if (cartesian) { let cat = DT.Cesium.Cartographic.fromCartesian(cartesian) let modify = DT.Cesium.Cartesian3.fromRadians(cat.longitude, cat.latitude, this.baseHeight) return modify } else { return null } // return cartesian } getCartesian3FromPXHeight(px) { let cartesian let ray = this.viewer.cesiumViewer.camera.getPickRay(px) if (!ray) return null cartesian = this.viewer.cesiumViewer.scene.globe.pick(ray, this.viewer.cesiumViewer.scene) if (cartesian && this.viewer.cesiumViewer.camera.positionCartographic.height > 0) { let ratio = this.baseHeight / this.viewer.cesiumViewer.camera.positionCartographic.height let result = new DT.Cesium.Cartesian3() DT.Cesium.Cartesian3.lerp(cartesian, this.viewer.cesiumViewer.camera.positionWC, ratio, result) // let cat = DT.Cesium.Cartographic.fromCartesian(result) // console.log('拾取的位置相机', cat.height ) return result } // return cartesian } destroy() { for (let key in this.pointCollection) { this.viewer.entities.remove(this.pointCollection[key]) } this.pointCollection = null if (this.polyline) { this.viewer.entities.remove(this.polyline) this.polyline = null } if (this.wave) { this.viewer.primitives.remove(this.wave.primitive) this.viewer.entities.remove(this.wave.crossLine) this.wave = null } if (this.uavEntity) { this.viewer.entities.remove(this.uavEntity) } if (this.moveHandler) { this.moveHandler.destroy() this.moveHandler = null } if (this.handler) { this.handler.destroy() this.handler = null } this.tempCollection.forEach(temp => { viewer.entities.remove(temp) }) this.tempCollection = [] } } export class LineWave { color = DT.Cesium.Color.CYAN.withAlpha(0.1) outlineColor = DT.Cesium.Color.RED crossPositions = [] constructor(options) { this.startPosition = options.startPosition this.endPosition = options.endPosition this.viewer = options.viewer this.middlePosition = new DT.Cesium.Cartesian3() this.lineLength = DT.Cesium.Cartesian3.distance(this.startPosition, this.endPosition) this.length = options.length ? options.length : 100000 DT.Cesium.Cartesian3.midpoint(this.startPosition, this.endPosition, this.middlePosition) this.angle = options.angle ? options.angle : 40 console.log('角度是啥', this.angle) this.rotation = typeof options.rotation === 'number' ? options.rotation : 0 let halfAngleRadians = Math.PI * this.angle / 180 this.bottomHorizontalLength = Math.tan(halfAngleRadians) * this.length this.bottomVerticalLength = this.lineLength this.createWave() this.createEdge() } createWave() { let positiveX = new DT.Cesium.Cartesian3(this.lineLength / 2, 0, 0) let negativeX = new DT.Cesium.Cartesian3(-this.lineLength / 2, 0, 0) let topLeft = new DT.Cesium.Cartesian3(this.lineLength / 2, this.bottomHorizontalLength, -this.length) let topRight = new DT.Cesium.Cartesian3(this.lineLength / 2, -this.bottomHorizontalLength, -this.length) let bottomLeft = new DT.Cesium.Cartesian3(-this.lineLength / 2, this.bottomHorizontalLength, -this.length) let bottomRight = new DT.Cesium.Cartesian3(-this.lineLength / 2, -this.bottomHorizontalLength, -this.length) let rawVertex = [ // 上三角 ...DT.Cesium.Cartesian3.pack(positiveX, new Array(3)), ...DT.Cesium.Cartesian3.pack(topLeft, new Array(3)), ...DT.Cesium.Cartesian3.pack(topRight, new Array(3)), // 下三角 ...DT.Cesium.Cartesian3.pack(negativeX, new Array(3)), ...DT.Cesium.Cartesian3.pack(bottomLeft, new Array(3)), ...DT.Cesium.Cartesian3.pack(bottomRight, new Array(3)), ] const positions = new Float64Array(rawVertex); // 4 定义索引 // const indices = new Uint16Array([0, 1, 2, 3, 4, 5, 0, 1, 4, 1, 3, 4, 0, 2, 3, 0, 3, 5, 1, 2, 4, 1, 4, 5]) const indices = new Uint16Array([0, 1, 2, 3, 4, 5, 0, 1, 4, 0, 3, 4, 0, 2, 5, 0, 3, 5, 1, 2, 5, 1, 5, 4]) // const indices = new Uint16Array([ 1, 2, 4, 2, 4, 5]) const outlineIndices = new Uint16Array([0, 1, 0, 2, 3, 4, 3, 5]); let geometry = new DT.Cesium.Geometry({ attributes: { position: new DT.Cesium.GeometryAttribute({ componentDatatype: DT.Cesium.ComponentDatatype.DOUBLE, componentsPerAttribute: 3, values: positions }), }, indices: indices, primitiveType: DT.Cesium.PrimitiveType.TRIANGLES, boundingSphere: DT.Cesium.BoundingSphere.fromPoints([positiveX, negativeX, bottomLeft, bottomRight, topLeft, topRight]), }); let outlineGeometry = new DT.Cesium.Geometry({ attributes: { position: new DT.Cesium.GeometryAttribute({ componentDatatype: DT.Cesium.ComponentDatatype.DOUBLE, componentsPerAttribute: 3, values: positions }) }, indices: outlineIndices, primitiveType: DT.Cesium.PrimitiveType.LINES, boundingSphere: DT.Cesium.BoundingSphere.fromPoints([positiveX, negativeX, bottomLeft, bottomRight, topLeft, topRight]) }) let que = DT.Tool.calculateQuaternionFromV1ToV2(this.startPosition, this.endPosition) console.log('角度', this.rotation) let rotationQuaternion = DT.Cesium.Quaternion.fromAxisAngle(DT.Cesium.Cartesian3.UNIT_X, this.rotation * Math.PI / 180) console.log('四元数', rotationQuaternion) let combineQuaternion = new DT.Cesium.Quaternion() DT.Cesium.Quaternion.multiply(que, rotationQuaternion, combineQuaternion) let rotation = DT.Cesium.Matrix4.fromTranslationQuaternionRotationScale(this.middlePosition, combineQuaternion, DT.Cesium.Cartesian3.ONE) let geometryInstance = new DT.Cesium.GeometryInstance({ geometry: geometry, modelMatrix: rotation, attributes: { color: DT.Cesium.ColorGeometryInstanceAttribute.fromColor(this.color) } }); this.primitive = new DT.Cesium.Primitive({ geometryInstances: geometryInstance, // modelMatrix: matrix, appearance: new DT.Cesium.PerInstanceColorAppearance({ flat: true }), asynchronous: false, show: true }); // let outlineGeometryInstance = new DT.Cesium.GeometryInstance({ // geometry: outlineGeometry, // modelMatrix: rotation, // attributes: { // color: DT.Cesium.ColorGeometryInstanceAttribute.fromColor(this.outlineColor) // } // }); // this.linePrimitive } createEdge() { let positiveX = new DT.Cesium.Cartesian3(this.lineLength / 2, 0, 0) let negativeX = new DT.Cesium.Cartesian3(-this.lineLength / 2, 0, 0) let topLeft = new DT.Cesium.Cartesian3(this.lineLength / 2, -this.bottomHorizontalLength, -this.length) let topRight = new DT.Cesium.Cartesian3(this.lineLength / 2, this.bottomHorizontalLength, -this.length) let bottomLeft = new DT.Cesium.Cartesian3(-this.lineLength / 2, -this.bottomHorizontalLength, -this.length) let bottomRight = new DT.Cesium.Cartesian3(-this.lineLength / 2, this.bottomHorizontalLength, -this.length) let que = DT.Tool.calculateQuaternionFromV1ToV2(this.startPosition, this.endPosition) let rotationQuaternion = DT.Cesium.Quaternion.fromAxisAngle(DT.Cesium.Cartesian3.UNIT_X, this.rotation * Math.PI / 180) let combineQuaternion = new DT.Cesium.Quaternion() DT.Cesium.Quaternion.multiply(que, rotationQuaternion, combineQuaternion) let worldMatrix = DT.Cesium.Matrix4.fromTranslationQuaternionRotationScale(this.middlePosition, combineQuaternion, DT.Cesium.Cartesian3.ONE) let positiveXWorld = new DT.Cesium.Cartesian3() let negativeXWorld = new DT.Cesium.Cartesian3() let topLeftWorld = new DT.Cesium.Cartesian3() let topRightWorld = new DT.Cesium.Cartesian3() let bottomLeftWorld = new DT.Cesium.Cartesian3() let bottomRightWorld = new DT.Cesium.Cartesian3() DT.Cesium.Matrix4.multiplyByPoint(worldMatrix, positiveX, positiveXWorld) DT.Cesium.Matrix4.multiplyByPoint(worldMatrix, negativeX, negativeXWorld) DT.Cesium.Matrix4.multiplyByPoint(worldMatrix, topLeft, topLeftWorld) DT.Cesium.Matrix4.multiplyByPoint(worldMatrix, topRight, topRightWorld) DT.Cesium.Matrix4.multiplyByPoint(worldMatrix, bottomLeft, bottomLeftWorld) DT.Cesium.Matrix4.multiplyByPoint(worldMatrix, bottomRight, bottomRightWorld) let topLeftCross = this.findCrossPoint(positiveXWorld, topLeftWorld) let topRightCross = this.findCrossPoint(positiveXWorld, topRightWorld) let bottomLeftCross = this.findCrossPoint(negativeXWorld, bottomLeftWorld) let bottomRightCross = this.findCrossPoint(negativeXWorld, bottomRightWorld) let arr = [] if (topLeftCross) { arr.push(topLeftCross) } if (topRightCross) { arr.push(topRightCross) } if (bottomRightCross) { arr.push(bottomRightCross) } if (bottomLeftCross) { arr.push(bottomLeftCross) } this.crossPositions = [topLeftCross, topRightCross,bottomRightCross, bottomLeftCross, topLeftCross ] if (this.crossPositions.length > 1) { this.crossLine = new DT.Cesium.Entity({ polyline: { positions: this.crossPositions, width: 2, material: DT.Cesium.Color.RED, depthFailMaterial: DT.Cesium.Color.RED, } }) } } findCrossPoint2(start, end) { let ray = new DT.Cesium.Ray() DT.Cesium.Cartesian3.clone(start, ray.origin); DT.Cesium.Cartesian3.subtract(end, start, ray.direction); let position = this.viewer.cesiumViewer.scene.globe.pick(ray, this.viewer.cesiumViewer.scene) console.log('交点', position) return position } findCrossPoint(start, end) { let ray = new DT.Cesium.Ray() let tmpInterval = new DT.Cesium.Interval(); let intersection = DT.IntersectionTest.lineSegmentEllipsoid( start, end, DT.Cesium.Ellipsoid.WGS84, ray, tmpInterval ); let tmpPoint2 = new DT.Cesium.Cartesian3() if (intersection && intersection.start !== 0) { DT.Cesium.Ray.getPoint(ray, intersection.start, tmpPoint2); return tmpPoint2 } else { return null } } }