From 49f1198d1f2da71f6213270dfe94be9b34ebf235 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Mon, 07 Apr 2025 20:41:50 +0800
Subject: [PATCH] feat: 量尺
---
src/assets/images/rSide/lc.png | 0
src/components/UserOperate.vue | 2
src/assets/images/rSide/dw1.png | 0
src/views/Home/RSide.vue | 46 +++++--
src/assets/images/cpoint.png | 0
src/views/Home/useMapAggregation/useMapAggregation.js | 6
src/views/TestTemplate.vue | 2
src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue | 8
src/assets/images/rSide/tc.png | 0
src/views/SignMachineNest/MachineRight/MachineTableDetails/MachineTableDetails.vue | 25 +++-
src/assets/images/rSide/dw.png | 0
src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetails.vue | 1
src/assets/images/rSide/tc1.png | 0
src/assets/images/newcon_box.png | 0
src/components/MeasuringDistance.vue | 254 ++++++++++++++++++++++++++++++++++++++++++
src/assets/images/rSide/lc1.png | 0
src/views/Home/Home.vue | 2
17 files changed, 317 insertions(+), 29 deletions(-)
diff --git a/src/assets/images/cpoint.png b/src/assets/images/cpoint.png
new file mode 100644
index 0000000..d9f005a
--- /dev/null
+++ b/src/assets/images/cpoint.png
Binary files differ
diff --git a/src/assets/images/newcon_box.png b/src/assets/images/newcon_box.png
new file mode 100644
index 0000000..483bf7a
--- /dev/null
+++ b/src/assets/images/newcon_box.png
Binary files differ
diff --git a/src/assets/images/rSide/dw.png b/src/assets/images/rSide/dw.png
new file mode 100644
index 0000000..faf5def
--- /dev/null
+++ b/src/assets/images/rSide/dw.png
Binary files differ
diff --git a/src/assets/images/self-positioning.png b/src/assets/images/rSide/dw1.png
similarity index 100%
rename from src/assets/images/self-positioning.png
rename to src/assets/images/rSide/dw1.png
Binary files differ
diff --git a/src/assets/images/measuring-scale.png b/src/assets/images/rSide/lc.png
similarity index 100%
rename from src/assets/images/measuring-scale.png
rename to src/assets/images/rSide/lc.png
Binary files differ
diff --git a/src/assets/images/rSide/lc1.png b/src/assets/images/rSide/lc1.png
new file mode 100644
index 0000000..27791c0
--- /dev/null
+++ b/src/assets/images/rSide/lc1.png
Binary files differ
diff --git a/src/assets/images/layer.png b/src/assets/images/rSide/tc.png
similarity index 100%
rename from src/assets/images/layer.png
rename to src/assets/images/rSide/tc.png
Binary files differ
diff --git a/src/assets/images/rSide/tc1.png b/src/assets/images/rSide/tc1.png
new file mode 100644
index 0000000..b9c5208
--- /dev/null
+++ b/src/assets/images/rSide/tc1.png
Binary files differ
diff --git a/src/components/MeasuringDistance.vue b/src/components/MeasuringDistance.vue
new file mode 100644
index 0000000..a7db8a9
--- /dev/null
+++ b/src/components/MeasuringDistance.vue
@@ -0,0 +1,254 @@
+<!-- 量尺模式 -->
+<template>
+ <div class="container"></div>
+</template>
+
+<script>
+import cesiumOperation from '@/utils/cesium-tsa'
+import cpoint from '@/assets/images/cpoint.png'
+const {
+ addLeftClickEvent,
+ removeLeftClickEvent,
+ removeById,
+ addRightClickEvent,
+ removeRightClickEvent,
+ globalCesium
+} = cesiumOperation()
+
+export default {
+ data () {
+ return {
+ positions: [],
+ menuPopup: null,
+ temporaryPointsDeleted: null,
+ alldistance: 0,
+ }
+ },
+ methods: {
+ // Prevent default Event
+ preventDefault (event) {
+ event.preventDefault()
+ },
+ init () {
+ addLeftClickEvent(null, this.handleMapClick)
+ addRightClickEvent(null, this.RightClickEvent)
+ let cesium = document.getElementById('cesium')
+ cesium.addEventListener('contextmenu', this.preventDefault)
+ },
+ remove () {
+ removeLeftClickEvent()
+ let cesium = document.getElementById('cesium')
+ cesium.removeEventListener('contextmenu', this.preventDefault)
+ if (this.menuPopup) {
+ window.$viewer.container.removeChild(this.menuPopup)
+ }
+ removeRightClickEvent()
+ removeById('route_planning')
+ removeById('alldistanceshow')
+ this.positions.forEach((_position, index) => {
+ removeById('created_point_' + index)
+ removeById('distance_' + index)
+ })
+ },
+ // 左键点击事件
+ handleMapClick (click) {
+ if (this.menuPopup) {
+ window.$viewer.container.removeChild(this.menuPopup)
+ this.menuPopup = null
+ }
+ const { position } = click
+ const ellipsoid = window.$viewer.scene.globe.ellipsoid
+ const c3Position = window.$viewer.scene.globe.pick(
+ window.$viewer.camera.getPickRay(position),
+ window.$viewer.scene,
+ )
+ const c2Postion = ellipsoid.cartesianToCartographic(c3Position)
+ const longitude = globalCesium.Math.toDegrees(c2Postion.longitude)
+ const latitude = globalCesium.Math.toDegrees(c2Postion.latitude)
+ this.positions.push({ longitude, latitude })
+ this.createWayline(this.positions)
+ },
+ // 创建点位
+ createWayline (positions) {
+ this.alldistance = 0
+ const cartesian3Arr = []
+ positions.forEach((position, index) => {
+ removeById('created_point_' + index)
+ removeById('distance_' + index)
+ const cartesian3 = globalCesium.Cartesian3.fromDegrees(
+ Number(position.longitude),
+ Number(position.latitude),
+ 0,
+ )
+ cartesian3Arr.push(cartesian3)
+ window.$viewer.entities.add({
+ id: 'created_point_' + index,
+ position: cartesian3,
+ billboard: {
+ image: cpoint,
+ pixelOffset: new globalCesium.Cartesian2(0, -13),
+ outlineWidth: 0,
+ width: 30,
+ height: 30,
+ scale: 1.0,
+ },
+ })
+ // 给最后一个点增加总长度展示
+ if (this.positions.length == index + 1 && this.alldistance != 0) {
+ removeById('alldistanceshow')
+ window.$viewer.entities.add({
+ position: cartesian3,
+ id: 'alldistanceshow',
+ label: {
+ text: `总长度:${this.alldistance}m`,
+ font: '12px monospace',
+ showBackground: true,
+ horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
+ verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
+ pixelOffset: new globalCesium.Cartesian2(40, 20),
+ },
+ })
+ }
+ //给每个点增加右击事件
+ addRightClickEvent('created_point_' + index, this.RightClickEvent)
+
+ if (positions[index + 1]) {
+ const next = positions[index + 1]
+ const { longitude: nextLng, latitude: nextLat } = next
+ const nextPoint = globalCesium.Cartesian3.fromDegrees(nextLng, nextLat, 0)
+ // 获取中心点
+ const centerPoint = globalCesium.Cartesian3.lerp(
+ cartesian3,
+ nextPoint,
+ 0.5,
+ new globalCesium.Cartesian3(),
+ )
+ // 获取两个点之间的距离并展示
+ let distance = globalCesium.Cartesian3.distance(cartesian3, nextPoint)
+ distance = Math.round(distance)
+ this.alldistance = this.alldistance + distance
+ if (positions.length < 1 || distance === 0) return
+ this.createDistanceLabel(centerPoint, distance, index)
+ }
+ })
+ removeById('route_planning')
+ window.$viewer.entities.add({
+ id: 'route_planning',
+ polyline: {
+ width: 7,
+ positions: cartesian3Arr,
+ material: new globalCesium.PolylineOutlineMaterialProperty({
+ color: globalCesium.Color.WHITE,
+ outlineWidth: 2,
+ outlineColor: globalCesium.Color.BLUE,
+ }),
+ clampToGround: false,
+ },
+ })
+ },
+ createDistanceLabel (position, dist, index) {
+ return window.$viewer.entities.add({
+ position: position,
+ id: 'distance_' + index,
+ label: {
+ text: `${dist}m`,
+ font: '12px monospace',
+ showBackground: true,
+ horizontalOrigin: globalCesium.HorizontalOrigin.CENTER,
+ verticalOrigin: globalCesium.VerticalOrigin.BOTTOM,
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
+ pixelOffset: new globalCesium.Cartesian2(0, -0),
+ },
+ })
+ },
+ // 添加右键菜单
+ RightClickEvent (click, pick, viewer) {
+ if (this.menuPopup) {
+ window.$viewer.container.removeChild(this.menuPopup)
+ this.menuPopup = null
+ }
+ if (this.positions.length == 0) return
+ const { position } = click
+ const { x, y } = position
+ this.menuPopup = this.createMenuPopup(pick)
+ this.menuPopup.addEventListener('click', this.appendPoint)
+ this.menuPopup.style.transform = `translate3d(${x}px, ${y}px, 0)`
+ window.$viewer.container.appendChild(this.menuPopup)
+ if (!pick) return
+ this.temporaryPointsDeleted = pick.id._id
+ },
+ // 创建弹窗
+ createMenuPopup (pick) {
+ const menuPopup = document.createElement('div')
+ menuPopup.className = 'create-wayline-menu'
+ const arr = [
+ { title: '删除点位', class: 'del-wayline' },
+ { title: '清空', class: 'remove-all' },
+ ]
+ // 只有对点位进行右击时,才能单独进行点位删除
+ if (!pick || ['route_planning', 'drone_dock'].includes(pick.id._id)) {
+ arr.splice(0, 1)
+ }
+ arr.forEach((item) => {
+ const title = document.createElement('div')
+ title.innerText = item.title
+ title.style.fontSize = '14px'
+ title.style.padding = '5px'
+ title.className = item.class
+ menuPopup.appendChild(title)
+ })
+ return menuPopup
+ },
+ // 对航点增加点击事件
+ appendPoint (e) {
+ const className = e.target.className
+ window.$viewer.container.removeChild(this.menuPopup)
+ this.menuPopup = null
+ removeById('route_planning')
+ removeById('alldistanceshow')
+ this.positions.forEach((_position, index) => {
+ removeById('created_point_' + index)
+ removeById('distance_' + index)
+ })
+ // 清空
+ if (className === 'remove-all') {
+ this.positions = []
+ }
+ // 单点删除
+ else {
+ this.positions.splice(this.temporaryPointsDeleted.split('_')[2], 1)
+ this.createWayline(this.positions)
+ }
+ },
+ },
+ mounted () {
+ this.init()
+ },
+ beforeUnmount () {
+ this.remove()
+ },
+}
+</script>
+
+<style lang="scss">
+.create-wayline-menu {
+ width: 'fit-content';
+ background: url('@/assets/images/newcon_box.png') no-repeat center / 100% 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ color: #fff;
+ font-size: 16px;
+
+ div {
+ padding: 5px 10px;
+ cursor: pointer;
+ font-weight: bold;
+
+ &:hover {
+ background-color: rgba(0, 0, 0, 0.3);
+ }
+ }
+}
+</style>
diff --git a/src/components/UserOperate.vue b/src/components/UserOperate.vue
index bccb5c4..5f07fff 100644
--- a/src/components/UserOperate.vue
+++ b/src/components/UserOperate.vue
@@ -45,7 +45,7 @@
.userOperate {
position: absolute;
right: 27px;
- top: -30px;
+ top: -35px;
width: 132px;
height: 38px;
display: flex;
diff --git a/src/views/Home/Home.vue b/src/views/Home/Home.vue
index 3a4de79..90ae6c3 100644
--- a/src/views/Home/Home.vue
+++ b/src/views/Home/Home.vue
@@ -21,6 +21,7 @@
import RSide from '@/views/Home/RSide.vue';
import { onMounted } from 'vue';
import cesiumOperation from '@/utils/cesium-tsa';
+import MeasuringDistance from '@/components/MeasuringDistance.vue';
const store = useStore();
const { _init,viewerDestory } = cesiumOperation();
@@ -28,6 +29,7 @@
onUnmounted(()=>{
store.commit('setSingleUavHome',null);
+ console.log('home销毁')
viewerDestory()
})
diff --git a/src/views/Home/RSide.vue b/src/views/Home/RSide.vue
index ffc2da6..3baca19 100644
--- a/src/views/Home/RSide.vue
+++ b/src/views/Home/RSide.vue
@@ -1,6 +1,5 @@
<template>
<div class="ai-chat">
-
<el-popover
placement="bottom"
:visible="visible"
@@ -16,25 +15,43 @@
<el-input/>
</div>
</el-popover>
-
-
<img class="chat-bottom" src="../../assets/images/chat-bottom.png" alt="">
</div>
<div class="r-side">
- <img class="positioning" src="../../assets/images/self-positioning.png" alt="" @mouseenter="enterHover(0)" @mouseleave="logIndex=3">
- <img class="measuring-scale" src="../../assets/images/measuring-scale.png" alt="" @mouseenter="enterHover(1)" @mouseleave="logIndex=3">
- <img class="layer" src="../../assets/images/layer.png" alt="" @mouseenter="enterHover(2)" @mouseleave="logIndex=3">
+ <img v-for="(item, index) in images"
+ :key="index" :class="item.class"
+ :src="activeIndex === index ? item.activeSrc : item.src" alt=""
+ @click="activeChange(index)"
+ @mouseenter="enterHover(index)"
+ @mouseleave="logIndex=3"
+ >
</div>
- <div v-if="logIndex===0" class="r-side-positioning">切换地图模式</div>
+ <div v-if="logIndex===0" class="r-side-positioning">返回当前位置</div>
<div v-if="logIndex===1" class="r-side-measuring">量尺</div>
- <div v-if="logIndex===2" class="r-side-layer">返回当前位置</div>
+ <div v-if="logIndex===2" class="r-side-layer">切换地图模式</div>
+ <MeasuringDistance v-if="activeIndex === 1"/>
</template>
<script setup>
import vDrag from '@/directive/drag'
+import MeasuringDistance from '@/components/MeasuringDistance.vue'
+import dw from '@/assets/images/rSide/dw.png'
+import dw1 from '@/assets/images/rSide/dw1.png'
+import lc from '@/assets/images/rSide/lc.png'
+import lc1 from '@/assets/images/rSide/lc1.png'
+import tc from '@/assets/images/rSide/tc.png'
+import tc1 from '@/assets/images/rSide/tc1.png'
+
let logIndex = ref(3);
const enterHover = (value) => {
- logIndex.value = value;
+ logIndex.value = value;
+}
+
+let activeIndex = ref(null);
+const activeChange = (value) => {
+ if (value === 1){
+ activeIndex.value = activeIndex.value === 1 ? null : value;
+ }
}
const visible = ref(false);
let pressStart = 0;
@@ -50,6 +67,13 @@
visible.value = !visible.value;
}
};
+
+// 添加: 定义图片数组
+const images = [
+ { class: 'positioning', src: dw,activeSrc:dw1 },
+ { class: 'measuring-scale', src: lc,activeSrc:lc1 },
+ { class: 'layer', src: tc,activeSrc:tc1 }
+];
</script>
<style scoped lang="scss">
@@ -63,8 +87,6 @@
height: 68px;
display: block;
};
-
-
.chat {
position: fixed;
bottom: 330px;
@@ -116,5 +138,5 @@
.r-side-layer {
bottom: 122px;
}
-
</style>
+
diff --git a/src/views/Home/useMapAggregation/useMapAggregation.js b/src/views/Home/useMapAggregation/useMapAggregation.js
index c3f6248..f28e071 100644
--- a/src/views/Home/useMapAggregation/useMapAggregation.js
+++ b/src/views/Home/useMapAggregation/useMapAggregation.js
@@ -160,8 +160,6 @@
const splashedList = type === 'device'
? await getDeviceList(areaCode)
: eventList.map(i=>({eventId:i.id,latitude:Number(i.latitude),longitude:Number(i.longitude),type:'event'}))
- console.log(list, 'list');
- console.log(splashedList, 'splashedList');
const hierarchy = convertToHierarchy(areaCode.slice(0, 6));
const jsonPath = hierarchy.join('/');
const jsonPathPre = hierarchy.slice(0, hierarchy.length - 1).join('/');
@@ -305,9 +303,10 @@
id: feature.id,
position: position,
label: {
- text: feature.data.total_device_count.toString(),
+ text: (feature.data.total_device_count || 0).toString(),
font: '12pt Source Han Sans CN',
fillColor: Cesium.Color.BLACK,
+ outlineColor: Cesium.Color.BLACK,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
eyeOffset: new Cesium.Cartesian3(0, 0, -10), // 让label "浮" 在广告牌前面
},
@@ -426,6 +425,7 @@
// 移除所有监听事件,变量置空
const removeAll = () => {
+ if (!viewer) return
removeEntities();
removeLabel();
// viewer.camera.moveEnd.removeEventListener(determineScaling);
diff --git a/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetails.vue b/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetails.vue
index 5a12471..d7be14f 100644
--- a/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetails.vue
+++ b/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetails.vue
@@ -86,7 +86,6 @@
}
const getDetails = () => {
getJobDetails({ wayLineJobInfoId: wayLineJodInfoId.value }).then(res => {
- console.log(res.data.data, 666)
detailsData.value = res.data.data
infoList.value.forEach(item => {
item.value = detailsData.value?.[item.field] || ''
diff --git a/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue b/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
index 75e3fc3..cef055c 100644
--- a/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
+++ b/src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
@@ -95,9 +95,9 @@
const analysis = async url => {
return new Promise(async resolve => {
const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`)
- const templateXML = await res.fileInfoObj['wpmz/template.kml']
- const templateXMLJSON = XMLToJSON(templateXML)?.['Document']
- const templateXMLObj = removeTextKey(templateXMLJSON.Folder)
+ const waylinesXML = await res.fileInfoObj['wpmz/waylines.wpml']
+ const waylinesXMLJSON = XMLToJSON(waylinesXML)?.['Document']
+ const templateXMLObj = removeTextKey(waylinesXMLJSON.Folder)
resolve(templateXMLObj)
})
}
@@ -106,6 +106,7 @@
const drawLine = async () => {
const res = await Promise.all(props.detailsData.way_lines.map(item => analysis(item.url)))
res.map(item => renderingLine(item))
+ console.log(res,'jiexi')
const allPoint = res
.flatMap(item => item.Placemark)
.map(item => item.Point.coordinates.split(','))
@@ -113,7 +114,6 @@
}
const removeMap = () => {
- console.log('yichu')
viewer.entities.removeAll()
viewer.destroy()
}
diff --git a/src/views/SignMachineNest/MachineRight/MachineTableDetails/MachineTableDetails.vue b/src/views/SignMachineNest/MachineRight/MachineTableDetails/MachineTableDetails.vue
index 0a20550..1d641c2 100644
--- a/src/views/SignMachineNest/MachineRight/MachineTableDetails/MachineTableDetails.vue
+++ b/src/views/SignMachineNest/MachineRight/MachineTableDetails/MachineTableDetails.vue
@@ -24,18 +24,29 @@
import DeviceEvent from '@/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceEvent.vue'
import DeviceJob from '@/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJob.vue'
import { pxToRem } from '@/utils/rem';
+import { useStore } from 'vuex'
const isShowDetails = defineModel('show')
const infoList = ref([
- { name: '机巢名称', value: 'xxx' },
- { name: '机巢所属地区', value: 'xxx' },
- { name: '机巢状态', value: 'xxx' },
- { name: '任务成功', value: 'xxx' },
- { name: '机巢位置', value: 'xxx' },
+ { name: '机巢名称', value: '',field:'nickname' },
+ { name: '机巢所属地区', value: '',field:'device_area' },
+ { name: '机巢状态', value: '',field:'status' },
+ { name: '任务成功', value: '',field:'result_num' },
+ { name: '机巢位置', value: '',field:'address' },
])
-
-onMounted(() => {})
+const store = useStore();
+// state必须带上.home
+const singleTotal = computed(() => store.state.home.singleTotal);
+watch(singleTotal, (val) => {
+ if (val?.device_info){
+ infoList.value.forEach(item => {
+ item.value = val.device_info?.[item.field] || ''
+ })
+ }
+})
+onMounted(() => {
+})
</script>
<style lang="scss">
diff --git a/src/views/TestTemplate.vue b/src/views/TestTemplate.vue
index 0836554..a632042 100644
--- a/src/views/TestTemplate.vue
+++ b/src/views/TestTemplate.vue
@@ -4,11 +4,11 @@
import { useStore } from 'vuex';
const store = useStore();
-
// state必须带上.home
const singleUavHome = computed(() => store.state.home.singleUavHome);
// getters不需要带.home
const test = computed(() => store.getters.test);
+
onMounted(() => {
// commit dispatch 不需要带.home
store.commit('xxxx', '同步步修改啦');
--
Gitblit v1.9.3