From bcb67f336c2b352177884b8db6decc3fcf382bb0 Mon Sep 17 00:00:00 2001 From: jihongshun <1151753686@qq.com> Date: 星期四, 11 九月 2025 16:58:13 +0800 Subject: [PATCH] 航线模拟 差视锥体的head值和时间轴 --- src/views/system/flightRouteSimulation/index.vue | 409 ++++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 327 insertions(+), 82 deletions(-) diff --git a/src/views/system/flightRouteSimulation/index.vue b/src/views/system/flightRouteSimulation/index.vue index cb73ab1..743f851 100644 --- a/src/views/system/flightRouteSimulation/index.vue +++ b/src/views/system/flightRouteSimulation/index.vue @@ -1,5 +1,6 @@ <template> <div class="app-container"> + <el-button type="primary" @click="showGZ">鏄剧ず瑙嗛敟浣�</el-button> <input @change="handleKMZUpload" type="file" id="kmzFile" accept=".kmz" class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0 @@ -21,71 +22,126 @@ }, data(){ return{ - trajectoryData: [ - { - time: '2025-04-01T13:00:00Z', // ISO 8601鏍煎紡鏃堕棿 - position: { - longitude: 125.14349012556997, // 缁忓害 - latitude:46.55684464616254, // 绾害 - height:33.157873665937274 // 楂樺害(绫�) - }, - speed: 0 // 閫熷害(鍏噷/灏忔椂) - }, - { - time: '2025-04-01T13:01:00Z', // ISO 8601鏍煎紡鏃堕棿 - position: { - longitude: 125.14347355270496, // 缁忓害 - latitude: 46.55684011411894, // 绾害 - height: 37.91924525928209 // 楂樺害(绫�) - }, - speed: 10 // 閫熷害(鍏噷/灏忔椂) - }, - { - time: '2025-04-01T13:02:00Z', // ISO 8601鏍煎紡鏃堕棿 - position: { - longitude: 125.14347355270496, // 缁忓害126.672952 , 45.744238 + // trajectoryData: [ + // { + // time: '2025-04-01T13:00:00Z', // ISO 8601鏍煎紡鏃堕棿 + // position: { + // longitude: 125.14349012556997, // 缁忓害 + // latitude:46.55684464616254, // 绾害 + // height:33.157873665937274 // 楂樺害(绫�) + // }, + // heading:0, + // pitch:-90, + // roll:0, + // speed: 10 // 閫熷害(鍏噷/灏忔椂) + // }, - latitude: 46.556840114118955, // 绾害 - height:87.91924526022864 // 楂樺害(绫�) - }, - speed: 20 // 閫熷害(鍏噷/灏忔椂) - }, - { - time: '2025-04-01T13:03:00Z', // ISO 8601鏍煎紡鏃堕棿 - position: { - longitude: 125.14347246077013, // 缁忓害126.671715 , 45.739693 - latitude: 46.556326837883375, // 绾害 - height: 83.15663931356488 // 楂樺害(绫�) - }, - speed: 30 // 閫熷害(鍏噷/灏忔椂) - }, - { - time: '2025-04-01T13:04:00Z', // ISO 8601鏍煎紡鏃堕棿 - position: { - longitude: 125.14347246077013, // 缁忓害 - latitude: 46.55632683788337, // 绾害 - height: 33.15663931413056 // 楂樺害(绫�) - }, - speed: 80 // 閫熷害(鍏噷/灏忔椂) - }, - // 鏇村鐐�... - ], + + + // { + // time: '2025-04-01T13:01:00Z', // ISO 8601鏍煎紡鏃堕棿 + // position: { + // longitude: 125.14347355270496, // 缁忓害 + // latitude: 46.55684011411894, // 绾害 + // height: 37.91924525928209 // 楂樺害(绫�) + // }, + // heading:30, + // pitch:45, + // roll:45, + // speed: 10 // 閫熷害(鍏噷/灏忔椂) + // }, + // { + // time: '2025-04-01T13:02:00Z', // ISO 8601鏍煎紡鏃堕棿 + // position: { + // longitude: 125.14347355270496, // 缁忓害126.672952 , 45.744238 + + // latitude: 46.556840114118955, // 绾害 + // height:87.91924526022864 // 楂樺害(绫�) + // }, + // heading:90, + // pitch:0, + // roll:45, + // speed: 20 // 閫熷害(鍏噷/灏忔椂) + // }, + // { + // time: '2025-04-01T13:03:00Z', // ISO 8601鏍煎紡鏃堕棿 + // position: { + // longitude: 125.14347246077013, // 缁忓害126.671715 , 45.739693 + + // latitude: 46.556326837883375, // 绾害 + // height: 83.15663931356488 // 楂樺害(绫�) + // }, + // heading:180, + // pitch:60, + // roll:0, + // speed: 30 // 閫熷害(鍏噷/灏忔椂) + // }, + // { + // time: '2025-04-01T13:04:00Z', // ISO 8601鏍煎紡鏃堕棿 + // position: { + // longitude: 125.14347246077013, // 缁忓害 + // latitude: 46.55632683788337, // 绾害 + // height: 33.15663931413056 // 楂樺害(绫�) + // }, + // heading:150, + // pitch:0, + // roll:45, + // speed: 80 // 閫熷害(鍏噷/灏忔椂) + // }, + + // // 鏇村鐐�... + // ], + trajectoryData:[],//鏁版嵁鏁扮粍 + c3Position:Cesium.Cartesian3.fromDegrees(125.04159166971326, 46.63755601510411,33.13806141449017),//鍒濆鍖栦綅缃� + camera: null, // Cesium Camera 瀹炰緥 + frustumOutline: null, // 瑙嗛敟浣� + heading: -90, // 鐩告満鐨� heading (鏈濆悜) + pitch: 0, // 鐩告満鐨� pitch (淇话) + roll: 0, // 鐩告満鐨� roll (婊氳浆) + aspectRatio: 1.0, // 绾垫í姣� + color: '#FF0000', // 瑙嗛敟浣撻鑹� + id: 'frustumOutline', + positionProperty : new Cesium.SampledPositionProperty(), + orientation : new Cesium.SampledProperty(Cesium.Quaternion),//鏃犱汉鏈烘湞鍚� + sztOrientation : new Cesium.SampledProperty(Cesium.Quaternion),//浜戝彴鏈濆悜 } }, mounted() { - console.log(window.viewer) - console.log(viewer) }, methods: { async handleKMZUpload(event) { const file = event.target.files[0]; if (!file) return; - try { const arrayBuffer = await this.readFileAsArrayBuffer(file); this.waypoints = await this.parseKMZ(arrayBuffer); + //鍔犵偣閫昏緫 姣斿鍚戠2-n-1涓彃鍏ュ厓绱� 缁忕含搴︿负褰撳墠鐨� heading pitch roll 涓嬩竴涓殑 + const dealArr = []; + // console.log(">> this.waypoints:", this.waypoints); + for (let i = 0; i < this.waypoints.length - 1; i++) { + dealArr.push(this.waypoints[i]); // Push the current element + const current = this.waypoints[i]; + const next = this.waypoints[i + 1]; + + // Create a new element with the current lng, lat and next heading, pitch, roll + dealArr.push({ + "lng": current.lng, + "lat": current.lat, + "alt": current.alt, + 'flyHeading':next.flyHeading, + "heading": next.heading, + "pitch": next.pitch, + "roll": next.roll + }); + } + + // Push the last element without any change + dealArr.push(this.waypoints[this.waypoints.length - 1]); + + console.log(dealArr) + this.waypoints = dealArr console.log(">> this.waypoints:", this.waypoints); this.fileInfo = ` @@ -94,6 +150,33 @@ `; this.showFlightPath() this.getTowerData() + const startDate = new Date("2025-04-01T13:00:00Z"); + const speeds = [10, 10, 20, 30, 80, 100, 60, 50, 40, 30, 20, 10]; // 鑷畾涔夐�熷害 + + // const result = this.waypoints.map((item, index) => { + console.log(result) + const result = dealArr.map((item, index) => { + // const result = this.waypoints.map((item, index) => { + // 姣忔鍔犱竴澶� + const time = new Date(startDate.getTime() + index * 60 * 1000).toISOString(); + // const time = Cesium.JulianDate.addSeconds(startDate, 3600, new Cesium.JulianDate()); + return { + time, + position: { + longitude: item.lng, + latitude: item.lat, + height: parseFloat(item.alt) + }, + heading:item.heading|| 0, + pitch:item.pitch|| 0, + roll:item.roll || 0, + speed: speeds[index] || 0, + // flyHeading:item.flyHeading + }; + }); + this.trajectoryData = result + console.log(this.trajectoryData) + // console.log(result); this.loadTimeLine() } catch (error) { console.error(error); @@ -117,7 +200,7 @@ const kmlFile = Object.keys(zip.files).find(name => name.endsWith(".kml") ); - console.log(">> kmlFile:", kmlFile); + // console.log(">> kmlFile:", kmlFile); if (!kmlFile) throw new Error("鏈壘鍒癒ML鏂囦欢"); const kmlContent = await zip.file(kmlFile).async("text"); @@ -134,10 +217,50 @@ placemarks.forEach(placemark => { const coords = placemark.Point?.[0]?.coordinates?.[0]; const height = placemark["wpml:height"]?.[0]; + // 鎻愬彇 aircraftHeading + // 鎻愬彇 action 閲岀殑鍙傛暟 + let heading = null; + let gimbalPitch = null, gimbalRoll = null, gimbalYaw = null; + // 鍒濆鍖� Pitch, Roll 鍜� Heading + let totalPitch = 0; + let totalRoll = 0; + let totalHeading = 0; + let flyHeadingData = 0; + if (placemark["wpml:actionGroup"]?.[0]?.["wpml:action"]) { + placemark["wpml:actionGroup"][0]["wpml:action"].forEach(action => { + // 澶勭悊 gimbalRotate 鍜� rotateYaw 鍑芥暟 + if (action['wpml:actionActuatorFunc'].includes("gimbalRotate")) { + // 鑾峰彇姣忎釜瑙掑害鍊� + const gimbalPitch = parseFloat(action['wpml:actionActuatorFuncParam'][0]["wpml:gimbalPitchRotateAngle"][0]); + const gimbalRoll = parseFloat(action['wpml:actionActuatorFuncParam'][0]["wpml:gimbalRollRotateAngle"][0]); + const gimbalYaw = parseFloat(action['wpml:actionActuatorFuncParam'][0]["wpml:gimbalYawRotateAngle"][0]); + + // 绱姞 Pitch, Roll 鍜� Heading + totalPitch += gimbalPitch; + totalRoll += gimbalRoll; + totalHeading += gimbalYaw; + console.log('totalHeading閲岄潰寰幆' + totalHeading) + } + // 澶勭悊 rotateYaw 鍑芥暟 + if (action['wpml:actionActuatorFunc'].includes("rotateYaw")) { + // 鑾峰彇 aircraftHeading + const aircraftHeading = parseFloat(action['wpml:actionActuatorFuncParam'][0]["wpml:aircraftHeading"][0]); + console.log(aircraftHeading) + flyHeadingData = aircraftHeading + // 灏� aircraftHeading 绱姞鍒� totalHeading + totalHeading += aircraftHeading; + console.log('totalHeading澶栧眰澶栧眰澶栧眰澶栧眰澶栧眰寰幆' + totalHeading) + } + }); + } + // 杈撳嚭缁撴灉 + console.log("Total Pitch:", totalPitch); + console.log("Total Roll:", totalRoll); + console.log("Total Heading:", totalHeading); if (coords) { coords.trim().split(" ").forEach(coord => { const [lng, lat] = coord.split(",").map(Number); - points.push({ lng, lat, alt: height }); + points.push({ lng, lat, alt: height,heading:totalHeading || 0,pitch:totalPitch || 0,roll:totalRoll|| 0 ,flyHeading:flyHeadingData}); }); } }); @@ -178,9 +301,6 @@ showFlightPath() { console.log(">> this.waypoints:", this.waypoints); if (this.waypoints.length === 0) return alert('璇峰厛涓婁紶KMZ鏂囦欢'); - - // viewer.entities.removeAll(); - // 杞崲鍧愭爣 const positions = this.waypoints.map(wp => Cesium.Cartesian3.fromDegrees(wp.lng, wp.lat, wp.alt) @@ -227,7 +347,6 @@ //绮惧害缁村害楂樺害 getScopeTower(lon,lat,distance).then(res=>{ if(res.code == 200) { - console.log(res.rows) res.rows.forEach((data) => { this.createModel(data); }); @@ -236,7 +355,6 @@ }) }, createModel(data){ - console.log(data) viewer.entities.add({ id: data.id, position: Cesium.Cartesian3.fromDegrees(data.longitude, data.latitude, data.altitude), @@ -264,7 +382,11 @@ loadTimeLine(){ // 璁剧疆鏃堕棿鑼冨洿 const allTimes = this.trajectoryData.map(item => Cesium.JulianDate.fromIso8601(item.time)) - console.log(allTimes) + // 鑾峰彇鎵�鏈夋椂闂达紝骞跺噺鍘�8灏忔椂 + // const allTimes = this.trajectoryData.map(item => { + // const time = Cesium.JulianDate.fromIso8601(item.time) + // return Cesium.JulianDate.addHours(time, +8, new Cesium.JulianDate()) + // }) const startTime = allTimes[0] const stopTime = allTimes[allTimes.length - 1] // const startTime = Cesium.JulianDate.minimum(...allTimes) @@ -278,9 +400,9 @@ // 鍒涘缓浣嶇疆鍜岄�熷害灞炴�� - const positionProperty = new Cesium.SampledPositionProperty() const speedProperty = new Cesium.SampledProperty(Number) -console.log(">> this.trajectoryData:", this.trajectoryData); + + console.log(">> this.trajectoryData:", this.trajectoryData); // 娣诲姞閲囨牱鐐� this.trajectoryData.forEach(data => { const time = Cesium.JulianDate.fromIso8601(data.time) @@ -289,32 +411,42 @@ data.position.latitude, data.position.height || 0 ) - positionProperty.addSample(time, position) + this.positionProperty.addSample(time, position) speedProperty.addSample(time, data.speed) + // 璁$畻鏈濆悜鍥涘厓鏁� + // const hpr = new Cesium.HeadingPitchRoll( + // Cesium.Math.toRadians(data.flyHeading), + // Cesium.Math.toRadians(data.pitch), + // Cesium.Math.toRadians(data.roll) + // ); + const hpr = new Cesium.HeadingPitchRoll( + Cesium.Math.toRadians(0), + Cesium.Math.toRadians(0), + Cesium.Math.toRadians(0) + ); + const quaternion = Cesium.Transforms.headingPitchRollQuaternion(position, hpr); + console.log(Cesium.JulianDate.toDate(time)) + // // 娣诲姞椋炴満鏈濆悜閲囨牱 + this.orientation.addSample(time, quaternion); + //浜戝彴 + const szthpr = new Cesium.HeadingPitchRoll( + Cesium.Math.toRadians(data.heading), + Cesium.Math.toRadians(data.pitch), + Cesium.Math.toRadians(data.roll) + ); + const sztquaternion = Cesium.Transforms.headingPitchRollQuaternion(position, szthpr); + + this.sztOrientation.addSample(time, sztquaternion); }) -console.log(">> positionProperty:",positionProperty ); + // console.log(">> positionProperty:",this.positionProperty ); let entity = viewer.entities.add({ show: true, - position: positionProperty, - label: { - show: true, - font: '18px 寰蒋闆呴粦', - style: Cesium.LabelStyle.FILL_AND_OUTLINE, - showBackground: false, - backgroundColor: Cesium.Color.fromCssColorString('#123456').withAlpha(0.5), - outlineColor: Cesium.Color.fromCssColorString('#00ff00'), - outlineWidth: 3, - fillColor: Cesium.Color.fromCssColorString("#000000"), - horizontalOrigin: Cesium.HorizontalOrigin.CENTER, - verticalOrigin: Cesium.VerticalOrigin.TOP, - text: '娴嬭瘯鏂囧瓧', - pixelOffset: new Cesium.Cartesian2(0, -1 * 100), - }, + position: this.positionProperty, + id:'lineFly', model: { - uri: "/Model/UAV.glb", // 娉ㄦ剰entitits.add鏂瑰紡鍔犺浇gltf鏂囦欢鏃讹紝杩欓噷鏄痷ri锛屼笉鏄痷rl锛屽苟涓旇繖绉嶆柟寮忓彧鑳藉姞杞�.glb鏍煎紡鐨勬枃浠� - scale: 1, // 缂╂斁姣斾緥 - // minimumPixelSize: this.minSize, // 鏈�灏忓儚绱犲ぇ灏忥紝鍙互閬垮厤澶皬鐪嬩笉瑙� + uri: "/Model/M300.glb", // 娉ㄦ剰entitits.add鏂瑰紡鍔犺浇gltf鏂囦欢鏃讹紝杩欓噷鏄痷ri锛屼笉鏄痷rl锛屽苟涓旇繖绉嶆柟寮忓彧鑳藉姞杞�.glb鏍煎紡鐨勬枃浠� + scale: 10, // 缂╂斁姣斾緥 minimumPixelSize: 0, // 鏈�灏忓儚绱犲ぇ灏忥紝鍙互閬垮厤澶皬鐪嬩笉瑙� maximumScale: 20000, // 妯″瀷鐨勬渶澶ф瘮渚嬪昂澶у皬銆俶inimumPixelSize鐨勪笂闄� incrementallyLoadTextures: true, // 鍔犺浇妯″瀷鍚庣汗鐞嗘槸鍚﹀彲浠ョ户缁祦鍏� @@ -336,8 +468,121 @@ leadTime: 60, trailTime: 60 }, - orientation: new Cesium.VelocityOrientationProperty(positionProperty), + orientation:this.orientation }) + }, + // 鏇存柊瑙嗛敟浣撲綅缃拰鏈濆悜 + updateFrustum() { + // 鏇存柊瑙嗛敟浣撲綅缃� + if (this.frustumOutline) { + // 鏇存柊鐩告満鍜岃閿ヤ綋浣嶇疆 + this.camera.setView({ + up: Cesium.Cartesian3.UNIT_Z, + destination: this.c3Position, + orientation: { + heading: Cesium.Math.toRadians(this.heading), + pitch: Cesium.Math.toRadians(this.pitch), + roll: Cesium.Math.toRadians(this.roll), + }, + }); + } else { + console.warn('Frustum outline is not initialized'); + } + }, + listenChange() { + let viewer = window.viewer; + viewer.clock.onTick.addEventListener(() => { + if (viewer.clock.shouldAnimate) { + this.getCurrentPosition() + // 鎵ц鍔ㄤ綔 + // console.log("Clock is running, performing action..."); + // 浣犵殑浠g爜閫� + } else { + // 鏃堕挓鏆傚仠鏃朵笉鎵ц + // console.log("Clock is paused, no action performed."); + } + }); + }, + getCurrentPosition() { + // 鑾峰彇褰撳墠鏃堕棿 + const currentTime = viewer.clock.currentTime; + console.log(Cesium.JulianDate.toDate(currentTime)) + console.log('start:', Cesium.JulianDate.toDate(this.positionProperty._property._times[0])); + console.log('stop:', Cesium.JulianDate.toDate(this.positionProperty._property._times.slice(-1)[0])); + // const currentTime = Cesium.JulianDate.addHours(currentTime, -8, new Cesium.JulianDate()); + + console.log(currentTime) + // 浠� positionProperty 涓幏鍙栧綋鍓嶄綅缃� + const currentPosition = this.positionProperty.getValue(currentTime); + + // console.log('currentPosition>>>>>>>>>>>>>>>>>>>>>>>' + currentPosition) + // 濡傛灉鑾峰彇鍒颁綅缃� + if (currentPosition) { + // 灏嗕綅缃粠 Cartesian 杞崲涓� Cartographic + const cartographicPosition = Cesium.Cartographic.fromCartesian(currentPosition); + + // 灏嗙粡绾害浠庡姬搴﹁浆鎹负搴� + this.currentLongitude = Cesium.Math.toDegrees(cartographicPosition.longitude); + console.log(Cesium.Math.toDegrees(cartographicPosition.longitude)) + console.log(Cesium.Math.toDegrees(cartographicPosition.latitude)) + this.currentLatitude = Cesium.Math.toDegrees(cartographicPosition.latitude); + this.currentHeight = cartographicPosition.height; + this.c3Position = Cesium.Cartesian3.fromDegrees(this.currentLongitude, this.currentLatitude,this.currentHeight) + // console.log(`褰撳墠浣嶇疆 - 缁忓害: ${this.currentLongitude}, 绾害: ${this.currentLatitude}, 楂樺害: ${this.currentHeight}`); + //鐩告満鍙樺寲 + const quaternion = this.orientation.getValue(currentTime) + // if(quaternion) { + // const hpr111 = Cesium.HeadingPitchRoll.fromQuaternion(quaternion) + // console.log('鐩告満鐨� ' +Cesium.Math.toDegrees(hpr111.heading).toFixed(2)) + // } + //浜戝彴鍙樺寲 + const sztquaternion = this.sztOrientation.getValue(currentTime) + console.log(sztquaternion) + if (sztquaternion) { + const hpr = Cesium.HeadingPitchRoll.fromQuaternion(sztquaternion) + console.log(hpr) + this.heading = Cesium.Math.toDegrees(hpr.heading).toFixed(2) + // this.heading = 180 + this.pitch = Cesium.Math.toDegrees(hpr.pitch).toFixed(2) + this.roll = Cesium.Math.toDegrees(hpr.roll).toFixed(2) + console.log('褰撳墠浣嶇疆 - heading ' + this.heading) + console.log(`褰撳墠浣嶇疆 - heading: ${this.heading}, pitch: ${this.pitch}, roll: ${this.roll}`); + } + + this.updateFrustum(); + } else { + console.log("鏃犳硶鑾峰彇褰撳墠浣嶇疆"); + } + }, + showGZ(){ + let viewer = window.viewer; + this.camera = new Cesium.Camera(viewer.scene) + // 瑙嗛敟浣撳弬鏁� + this.camera.frustum = new Cesium.PerspectiveFrustum({ + // fov: Cesium.Math.PI_OVER_THREE, + fov: Cesium.Math.toRadians(10), + // aspectRatio: this.aspectRatio, + aspectRatio: 1920 / 1080, + }); + this.camera.setView({ + up: Cesium.Cartesian3.UNIT_Z, + destination: this.c3Position, + orientation: { + heading: Cesium.Math.toRadians(this.heading), + pitch: Cesium.Math.toRadians(this.pitch), + roll: Cesium.Math.toRadians(this.roll), + }, + }) + this.frustumOutline = new Cesium.DebugCameraPrimitive({ + id: 111111, + camera: this.camera, + frustumSplits: [0.01, 10000], + color: Cesium.Color.fromCssColorString('#00ff00'), + // updateOnChange: false, + updateOnChange: true, + }) + viewer.scene.primitives.add(this.frustumOutline); + this.listenChange() } } -- Gitblit v1.9.3