diff --git a/src/assets/images/bottom-box.png b/src/assets/images/bottom-box.png new file mode 100644 index 0000000..5b2fd3d Binary files /dev/null and b/src/assets/images/bottom-box.png differ diff --git a/src/assets/images/left-bg.png b/src/assets/images/left-bg.png new file mode 100644 index 0000000..db3461f Binary files /dev/null and b/src/assets/images/left-bg.png differ diff --git a/src/assets/images/map-title.png b/src/assets/images/map-title.png new file mode 100644 index 0000000..0eaf1af Binary files /dev/null and b/src/assets/images/map-title.png differ diff --git a/src/assets/images/right-bg.png b/src/assets/images/right-bg.png new file mode 100644 index 0000000..3d3cd3b Binary files /dev/null and b/src/assets/images/right-bg.png differ diff --git a/src/assets/images/top-box.png b/src/assets/images/top-box.png new file mode 100644 index 0000000..c7a273d Binary files /dev/null and b/src/assets/images/top-box.png differ diff --git a/src/assets/styles/font.css b/src/assets/styles/font.css new file mode 100644 index 0000000..6104a36 --- /dev/null +++ b/src/assets/styles/font.css @@ -0,0 +1,4 @@ +@font-face { + font-family: "YouSheBiaoTiHei"; + src: url("./font/YouSheBiaoTiHei.ttf"); +} \ No newline at end of file diff --git a/src/assets/styles/font/YouSheBiaoTiHei.ttf b/src/assets/styles/font/YouSheBiaoTiHei.ttf new file mode 100644 index 0000000..3729151 Binary files /dev/null and b/src/assets/styles/font/YouSheBiaoTiHei.ttf differ diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index 36e3a8f..816aec6 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -6,6 +6,7 @@ @import './btn.scss'; @import './ruoyi.scss'; @import './marsMap.scss'; +@import './font.css'; body { width: 100%; diff --git a/src/views/components/map/container.vue b/src/views/components/map/container.vue index 570e7d0..d19c821 100644 --- a/src/views/components/map/container.vue +++ b/src/views/components/map/container.vue @@ -1,31 +1,104 @@ <template> - <div class="map-container" id="mapContainer"> - <slot></slot> + <div class="map-container" id="mapContainer"> + <div class="top-main"> + <div class="map-title"> + <span> 云航低空研训基地飞行控制中心</span> + </div> </div> - </template> - - <script setup> - import { onMounted } from 'vue'; - import autofit from 'autofit.js' - onMounted(()=>{ - //启用适配 - autofit.init({ - el:"#mapContainer", - dh: 1080, - dw: 1920, - resize:true, - }) - }) - - </script> - - <style lang="scss" scoped> - .map-container{ - position: relative; - z-index: 100; + <div class="bottom-box"></div> + <div class="left-bg"> + <slot name="left"></slot> + </div> + <div class="right-bg"> + <slot name="right"></slot> + </div> + <div class="map-main"> + <slot name="map"></slot> + </div> + </div> +</template> + +<script setup> +import { onMounted } from "vue"; +import autofit from "autofit.js"; +onMounted(() => { + //启用适配 + autofit.init({ + el: "#mapContainer", + dh: 1080, + dw: 1920, + resize: true, + }); +}); +</script> + +<style lang="scss" scoped> +.map-container { + position: relative; + z-index: 100; + height: 100%; + width: 100%; + .map-main { + height: 100%; + width: 100%; + } + .top-main { + position: fixed; + top: 0; + width: 100%; + z-index: 1000; + height: 120px; + background: url("@/assets/images/top-box.png"); + background-size: 100% 100%; + } + .map-title { + width: 100%; height: 100%; + background: url("@/assets/images/map-title.png") no-repeat top center; + background-size: 100% cover; + text-align: center; + span { + display: inline-block; + letter-spacing: 2px; + font-size: 40px; + color: #ffffff; + font-family: "YouSheBiaoTiHei"; + text-shadow: 2px 6px 4px #0e426c; + } + } + + .bottom-box { + position: absolute; + bottom: 0; + z-index: 200; width: 100%; - + height: 150px; + background: url("@/assets/images/bottom-box.png"); + background-size: 100% 100%; + } + .left-bg { + position: absolute; + left: 0; + top: 0; + z-index: 200; + height: 100%; + width: 500px; + background: url("@/assets/images/left-bg.png"); + background-size: 100% 100%; + box-sizing: border-box; + padding: 120px 47px 67px 47px; + } + .right-bg { + position: absolute; + right: 0; + top: 0; + z-index: 100; + height: 100%; + width: 500px; + background: url("@/assets/images/right-bg.png"); + background-size: 100% 100%; + box-sizing: border-box; + padding: 120px 47px 67px 47px; } - </style> - \ No newline at end of file +} +</style> diff --git a/src/views/components/map/marsMap.vue b/src/views/components/map/marsMap.vue index 36a3562..4883b3d 100644 --- a/src/views/components/map/marsMap.vue +++ b/src/views/components/map/marsMap.vue @@ -17,15 +17,9 @@ let options = { }, showSun: false, showMoon: false, - showSkyBox: false, - showSkyAtmosphere: false, + showSkyBox: true, + showSkyAtmosphere: true, fog: false, - // backgroundColor: "#363635", // 天空背景色 - globe: { - baseColor: "#363635", // 地球地面背景色 - showGroundAtmosphere: false, - enableLighting: false, - }, clock: { currentTime: "2023-11-01 12:00:00", // 固定光照时间 }, @@ -62,8 +56,39 @@ let options = { }, ], }; +const params = reactive({ + lat: 31.162232, + lng: 120.734077, + altitude: 3000, + heading: 0, //当前朝向 + pitch: 0, //保当前俯仰角 + roll: 0, //当前翻滚角 + correction: 1, + speed: 800, + +}); +const EARTH_RADIUS = 6371000; +let isUav = true +const DIRECTION = { + UP: "w", + DOWN: "s", + LEFT: "a", + RIGHT: "d", + SPEED_UP: "q", + SPEED_DOWN: "e", +}; +const keyboardMap = { + [DIRECTION.UP]: false, + [DIRECTION.DOWN]: false, + [DIRECTION.LEFT]: false, + [DIRECTION.RIGHT]: false, + [DIRECTION.SPEED_UP]: false, + [DIRECTION.SPEED_DOWN]: false, +}; let map = null; +let list = []; +let uav = null const mapLayer = {}; const mapLoad = (mapInstance) => { map = mapInstance; @@ -73,38 +98,152 @@ const mapLoad = (mapInstance) => { }); map.addLayer(mapLayer.markerLayer); //创建无人机固定巡航 - initUav() - // 绘制停机场矩形 - initRectangle(); - initMarker(); + // initUav() + // // 绘制停机场矩形 + // initRectangle(); + // initMarker(); + + + boostrapUav() }; -const initUav = ()=>{ - let list = [] - PointJson.map(item=>{ - list.push(item.wz.split(",").map(Number)) - }) - const uav = new mars3d.graphic.Route({ +const boostrapUav = () => { + // initUav() + // onAddKeyboardListener() + // const renderer = () => { + // onAdjustParams(); + // onAdjustAttitude(); + // requestAnimationFrame(renderer); + // }; + // renderer(); +} + +//开启按键监听 +const onAddKeyboardListener = () => { + document.addEventListener("keydown", (e) => { + if (Object.keys(keyboardMap).includes(e.key)) { + keyboardMap[e.key] = true; + } + }); + document.addEventListener("keyup", (e) => { + if (Object.keys(keyboardMap).includes(e.key)) { + keyboardMap[e.key] = false; + } + }); +}; + +//开启飞行参数调整 +const onAdjustParams = () => { + if (keyboardMap[DIRECTION.SPEED_UP]) { + params.speed += 100; + } + if (keyboardMap[DIRECTION.SPEED_DOWN]) { + if (params.speed >= 500) { + params.speed -= 100; + } + } + //机体爬升 + if (keyboardMap[DIRECTION.UP] && params.pitch <= 0.3) { + params.pitch += 0.005; + if (params.pitch > 0) { + const { speed, pitch } = params; + const temp = (params.speed / 60 / 60 / 60) * 110; + //1经纬度约等于110km + params.altitude += temp * Math.sin(pitch); + } + } + //机体俯冲 + if (keyboardMap[DIRECTION.DOWN] && params.pitch >= -0.3) { + params.pitch -= 0.006; + if (params.pitch < 0) { + const { speed, pitch } = params; + //1经纬度约等于110km + const temp = (params.speed / 60 / 60 / 60) * 110; + params.altitude += temp * Math.sin(pitch); + } + } + //机体左转 + if (keyboardMap[DIRECTION.LEFT]) { + params.heading -= 0.115; + if (params.roll > -10) { + params.roll -= 0.115; + } + } + //机体右转 + if (keyboardMap[DIRECTION.RIGHT]) { + params.heading += 0.115; + if (params.roll < 10) { + params.roll += 0.115; + } + + } + const { heading, pitch, roll } = params; + const { abs, cos } = Math; + params.correction = abs(cos(heading) * cos(pitch)); + if (abs(heading) < 0.001) params.heading = 0; + if (abs(roll) < 0.001) params.roll = 0; + if (abs(pitch) < 0.001) params.pitch = 0; + //方向自动回正 + // if (params.heading > 0) params.heading -= 0.0025 + // if (params.heading < 0) params.heading += 0.0025 + if (params.roll > 0) params.roll -= 0.003; + if (params.roll < 0) params.roll += 0.003; + if (params.pitch < 0) params.pitch += 0.005; + if (params.pitch > 0) params.pitch -= 0.003; +}; + +// 开启飞行姿态调整/ +const onAdjustAttitude = () => { + const temp = params.speed / 60 / 60 / 60 / 110; + params.lng += temp * Math.cos(params.heading); + params.lat -= temp * Math.sin(params.heading); + const { lng, lat, altitude, heading, pitch, roll } = params; + + params.altitude += temp * Math.sin(pitch) * 110 * 1000 * 10; + + const position = Cesium.Cartesian3.fromDegrees(lng, lat, altitude); + + uav.model.setStyle({ + heading, + pitch, + roll + }); + uav.addTimePosition(position); + + +}; + + +const initUav = () => { + if (list.length == 0) { + PointJson.map((item) => { + list.push(item.wz.split(",").map(Number)); + }); + } + + uav = new mars3d.graphic.Route({ id: "uav", name: "无人机模型", position: { - type: "time", // 时序动态坐标 - speed: 100, - list: list - }, + type: "time", // 时序动态坐标 + speed: 100, + list: list, + }, model: { url: "https://data.mars3d.cn/gltf/mars/wrj.glb", scale: 0.1, minimumPixelSize: 0.1, runAnimations: true, mergeOrientation: true, + }, + camera: { type: "gs", - } - }) + }, + }); mapLayer.markerLayer.addGraphic(uav); -} +}; const initRectangle = () => { const graphic = new mars3d.graphic.RectanglePrimitive({ @@ -124,7 +263,6 @@ const initRectangle = () => { mapLayer.markerLayer.addGraphic(graphic); }; - /** * 渲染所有点位 */ diff --git a/src/views/components/map/panelLeft.vue b/src/views/components/map/panelLeft.vue index 9ba79d7..cdd3110 100644 --- a/src/views/components/map/panelLeft.vue +++ b/src/views/components/map/panelLeft.vue @@ -9,6 +9,6 @@ <style scoped> .panel-left{ - left: 46px; + } </style> \ No newline at end of file diff --git a/src/views/map.vue b/src/views/map.vue index 5aaa201..bc384da 100644 --- a/src/views/map.vue +++ b/src/views/map.vue @@ -1,11 +1,16 @@ <template> <div> <map-container> - <!-- <panel-left></panel-left> - <panel-right></panel-right> --> - <mars-map></mars-map> + <template #map> + <mars-map></mars-map> + </template> + <template #left> + <panel-left></panel-left> + </template> + <template #right> + <panel-right></panel-right> + </template> </map-container> - </div> </template> @@ -20,12 +25,8 @@ import { <style lang="scss" scoped> .panel-box { - position: absolute; - top: 50%; - z-index: 100; - transform: translateY(-50%); - height: calc(100% - 175px); - width: 390px; + height: 100%; + width: 100%; background: url("../assets/images/panel-bg.png"); background-size: 100% 100%; }