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 | 250 +++++++++++++++++++++++++++++++++++-------------- 1 files changed, 178 insertions(+), 72 deletions(-) diff --git a/src/views/system/flightRouteSimulation/index.vue b/src/views/system/flightRouteSimulation/index.vue index 476d099..743f851 100644 --- a/src/views/system/flightRouteSimulation/index.vue +++ b/src/views/system/flightRouteSimulation/index.vue @@ -1,6 +1,6 @@ <template> <div class="app-container"> - <el-button type="primary" @click="showGZ">涓昏鎸夐挳</el-button> + <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 @@ -30,8 +30,16 @@ // latitude:46.55684464616254, // 绾害 // height:33.157873665937274 // 楂樺害(绫�) // }, - // speed: 0 // 閫熷害(鍏噷/灏忔椂) + // heading:0, + // pitch:-90, + // roll:0, + // speed: 10 // 閫熷害(鍏噷/灏忔椂) // }, + + + + + // { // time: '2025-04-01T13:01:00Z', // ISO 8601鏍煎紡鏃堕棿 // position: { @@ -39,6 +47,9 @@ // latitude: 46.55684011411894, // 绾害 // height: 37.91924525928209 // 楂樺害(绫�) // }, + // heading:30, + // pitch:45, + // roll:45, // speed: 10 // 閫熷害(鍏噷/灏忔椂) // }, // { @@ -49,6 +60,9 @@ // latitude: 46.556840114118955, // 绾害 // height:87.91924526022864 // 楂樺害(绫�) // }, + // heading:90, + // pitch:0, + // roll:45, // speed: 20 // 閫熷害(鍏噷/灏忔椂) // }, // { @@ -59,6 +73,9 @@ // latitude: 46.556326837883375, // 绾害 // height: 83.15663931356488 // 楂樺害(绫�) // }, + // heading:180, + // pitch:60, + // roll:0, // speed: 30 // 閫熷害(鍏噷/灏忔椂) // }, // { @@ -68,38 +85,63 @@ // latitude: 46.55632683788337, // 绾害 // height: 33.15663931413056 // 楂樺害(绫�) // }, + // heading:150, + // pitch:0, + // roll:45, // speed: 80 // 閫熷害(鍏噷/灏忔椂) // }, // // 鏇村鐐�... // ], - trajectoryData:[], - c3Position:Cesium.Cartesian3.fromDegrees(125.14349012556997, 46.55684464616254,33.157873665937274), - enableChange:true, + trajectoryData:[],//鏁版嵁鏁扮粍 + c3Position:Cesium.Cartesian3.fromDegrees(125.04159166971326, 46.63755601510411,33.13806141449017),//鍒濆鍖栦綅缃� camera: null, // Cesium Camera 瀹炰緥 frustumOutline: null, // 瑙嗛敟浣� - heading: 0, // 鐩告満鐨� heading (鏈濆悜) - pitch: -90, // 鐩告満鐨� pitch (淇话) + heading: -90, // 鐩告満鐨� heading (鏈濆悜) + pitch: 0, // 鐩告満鐨� pitch (淇话) roll: 0, // 鐩告満鐨� roll (婊氳浆) aspectRatio: 1.0, // 绾垫í姣� color: '#FF0000', // 瑙嗛敟浣撻鑹� id: 'frustumOutline', - positionProperty : new Cesium.SampledPositionProperty() + positionProperty : new Cesium.SampledPositionProperty(), + orientation : new Cesium.SampledProperty(Cesium.Quaternion),//鏃犱汉鏈烘湞鍚� + sztOrientation : new Cesium.SampledProperty(Cesium.Quaternion),//浜戝彴鏈濆悜 } }, mounted() { - console.log(window.viewer) - console.log(viewer) - this.showGZ() }, 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 = ` @@ -111,9 +153,13 @@ 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) => { + // 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: { @@ -121,11 +167,16 @@ latitude: item.lat, height: parseFloat(item.alt) }, - speed: speeds[index] || 0 + heading:item.heading|| 0, + pitch:item.pitch|| 0, + roll:item.roll || 0, + speed: speeds[index] || 0, + // flyHeading:item.flyHeading }; }); this.trajectoryData = result - console.log(result); + console.log(this.trajectoryData) + // console.log(result); this.loadTimeLine() } catch (error) { console.error(error); @@ -149,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"); @@ -166,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}); }); } }); @@ -210,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) @@ -259,7 +347,6 @@ //绮惧害缁村害楂樺害 getScopeTower(lon,lat,distance).then(res=>{ if(res.code == 200) { - console.log(res.rows) res.rows.forEach((data) => { this.createModel(data); }); @@ -268,7 +355,6 @@ }) }, createModel(data){ - console.log(data) viewer.entities.add({ id: data.id, position: Cesium.Cartesian3.fromDegrees(data.longitude, data.latitude, data.altitude), @@ -296,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) @@ -311,6 +401,7 @@ // 鍒涘缓浣嶇疆鍜岄�熷害灞炴�� const speedProperty = new Cesium.SampledProperty(Number) + console.log(">> this.trajectoryData:", this.trajectoryData); // 娣诲姞閲囨牱鐐� this.trajectoryData.forEach(data => { @@ -322,32 +413,40 @@ ) 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:",this.positionProperty ); + // console.log(">> positionProperty:",this.positionProperty ); let entity = viewer.entities.add({ show: true, position: this.positionProperty, id:'lineFly', - // 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), - // pixelOffset: new Cesium.Cartesian2(0, -90) - // }, model: { uri: "/Model/M300.glb", // 娉ㄦ剰entitits.add鏂瑰紡鍔犺浇gltf鏂囦欢鏃讹紝杩欓噷鏄痷ri锛屼笉鏄痷rl锛屽苟涓旇繖绉嶆柟寮忓彧鑳藉姞杞�.glb鏍煎紡鐨勬枃浠� - scale: 1, // 缂╂斁姣斾緥 - // minimumPixelSize: this.minSize, // 鏈�灏忓儚绱犲ぇ灏忥紝鍙互閬垮厤澶皬鐪嬩笉瑙� + scale: 10, // 缂╂斁姣斾緥 minimumPixelSize: 0, // 鏈�灏忓儚绱犲ぇ灏忥紝鍙互閬垮厤澶皬鐪嬩笉瑙� maximumScale: 20000, // 妯″瀷鐨勬渶澶ф瘮渚嬪昂澶у皬銆俶inimumPixelSize鐨勪笂闄� incrementallyLoadTextures: true, // 鍔犺浇妯″瀷鍚庣汗鐞嗘槸鍚﹀彲浠ョ户缁祦鍏� @@ -369,23 +468,12 @@ leadTime: 60, trailTime: 60 }, - orientation: Cesium.Quaternion.fromHeadingPitchRoll( - new Cesium.HeadingPitchRoll( - Cesium.Math.toRadians(45), // 鑸悜瑙�(姝e寳涓�0锛岄『鏃堕拡澧炲姞) - Cesium.Math.toRadians(45), // 淇话瑙� - Cesium.Math.toRadians(0) // 缈绘粴瑙� - ) - ), + orientation:this.orientation }) }, // 鏇存柊瑙嗛敟浣撲綅缃拰鏈濆悜 updateFrustum() { - console.log(this.c3Position) - console.log(this.pitch) - console.log(this.heading) - console.log(this.roll) // 鏇存柊瑙嗛敟浣撲綅缃� - // this.c3Position = Cesium.Cartesian3.fromDegrees(114.169, 22.278, 500); // 鍔ㄦ�佹洿鏂颁綅缃� if (this.frustumOutline) { // 鏇存柊鐩告満鍜岃閿ヤ綋浣嶇疆 this.camera.setView({ @@ -397,15 +485,9 @@ roll: Cesium.Math.toRadians(this.roll), }, }); - - // 鍙湪frustumOutline瀛樺湪鏃惰皟鐢╱pdate - this.frustumOutline.update(); } else { console.warn('Frustum outline is not initialized'); } - // 鏇存柊瑙嗛敟浣撹竟妗� - console.log(this.frustumOutline) - // this.frustumOutline.update(); }, listenChange() { let viewer = window.viewer; @@ -413,22 +495,27 @@ if (viewer.clock.shouldAnimate) { this.getCurrentPosition() // 鎵ц鍔ㄤ綔 - console.log("Clock is running, performing action..."); - // 浣犵殑浠g爜閫昏緫 + // console.log("Clock is running, performing action..."); + // 浣犵殑浠g爜閫� } else { // 鏃堕挓鏆傚仠鏃朵笉鎵ц - console.log("Clock is paused, no action performed."); + // 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 涓幏鍙栧綋鍓嶄綅缃� - console.log(this.positionProperty) const currentPosition = this.positionProperty.getValue(currentTime); - + + // console.log('currentPosition>>>>>>>>>>>>>>>>>>>>>>>' + currentPosition) // 濡傛灉鑾峰彇鍒颁綅缃� if (currentPosition) { // 灏嗕綅缃粠 Cartesian 杞崲涓� Cartographic @@ -436,10 +523,32 @@ // 灏嗙粡绾害浠庡姬搴﹁浆鎹负搴� 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}`); + // 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("鏃犳硶鑾峰彇褰撳墠浣嶇疆"); @@ -450,7 +559,8 @@ this.camera = new Cesium.Camera(viewer.scene) // 瑙嗛敟浣撳弬鏁� this.camera.frustum = new Cesium.PerspectiveFrustum({ - fov: Cesium.Math.PI_OVER_THREE, + // fov: Cesium.Math.PI_OVER_THREE, + fov: Cesium.Math.toRadians(10), // aspectRatio: this.aspectRatio, aspectRatio: 1920 / 1080, }); @@ -458,23 +568,19 @@ 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), heading: Cesium.Math.toRadians(this.heading), pitch: Cesium.Math.toRadians(this.pitch), roll: Cesium.Math.toRadians(this.roll), }, }) this.frustumOutline = new Cesium.DebugCameraPrimitive({ - // id: this.id, id: 111111, camera: this.camera, frustumSplits: [0.01, 10000], color: Cesium.Color.fromCssColorString('#00ff00'), - updateOnChange: false, + // updateOnChange: false, + updateOnChange: true, }) - console.log(this.frustumOutline) viewer.scene.primitives.add(this.frustumOutline); this.listenChange() } -- Gitblit v1.9.3