import { twoline2satrec, propagate } from 'satellite.js' import CreateFrustum from './sensor.js' // import './polylineTrail.js' import chroma from 'chroma-js' class SatelliteEntity { constructor(tle = '', options = {}) { const [name, tleLine1, tleLine2] = this._checkTle(tle) let circle = tleLine2.slice(52, 64) this.name = name.trim() this.tleLine1 = tleLine1.trim() this.tleLine2 = tleLine2.trim() this.satrec = twoline2satrec(this.tleLine1, this.tleLine2) this.totalSeconds = 7 * 86400 // 24小时 this.stepSeconds = 100 this.leadTime = parseInt((24 * 3600) / circle) this.trailTime = 0 this.sensor = false this.entity = null this.sensorType = 'rectangle' } get sensor() { return this.sensor } set sensor(showSensor) { console.log(showSensor, 'showSensor') if (showSensor) { if (this.sensorType === 'conic') { this.createConicSensor(this.entity) } else { this.createRectangleSensor(this.entity) } } //showSensor && } _checkTle(tle) { let elements = tle.split('\n') if (elements.length !== 3) { throw new Error('tle data error') } return elements } // 获取地心惯性坐标系坐标 getPositionEci(time) { return propagate(this.satrec, time).position } // 创建PositionProperty _getPositionProperty() { const start = Cesium.JulianDate.fromIso8601(new Date().toISOString()) const positionProperty = new Cesium.SampledPositionProperty( Cesium.ReferenceFrame.INERTIAL ) let now = Date.now() for (let i = 0; i < this.totalSeconds / this.stepSeconds; i++) { let sateTime = new Date(now + i * this.stepSeconds * 1000) let sateCoord = this.getPositionEci(sateTime) if (!sateCoord) { continue } const cesiumTime = Cesium.JulianDate.addSeconds( start, i * this.stepSeconds, new Cesium.JulianDate() ) const cesiumPosition = { x: sateCoord.x * 1000, y: sateCoord.y * 1000, z: sateCoord.z * 1000, } positionProperty.addSample(cesiumTime, cesiumPosition) } return positionProperty } // 创建卫星实例 createSatelliteEntity() { const start = Cesium.JulianDate.fromIso8601(new Date().toISOString()) const stop = Cesium.JulianDate.addSeconds( start, this.totalSeconds, new Cesium.JulianDate() ) const color = Cesium.Color.fromCssColorString( chroma.random().brighten().hex() ) // const color = Cesium.Color.fromRandom({ alpha: 0.5 }) let satelliteEntity = { name: this.name, description: this.name, show: true, availability: new Cesium.TimeIntervalCollection([ new Cesium.TimeInterval({ start: start, stop: stop }), ]), position: this._getPositionProperty(), // point: { // pixelSize: 8, // color: color, // // scaleByDistance: new Cesium.NearFarScalar(1.5e3, 1, 8.0e8, 0.5), // }, path: new Cesium.PathGraphics({ width: 2, show: true, leadTime: this.leadTime, trailTime: this.trailTime, // material: color, material: new Cesium.PolylineTrailLinkMaterialProperty({ color, duration: 86400 * 1000, }), }), label: { show: true, text: this.name, font: '12px sans-serif', showBackground: true, backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.5), backgroundPadding: new Cesium.Cartesian2(4, 4), outlineWidth: 1, verticalOrigin: Cesium.VerticalOrigin.TOP, horizontalOrigin: Cesium.VerticalOrigin.LEFT, pixelOffset: new Cesium.Cartesian2(0, 5), fillColor: Cesium.Color.WHITE, // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10.0, 50000000), }, billboard: { image: '/images/satellite.png', width: 40, height: 40, show: true, distanceDisplayCondition: new Cesium.DistanceDisplayCondition( 10.0, 50000000 ), }, // model: { // uri: '/GV/resources/model/wx.glb', // minimumPixelSize: 64, // maximumScale: 20000, // show: true, // distanceDisplayCondition: new Cesium.DistanceDisplayCondition( // 10.0, // 50000000 // ), // }, // cylinder: { // HeightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // length: 1700000, // topRadius: 0, // bottomRadius: 700000 / 2, // material: Cesium.Color.RED.withAlpha(0.4), // outline: !0, // numberOfVerticalLines: 0, // outlineColor: Cesium.Color.RED.withAlpha(0.8), // horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // }, orientation: new Cesium.VelocityOrientationProperty( this._getPositionProperty() ), } // this.createSensor(satelliteEntity) // return satelliteEntity this.entity = viewer.entities.add(satelliteEntity) return this.entity } createSensor(satellite) { // const color = '#00ffff' // let customSensor = new CesiumSensorVolumes.RectangularPyramidSensorVolume() // // const sate = tasks.value.find((item) => item.satId === sate_id); // // radius 是指波束的长度 // customSensor.radius = 40000000.0 // // customSensor.id = `${sate_id}_sensor`; // customSensor.id = `test_sensor` // customSensor.intersectionWidth = 1 // customSensor.xHalfAngle = Cesium.Math.toRadians(1) // customSensor.yHalfAngle = Cesium.Math.toRadians(1) // customSensor.lateralSurfaceMaterial = Cesium.Material.fromType('Color') // customSensor.lateralSurfaceMaterial.uniforms.color = // new Cesium.Color.fromCssColorString(color).withAlpha(0.3) // // 默认矩阵 // customSensor.modelMatrix = new Cesium.Matrix4() // // 使用preRender 监听卫星每帧运动 // viewer.scene.preRender.addEventListener((scene, time) => { // customSensor.show = false // // 判断数据源中所有实体是否准备就绪,viewer.dataSourceDisplay.dataSources = viewer.dataSources // if (viewer.dataSourceDisplay.ready) { // // const satellite = viewer.dataSources // // .getByName("simDemon")[0] // // .entities.getById(sate_id); // // 根据时间获取卫星实时笛卡尔位置 // let position = Cesium.Property.getValueOrUndefined( // satellite.position, // time, // new Cesium.Cartesian3() // ) // // 根据卫星位置和朝向转换为矩阵信息,此处使用的是后台计算的四元数,实际一般情况应该使用Cesium.Transforms+position转换 // console.log( // satellite.orientation.getValue(time), // 'satellite.orientation.getValue(time)' // ) // // let m = Cesium.Matrix4.fromRotationTranslation( // // Cesium.Matrix3.fromQuaternion( // // satellite.orientation.getValue(time), // // new Cesium.Matrix3() // // ), // // position, // // new Cesium.Matrix4() // // ) // let m = this.getModelMatrix(position, satellite.orientation) // console.log(m, 'm') // // // let m = Cesium.Transforms.northUpEastToFixedFrame(position) // customSensor.modelMatrix = m // // customSensor.modelMatrix = this.getModelMatrix() // customSensor.show = true // } // }) // viewer.scene.primitives.add(customSensor) // let position = Cesium.Property.getValueOrUndefined( // satellite.position, // viewer.clock.currentTime, // new Cesium.Cartesian3() // ) } createRectangleSensor(satellite) { // viewer.scene.primitives.removeAll() let position = Cesium.Property.getValueOrUndefined( satellite.position, viewer.clock.currentTime, new Cesium.Cartesian3() ) const rectangularPyramidSensor = new CesiumSensorVolumes.RectangularPyramidSensorVolume() rectangularPyramidSensor.modelMatrix = this.getModelMatrix(position) rectangularPyramidSensor.radius = 20000000.0 rectangularPyramidSensor.xHalfAngle = Cesium.Math.toRadians(20.0) rectangularPyramidSensor.yHalfAngle = Cesium.Math.toRadians(10.0) rectangularPyramidSensor.lateralSurfaceMaterial = Cesium.Material.fromType('Color') rectangularPyramidSensor.lateralSurfaceMaterial.uniforms.color = new Cesium.Color(0.0, 1.0, 1.0, 0.3) viewer.scene.preRender.addEventListener((scene, time) => { rectangularPyramidSensor.show = false let position = Cesium.Property.getValueOrUndefined( satellite.position, time, new Cesium.Cartesian3() ) rectangularPyramidSensor.modelMatrix = this.getModelMatrix(position) rectangularPyramidSensor.show = true }) viewer.scene.primitives.add(rectangularPyramidSensor) } getModelMatrix(location) { // let ellipsoid = viewer.scene.globe.ellipsoid // console.log(position, '----') // let location = ellipsoid.cartographicToCartesian( // new Cesium.Cartographic( // Cesium.Math.toRadians(120.0), // Cesium.Math.toRadians(24.0), // 1300000 // ) // ) let modelMatrix = Cesium.Transforms.northEastDownToFixedFrame(location) let orientation = Cesium.Matrix3.multiply( Cesium.Matrix3.multiply( Cesium.Matrix3.fromRotationZ(0.0), Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(0.0)), new Cesium.Matrix3() ), Cesium.Matrix3.fromRotationX(0.0), new Cesium.Matrix3() ) return Cesium.Matrix4.multiply( modelMatrix, Cesium.Matrix4.fromRotationTranslation( orientation, Cesium.Cartesian3.ZERO ), new Cesium.Matrix4() ) } createConicSensor(satellite) { let position = Cesium.Property.getValueOrUndefined( satellite.position, viewer.clock.currentTime, new Cesium.Cartesian3() ) // const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics() // conicSensor.radius = 20000000.0 // conicSensor.modelMatrix = this.getModelMatrix(position) // conicSensor.intersectionColor = new Cesium.ConstantProperty( // new Cesium.Color(0.1, 0.2, 0.3, 0.4) // ) const customSensor = new CesiumSensorVolumes.CustomSensorVolume() customSensor.modelMatrix = this.getModelMatrix(position) customSensor.radius = 20000000.0 // customSensor.directions = directions; viewer.scene.primitives.add(customSensor) viewer.scene.preRender.addEventListener((scene, time) => { customSensor.show = false let position = Cesium.Property.getValueOrUndefined( satellite.position, time, new Cesium.Cartesian3() ) customSensor.modelMatrix = this.getModelMatrix(position) customSensor.show = true }) viewer.scene.primitives.add(customSensor) } // createSensor(satellite) { // // let sensor = new Sensor({ // // position: satellite.position, // // orientation: satellite.orientation, // // aspectRatio: 1000, // // }) // // viewer.scene.preRender.addEventListener((scene, time) => { // let position = Cesium.Property.getValueOrUndefined( // satellite.position, // viewer.clock.currentTime, // new Cesium.Cartesian3() // ) // console.log(position, 'position') // let heading = 0 // let pitch = 0 // let roll = 90 // let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll) // let orientation = Cesium.Quaternion.fromHeadingPitchRoll(hpr) // let sensor = new CreateFrustum({ // position: position, // orientation: orientation, // far: 1000000, // aspectRatio: 600 / 1080, // }) // console.log(sensor, 'sensor') // // }) // } } export default SatelliteEntity