无人机管理后台前端(已迁走)
张含笑
2025-08-25 ed55401fa7a62c88a07a65e08e3ede9fc98a99d6
feat:显示图斑
1 files modified
278 ■■■■ changed files
src/views/resource/components/spotDetails.vue 278 ●●●● patch | view | raw | blame | history
src/views/resource/components/spotDetails.vue
@@ -7,16 +7,7 @@
          <div v-for="(item, index) in infoList" :key="index" class="itemCon">
            <div class="itemBox">
              <div class="itemTitle">{{ item.name }}:</div>
              <div
                truncated
                class="itemValue"
                v-if="item.name !== '飞行事件' && item.name !== '任务执行次数'"
              >
                {{ item.value ? item.value : '--' }}
              </div>
              <div class="itemValue" v-if="item.name === '任务执行次数'">
                {{ item.value ? item.value : '0' }}次
              </div>
              <div class="itemValue">{{item.value}}</div>
            </div>
          </div>
        </div>
@@ -28,7 +19,7 @@
        <div class="table-overlay">
          <div class="table-content">
            <div>图斑列表</div>
            <el-table :data="tableData" border style="width: 100%">
            <el-table     ref="polygonTableEle" :data="tableData" border style="width: 100%" @row-click="handleLocationPolygon">
              <el-table-column type="index" label="序号" width="80">
                <template #default="{ $index }">
                  {{ ($index + 1).toString().padStart(2, '0') }}
@@ -37,15 +28,17 @@
              <el-table-column prop="dkbh" label="图斑名称" />
              <el-table-column prop="investigate" label="图斑状态" />
              <el-table-column label="操作" width="100" align="center">
                <el-button type="text">删除</el-button>
                <el-button type="text">编辑</el-button>
                <template #default="scope">
                    <el-button type="text">删除</el-button>
                <el-button type="text" @click="handleSelectionChange(scope.row)">编辑</el-button>
                </template>
              </el-table-column>
            </el-table>
            <div class="pagination-container">
              <el-pagination
                background
                layout="prev, pager, next"
                :total="10"
                :total="50"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
              />
@@ -60,19 +53,32 @@
</template>
<script setup>
import {getPatchesSpotList} from '@/api/patchManagement/index'
import {
    getCenterPoint,
    getLnglatDist,
    getLnglatAltitude,
    getPolygonMaxHeight,
    cartesian3Convert,
    getWaylineShowHeight,
} from '@/utils/cesium/mapUtil.js'
import { getPatchesSpotList } from '@/api/patchManagement/index';
import * as Cesium from 'cesium';
import { PublicCesium } from '@/utils/cesium/publicCesium';
import { ref, watch, onBeforeUnmount } from 'vue';
const uploadPatchDialog = defineModel('show');
const polygonTableEle = ref(null)
let publicCesiumInstance = null;
let viewer = null;
const viewInstance = shallowRef(null)
const homeViewer = shallowRef(null)
let tbJwdList = []
const viewInstance = shallowRef(null);
const homeViewer = shallowRef(null);
let tbJwdList = [];
// 当前选中的图斑面数据
let nowSelectObj = ref({})
// 记录上一次点击高亮
let lastHighlightRow = null
const infoList = ref([
  { name: '文件名称', value: '', field: 'job_info_num' },
  { name: '图斑类型', value: '', field: 'name' },
  { name: '文件名称', value: '55', field: 'job_info_num' },
  { name: '图斑类型', value: 'ee', field: 'name' },
  { name: '图斑数量', value: '', field: 'industry_type_str' },
  { name: '异常图斑数量', value: '', field: 'event_number' },
  { name: '行政区划', value: '', field: 'device_names' },
@@ -86,110 +92,36 @@
});
const handleSizeChange = () => {};
const handleCurrentChange = () => {};
const tableData = ref([])
const tableData = ref([]);
const polygonSearch = ref({
        investigate: '',
        isPush: '',
        isException: '',
        inRange: '1',
        dkbh: '',
        dkmj: '',
        page: 1,
        pageSize: 20,
        total: 0,
        workspaceId: 'ede19ef4-2e92-42f3-83cc-89afb54e95a7',
        area_code: '360000000000',
        device_sn: '',
    })
  investigate: '',
  isPush: '',
  isException: '',
  inRange: '1',
  dkbh: '',
  dkmj: '',
  page: 1,
  page_size: 1000,
  total: 0,
  workspaceId: 'ede19ef4-2e92-42f3-83cc-89afb54e95a7',
  area_code: '360000000000',
  device_sn: '',
});
// 获取列表数据
// const getTableList = async () => {
//     tableData.value = []
//     const res = await getPatchesSpotList(polygonSearch.value)
//     if (res.data.code !== 0) return
//     tableData.value = res.data.data.list.map(item => ({
//         ...item,
//         dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw,
//     }))
//     console.log('shuju ',tableData.value);
//     // 加载图斑
//     entitiesAddSpot()
// }
   const getTableList = async () => {
     tableData.value = []
     const res = await getPatchesSpotList(polygonSearch.value)
     if (res.data.code !== 0) return
     tableData.value = res.data.data.list.map(item => ({
       ...item,
       dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw,
     }))
     // 先清空地图现有图斑
     tbJwdList = []
     viewer.entities.removeAll() // 清除所有实体
     // 再加载新图斑
     entitiesAddSpot()
   }
// 初始化所有图斑
   const entitiesAddSpot = () => {
     tableData.value.forEach(item => {
       if (!item.dkfw) return
       const numbersWithCommas = item.dkfw.match(/\d+(\.\d+)?/g)
       if (!numbersWithCommas || numbersWithCommas.length % 2 !== 0) {
         console.error('Invalid coordinate format for item:', item.id)
         return
       }
       const grouped = numbersWithCommas.map(Number)
       tbJwdList.push({
         ...item,
         grouped: grouped,
       })
       try {
         homeViewer.value.entities.add({
           id: 'polygon_dk' + item.id,
           name: item.dkbh || '未命名图斑',
           polygon: {
             hierarchy: new Cesium.PolygonHierarchy(
               Cesium.Cartesian3.fromDegreesArray(grouped)
             ),
             material: item.is_exception == 1
               ? Cesium.Color.RED.withAlpha(0.5)
               : Cesium.Color.YELLOW.withAlpha(0.5),
             outline: true,
             outlineColor: Cesium.Color.WHITE,
             outlineWidth: 2,
             clampToGround: true
           },
           label: {
             text: item.dkbh || '',
             font: '14px sans-serif',
             style: Cesium.LabelStyle.FILL_AND_OUTLINE,
             outlineWidth: 2,
             verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
             pixelOffset: new Cesium.Cartesian2(0, -10)
           }
         })
       } catch (e) {
         console.error('Failed to add polygon:', e)
       }
     })
     // 自动缩放到所有图斑范围
     if (tbJwdList.length > 0) {
       const positions = tbJwdList.flatMap(item =>
         Cesium.Cartesian3.fromDegreesArray(item.grouped)
       )
       homeViewer.value.camera.flyToBoundingSphere(
         new Cesium.BoundingSphere.fromPoints(positions)
       )
     }
   }
const getTableList = async () => {
  tableData.value = [];
  const res = await getPatchesSpotList(polygonSearch.value);
  if (res.data.code !== 0) return;
  tableData.value = res.data.data.list.map(item => ({
    ...item,
    dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw,
  }));
  // 先清空地图现有图斑
  tbJwdList = [];
  viewer.entities.removeAll(); // 清除所有实体
  // 加载图斑
  entitiesAddSpot();
};
// 地图
const initMap = () => {
@@ -203,12 +135,107 @@
    flatMode: false,
    layerMode: 4,
  });
homeViewer.value = publicCesiumInstance.getViewer()
  homeViewer.value = publicCesiumInstance.getViewer();
  viewer = publicCesiumInstance.getViewer();
      viewInstance.value = publicCesiumInstance
  viewInstance.value = publicCesiumInstance;
  viewer.scene.globe.depthTestAgainstTerrain = true;
};
// 初始化所有图斑
const entitiesAddSpot = () => {
  tableData.value.forEach(item => {
    // 取出当中经纬度
    const numbersWithCommas = item.dkfw.match(/\d+(\.\d+)?/g);
    if (!numbersWithCommas) return;
    // 绘制图斑
    const grouped = numbersWithCommas.map(item => Number(item));
    // 为框选存储对比值
    tbJwdList.push({
      ...item,
      grouped: grouped,
    });
    viewInstance.value.removeById('polygon_dk' + item.id);
    homeViewer.value.entities?.add({
      id: 'polygon_dk' + item.id,
      customType: 'pattern_spot_polygon',
      customInfo: {
        ...item,
      },
      polygon: {
        hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(grouped)),
        material: Cesium.Color.YELLOW.withAlpha(0.5),
        outline: true,
        outlineColor: Cesium.Color.YELLOW,
        outlineWidth: 2,
        clampToGround: true,
      },
      zIndex: 99,
    });
    if (tbJwdList.length > 0) {
      const positions = tbJwdList.flatMap(item => Cesium.Cartesian3.fromDegreesArray(item.grouped));
      homeViewer.value.camera.flyToBoundingSphere(new Cesium.BoundingSphere.fromPoints(positions));
    }
    viewInstance.value.removeLeftClickEvent('spotHighlighting')
    viewInstance.value.addLeftClickEvent(null, spotHighlighting, 'spotHighlighting')
  });
};
// 编辑
const handleSelectionChange =(row)=>{
    heightlightSpot(row)
}
// 高亮当前选中图斑,并定位
const handleLocationPolygon = (data, Deselect) => {
    heightlightSpot(data)
}
// 鼠标触发点击图斑高亮 pick:可以获取当前图斑数据
const spotHighlighting = (click, pick, viewer) => {
    if (!pick || !(pick.id?.customType == 'pattern_spot_polygon')) return
    // 表格也对应选中数据 TODO
    const data = pick.id?.customInfo
    // 高亮图斑
    heightlightSpot(data)
}
// 选中列表或者点击地图内的图斑 高亮图斑
const heightlightSpot = data => {
    nowSelectObj.value = data
    if (!data) {
        clearSelect()
        return
    }
    // 保存当前选中图斑
    // 取出当中经纬度
    const numbersWithCommas = data.dkfw.match(/\d+(\.\d+)?/g)
    // 转换为二维数组
    const groupedArr = numbersWithCommas.reduce((acc, val, index, src) => {
        if (index % 2 === 0) acc.push(src.slice(index, index + 2))
        return acc
    }, [])
    // 求出中心点
    const polygonCenter = getCenterPoint(groupedArr)
    if (viewInstance.value.getEntityById('polygon_center')) {
        viewInstance.value.removeById('polygon_center')
    }
    // 高亮当前图斑,将上一个高亮图斑恢复
    if (lastHighlightRow) {
        let lastentity = homeViewer.value.entities?.getById('polygon_dk' + lastHighlightRow.id)
        if (lastentity && lastentity.polygon) {
            lastentity.polygon.material = Cesium.Color.YELLOW.withAlpha(0.5)
            lastentity.polygon.outlineColor = Cesium.Color.YELLOW
        }
    }
    let Nowentity = homeViewer.value.entities?.getById('polygon_dk' + data.id)
    if (Nowentity && Nowentity.polygon) {
        Nowentity.polygon.material = Cesium.Color.RED.withAlpha(0.3)
        Nowentity.polygon.outlineColor = Cesium.Color.RED
    }
    homeViewer.value.scene.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(Number(polygonCenter.lng), Number(polygonCenter.lat), 2500.0),
    })
    lastHighlightRow = data
}
// 销毁
const destroyMap = () => {
  if (viewer) {
@@ -222,7 +249,7 @@
  if (newVal) {
    setTimeout(() => {
      initMap();
      getTableList()
      getTableList();
    }, 0);
  } else {
    destroyMap();
@@ -231,7 +258,6 @@
onBeforeUnmount(() => {
  destroyMap();
});
</script>