| | |
| | | import request from '@/axios'; |
| | | export const treeDataApi = (params) => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/tree`, |
| | | method: 'get', |
| | | params, |
| | | |
| | | }) |
| | | }; |
| | | export const treeDataApi = params => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/tree`, |
| | | method: 'get', |
| | | params, |
| | | }); |
| | | }; |
| | | // 电子围栏 |
| | | // 编辑 |
| | | export const deitFenceApi = data => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/data`, |
| | | method: 'put', |
| | | data: data, |
| | | }); |
| | | }; |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/data`, |
| | | method: 'put', |
| | | data: data, |
| | | }); |
| | | }; |
| | | |
| | | // 删除 |
| | | export const deleteFenceApi = (id) => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/data/${id}`, |
| | | method: 'delete', |
| | | }); |
| | | }; |
| | | export const deleteFenceApi = id => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/data/${id}`, |
| | | method: 'delete', |
| | | }); |
| | | }; |
| | | |
| | | // 新增 |
| | | export const addFenceApi = (data) => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/data`, |
| | | method: 'post', |
| | | data |
| | | }) |
| | | } |
| | | export const addFenceApi = data => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/data`, |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }; |
| | | // 获取文件夹 |
| | | export const dataFolderApi = (id) => { |
| | | return request({ |
| | | url:`/drone-device-core/layer/api/v1/getFolderByCategoryId/${id}`, |
| | | method: 'get', |
| | | }) |
| | | }; |
| | | export const dataFolderApi = id => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/getFolderByCategoryId/${id}`, |
| | | method: 'get', |
| | | }); |
| | | }; |
| | | // 文件夹 |
| | | // 编辑 |
| | | export const deitFolderApi = data => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/folder`, |
| | | method: 'put', |
| | | data: data, |
| | | }); |
| | | }; |
| | | |
| | | // 删除 |
| | | export const deleteFolderApi = id => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/folder/${id}`, |
| | | method: 'delete', |
| | | }); |
| | | }; |
| | | |
| | | // 新增 |
| | | export const addFolderApi = data => { |
| | | return request({ |
| | | url: `/drone-device-core/layer/api/v1/folder`, |
| | | method: 'post', |
| | | data, |
| | | }); |
| | | }; |
| | |
| | | <div class="rightContainer"> |
| | | <div class="contenttitle">文件夹信息</div> |
| | | <div class="centerBox"> |
| | | |
| | | <div class="itemRow"> |
| | | <div class="label">文件夹名称</div> |
| | | <div> |
| | |
| | | class="ztzf-layer-search filter-item" |
| | | popper-class="ztzf-select-popper" |
| | | @change="handleTypeChange" |
| | | v-model="formData.type" |
| | | v-model="formData.event_type" |
| | | placeholder="请选择" |
| | | clearable |
| | | > |
| | |
| | | /> |
| | | </el-select> |
| | | <el-select |
| | | v-model="formData.algorithm" |
| | | v-model="formData.algorithm_name" |
| | | popper-class="ztzf-select-popper" |
| | | class="ztzf-layer-search" |
| | | placeholder="请选择" |
| | | clearable |
| | | :disabled="!formData.type" |
| | | :disabled="!formData.event_type" |
| | | > |
| | | <el-option |
| | | v-for="item in algorithms" |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="detailInfo"> |
| | | <div class="detailInfo" v-if="layerParams.editFolder"> |
| | | <div class="infpItem"> |
| | | <div class="itemData"> |
| | | <div class="title">围栏总数量</div> |
| | | <div class="num"><span>{{totalCount}}</span>个</div> |
| | | <div class="num"> |
| | | <span>{{ formData.total_count }}</span> 个 |
| | | </div> |
| | | </div> |
| | | <div class="itemData"> |
| | | <div class="title">围栏总面积</div> |
| | | <div class="num"><span>{{totalArea}}</span>m²</div> |
| | | <div class="num"> |
| | | <span>{{ formData.total_area }}</span> m² |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="infpItem"> |
| | | <div class="itemData"> |
| | | <div class="title">创建时间</div> |
| | | <div class="num"><span>{{formData?.create_time}}</span></div> |
| | | <div class="num"> |
| | | <span>{{ formData?.create_time }}</span> |
| | | </div> |
| | | </div> |
| | | <div class="itemData"> |
| | | <div class="title">创建人</div> |
| | | <div class="num"><span>{{formData?.create_name}}</span></div> |
| | | <div class="num"> |
| | | <span>{{ formData?.create_name }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { deitFenceApi } from '@/api/layer/index'; |
| | | import { |
| | | getTicketInfo, |
| | | } from '@/api/tickets/ticket'; |
| | | import { ElMessage } from 'element-plus'; |
| | | import dayjs from 'dayjs'; |
| | | import { deleteFolderApi, deitFolderApi, addFolderApi } from '@/api/layer/index'; |
| | | import { getTicketInfo } from '@/api/tickets/ticket'; |
| | | const layerParams = inject('layerParams'); |
| | | const types = ref([]) //工单类型 |
| | | const allAlgorithms = ref([]) |
| | | const algorithms = ref([]) |
| | | |
| | | const types = ref([]); //工单类型 |
| | | const allAlgorithms = ref([]); |
| | | const algorithms = ref([]); |
| | | const formData = ref({ |
| | | folder_id: '', |
| | | category_id: '', |
| | | name: '', |
| | | description: '', |
| | | is_enabled: false, |
| | | area: '', |
| | | altitude: '', |
| | | control_start_time: '', |
| | | control_end_time: '', |
| | | geo_data: '', |
| | | algorithm:'', |
| | | type: '', |
| | | event_type: '', |
| | | algorithm_name: '', |
| | | total_count: 0, |
| | | total_area: 0, |
| | | }); |
| | | const detailData = ref(null) |
| | | const totalArea = ref(null) |
| | | const totalCount = ref(null) |
| | | detailData.value = layerParams.value.editDetailData |
| | | totalArea.value = layerParams.value.total_area |
| | | totalCount.value = layerParams.value.total_count |
| | | |
| | | const detailData = ref(null); |
| | | detailData.value = layerParams.value.editFolderData; |
| | | const getTicketInfoData = async () => { |
| | | const response = await getTicketInfo() |
| | | const { dept_data, event_type, ai_type, info } = response.data.data |
| | | allAlgorithms.value = info |
| | | const response = await getTicketInfo(); |
| | | const { dept_data, event_type, ai_type, info } = response.data.data; |
| | | allAlgorithms.value = info; |
| | | types.value = Object.entries(event_type).map(([key, value]) => ({ |
| | | label: value, |
| | | value: key, |
| | | })) |
| | | |
| | | } |
| | | const handleTypeChange=(typeValue)=>{ |
| | | |
| | | const matchedCategory = allAlgorithms.value.find(category => category.dict_key === typeValue) |
| | | })); |
| | | }; |
| | | const handleTypeChange = typeValue => { |
| | | const matchedCategory = allAlgorithms.value.find(category => category.dict_key === typeValue); |
| | | if (!matchedCategory || !matchedCategory.algorithms || matchedCategory.algorithms.length === 0) { |
| | | // 无匹配的算法时清空 |
| | | algorithms.value = [] |
| | | return |
| | | algorithms.value = []; |
| | | return; |
| | | } |
| | | algorithms.value = matchedCategory.algorithms.map(algo => ({ |
| | | label: algo.dict_value, |
| | | value: algo.dict_key, |
| | | dict_key: algo.dict_key, |
| | | dict_value: algo.dict_value, |
| | | })) |
| | | console.log(' algorithms.value ', algorithms.value ); |
| | | } |
| | | })); |
| | | }; |
| | | const clearAllData = () => { |
| | | detailData.value = {} |
| | | // 清空回显相关数据 |
| | | formData.value = { |
| | | category_id: '', |
| | | name: '', |
| | | event_type: '', |
| | | algorithm_name: '', |
| | | total_count: 0, |
| | | total_area: 0, |
| | | create_time: '', |
| | | create_name: '', |
| | | }; |
| | | algorithms.value = []; |
| | | detailData.value = {}; |
| | | totalArea.value = null; |
| | | totalCount.value = null; |
| | | // 重置判断状态(可选,根据业务需求是否需要) |
| | | layerParams.value.decideWhetherToAddOrEdit = 1; |
| | | // 重置面板状态和缓存数据 |
| | | layerParams.value.addFolder = false; |
| | | layerParams.value.editFolder = false; |
| | | layerParams.value.editDetailData = null; |
| | | layerParams.value.polygonPosition = null; |
| | | }; |
| | | const cancelHandel = () => { |
| | | clearAllData() |
| | | |
| | | clearAllData(); |
| | | }; |
| | | const submitHandle = () => { |
| | | |
| | | clearAllData() |
| | | |
| | | const params = { |
| | | category_id: layerParams.value.fileType === 1 ? 1 : 2, |
| | | name: formData.value.name, |
| | | event_type: formData.value.event_type, |
| | | algorithm_name: formData.value.algorithm_name, |
| | | }; |
| | | // 如果是编辑模式,才添加 id |
| | | if (layerParams.value.addAnEditingFolder === 2) { |
| | | params.id = detailData.value.id; |
| | | } |
| | | if (layerParams.value.addAnEditingFolder === 1) { |
| | | // 文件夹新增 |
| | | addFolderApi(params).then(res => { |
| | | if (res.status === 200) { |
| | | ElMessage({ |
| | | message: '新增成功', |
| | | type: 'success', |
| | | }); |
| | | } |
| | | }); |
| | | } else { |
| | | //文件夹编辑 |
| | | deitFolderApi(params).then(res => { |
| | | if (res.status === 200) { |
| | | ElMessage({ |
| | | message: '编辑成功', |
| | | type: 'success', |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | clearAllData(); |
| | | }; |
| | | onMounted(() => { |
| | | getTicketInfoData() |
| | | onMounted(async () => { |
| | | |
| | | await getTicketInfoData(); |
| | | const addOrEditStatus = layerParams.value.addAnEditingFolder || 1; |
| | | // 判断是否有编辑数据,有则回显 |
| | | if (detailData.value && addOrEditStatus === 2) { |
| | | const editData = detailData.value; |
| | | formData.value = { |
| | | ...formData.value, |
| | | category_id: editData.category_id, |
| | | name: editData.name, |
| | | event_type: editData.event_type, // 回显“关联算法类型”值 |
| | | algorithm_name: editData.algorithm_name, // 回显“算法”值 |
| | | |
| | | total_count: editData.total_count, |
| | | total_area: editData.total_area, |
| | | create_time: editData.create_time ? dayjs(editData.create_time).format('YYYY年MM月DD日') : '', |
| | | create_name: editData.create_name, |
| | | }; |
| | | if (formData.value.event_type) { |
| | | handleTypeChange(formData.value.event_type); |
| | | |
| | | setTimeout(() => { |
| | | formData.value.algorithm_name = editData.algorithm_name; |
| | | }, 100); |
| | | } |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | |
| | | </div> |
| | | </div> |
| | | <div class="btnGroups"> |
| | | <el-button class="ztzf-button" @click="addFence">{{props.activeName === '电子围栏' ? '新增围栏' : '新增禁飞区'}}</el-button> |
| | | <el-button class="ztzf-button" @click="addFence">{{ |
| | | props.activeName === '电子围栏' ? '新增围栏' : '新增禁飞区' |
| | | }}</el-button> |
| | | <el-button class="ztzf-button" @click="addFolder">新增文件夹</el-button> |
| | | <el-button class="ztzf-button" @click="selectAll">全选</el-button> |
| | | </div> |
| | |
| | | <span>{{ node.label }}</span> |
| | | <!-- 操作按钮组 --> |
| | | <div class="tree-node-actions"> |
| | | <el-button v-if="node.level !== 1" |
| | | <el-button |
| | | |
| | | icon="el-icon-location" |
| | | type="text" |
| | | @click="handleLocation(node)" |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { treeDataApi ,deleteFenceApi} from '@/api/layer/index'; |
| | | import { ElMessage } from 'element-plus'; |
| | | import { treeDataApi, deleteFenceApi } from '@/api/layer/index'; |
| | | import { inject, onMounted } from 'vue'; |
| | | const emit = defineEmits(['update:coverData', 'update:deitData','newFencesMethods']); |
| | | import EventBus from '@/utils/eventBus' |
| | | const emit = defineEmits(['update:coverData', 'update:deitData', 'newFencesMethods']); |
| | | import EventBus from '@/utils/eventBus'; |
| | | const coverData = ref(); |
| | | const layerParams = inject('layerParams'); |
| | | const checkedKeys = ref([]); // 存储勾选的节点key |
| | |
| | | try { |
| | | const res = await treeDataApi(); |
| | | treeAllData.value = res.data.data; |
| | | console.log('接口数据',treeAllData.value); |
| | | console.log('接口数据', treeAllData.value); |
| | | |
| | | setupWatch(); |
| | | } catch (error) { |
| | |
| | | if (treeData.value && treeData.value.length > 0) { |
| | | const folderNode = treeData.value[0]; |
| | | // 赋值给 layerParams |
| | | layerParams.value.total_count = folderNode.total_count ?folderNode.total_count :0; |
| | | layerParams.value.total_area = folderNode.total_area ? folderNode.total_area :0; |
| | | } |
| | | layerParams.value.total_count = folderNode.total_count ? folderNode.total_count : 0; |
| | | layerParams.value.total_area = folderNode.total_area ? folderNode.total_area : 0; |
| | | } |
| | | }, |
| | | { immediate: true } |
| | | ); |
| | |
| | | |
| | | // 编辑按钮事件 |
| | | const handleEdit = node => { |
| | | checkedKeys.value = []; |
| | | checkedNodes.value = []; |
| | | coverData.value = []; |
| | | if (node.data.level == 2) { |
| | | layerParams.value.editFolder = true; |
| | | layerParams.value.addAnEditingFolder = 2; |
| | | if (props.activeName === '电子围栏') { |
| | | layerParams.value.fileType = 1; |
| | | } else if (props.activeName === '自定义禁飞区') { |
| | | layerParams.value.fileType = 2; |
| | | } |
| | | emit('update:editFolder', node.data); |
| | | } else if (node.data.level === 3) { |
| | | checkedKeys.value = []; |
| | | checkedNodes.value = []; |
| | | coverData.value = []; |
| | | layerParams.value.editNest = true; |
| | | layerParams.value.decideWhetherToAddOrEdit = 2 |
| | | if (props.activeName === '电子围栏') { |
| | | layerParams.value.fenceType = 1; // 电子围栏类型标识 |
| | | } else if (props.activeName === '自定义禁飞区') { |
| | | layerParams.value.fenceType = 2; // 自定义禁飞区类型标识 |
| | | layerParams.value.decideWhetherToAddOrEdit = 2; |
| | | if (props.activeName === '电子围栏') { |
| | | layerParams.value.fenceType = 1; // 电子围栏类型标识 |
| | | } else if (props.activeName === '自定义禁飞区') { |
| | | layerParams.value.fenceType = 2; // 自定义禁飞区类型标识 |
| | | } |
| | | emit('update:deitData', node.data); |
| | | } |
| | | emit('update:deitData', node.data); |
| | | }; |
| | | |
| | | // 删除按钮事件 |
| | | const handleDelete = node => { |
| | | let id = node.data.id |
| | | deleteFenceApi(id).then(res=>{ |
| | | console.log('删除成功',res); |
| | | }) |
| | | gettreeDataApi(); |
| | | let id = node.data.id; |
| | | deleteFenceApi(id).then(res => { |
| | | if (res.status === 200) { |
| | | ElMessage({ |
| | | message: '删除成功', |
| | | type: 'success', |
| | | }); |
| | | } |
| | | }); |
| | | gettreeDataApi(); |
| | | }; |
| | | // 新增围栏 |
| | | const addFence = () => { |
| | | layerParams.value.addNest = true; |
| | | layerParams.value.decideWhetherToAddOrEdit = 1 |
| | | if (props.activeName === '电子围栏') { |
| | | layerParams.value.decideWhetherToAddOrEdit = 1; |
| | | if (props.activeName === '电子围栏') { |
| | | layerParams.value.fenceType = 1; // 电子围栏类型标识 |
| | | } else if (props.activeName === '自定义禁飞区') { |
| | | layerParams.value.fenceType = 2; // 自定义禁飞区类型标识 |
| | | } |
| | | emit('newFencesMethods'); |
| | | emit('newFencesMethods'); |
| | | }; |
| | | // 新增文件夹 |
| | | const addFolder = () => { |
| | | layerParams.value.addFolder = true |
| | | layerParams.value.addAnEditingFolder =1 |
| | | layerParams.value.addFolder = true; |
| | | layerParams.value.addAnEditingFolder = 1; |
| | | if (props.activeName === '电子围栏') { |
| | | layerParams.value.fileType = 1; |
| | | } else if (props.activeName === '自定义禁飞区') { |
| | | layerParams.value.fileType = 2; |
| | | } |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | gettreeDataApi(); |
| | | EventBus.on('gettreeDataApi', gettreeDataApi) |
| | | EventBus.on('gettreeDataApi', gettreeDataApi); |
| | | }); |
| | | onBeforeUnmount(()=>{ |
| | | EventBus.off('gettreeDataApi', gettreeDataApi) |
| | | }) |
| | | onBeforeUnmount(() => { |
| | | EventBus.off('gettreeDataApi', gettreeDataApi); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | |
| | | // } |
| | | //} |
| | | |
| | | |
| | | :deep(){ |
| | | .el-checkbox{ |
| | | :deep() { |
| | | .el-checkbox { |
| | | --el-checkbox-bg-color: transparent !important; |
| | | } |
| | | } |
| | |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | width: 100%; |
| | | |
| | | } |
| | | |
| | | .tree-node-actions { |
| | |
| | | </div> |
| | | </div> |
| | | <div class="detailInfo"> |
| | | <div class="infpItem" v-if="layerParams.fenceType === 1"> |
| | | <div class="infpItem" v-if="layerParams.editNest"> |
| | | |
| | | <div class="itemData"> |
| | | <div class="title">围栏面积</div> |
| | |
| | | control_start_time: '', |
| | | control_end_time: '', |
| | | geo_data: '', |
| | | noFlyZoneArea: '', |
| | | |
| | | altitude:'' |
| | | }); |
| | | |
| | | const detailData = ref(null); |
| | | const totalArea = ref(null); |
| | | const totalCount = ref(null); |
| | | const fenceArea = ref(0) |
| | | detailData.value = layerParams.value.editDetailData; |
| | | totalArea.value = layerParams.value.total_area; |
| | | totalCount.value = layerParams.value.total_count; |
| | | fenceArea.value = layerParams.value.fenceArea |
| | | |
| | | watch( |
| | | () => layerParams.value.fenceArea, |
| | | (newArea) => { |
| | |
| | | watch( |
| | | () => timeValue.value, |
| | | (newTimeArr) => { |
| | | |
| | | if (Array.isArray(newTimeArr) && newTimeArr.length === 2) { |
| | | const startTime = newTimeArr[0]; |
| | | const endTime = newTimeArr[1]; |
| | |
| | | ); |
| | | const clearAllData = () => { |
| | | detailData.value = {}; |
| | | // 清空回显相关数据 |
| | | detailData.value = {}; |
| | | totalArea.value = null; |
| | | totalCount.value = null; |
| | | // 重置判断状态(可选,根据业务需求是否需要) |
| | | layerParams.value.decideWhetherToAddOrEdit = 1; |
| | | // 重置面板状态和缓存数据 |
| | | layerParams.value.addNest = false; |
| | |
| | | }; |
| | | const submitHandle = () => { |
| | | const params = { |
| | | folder_id: layerParams.value.fenceType === 1 ? 1 : 2, |
| | | folder_id: formData.value.folder_id, |
| | | name: formData.value.name, |
| | | description: formData.value.description, |
| | | is_enabled: true, |
| | |
| | | if (layerParams.value.decideWhetherToAddOrEdit === 2) { |
| | | params.id = detailData.value.id; |
| | | } |
| | | console.log('formData', params); |
| | | |
| | | if (layerParams.value.decideWhetherToAddOrEdit === 1) { |
| | | //围栏新增 |
| | |
| | | dayjs(editData.control_end_time).toDate() |
| | | ]; |
| | | } |
| | | // 回显总数和总面积(编辑时可能需要展示) |
| | | totalArea.value = layerParams.value.total_area || 0; |
| | | totalCount.value = layerParams.value.total_count || 0; |
| | | fenceArea.value = editData.area|| 0; |
| | | } else { |
| | | // 新增状态:不回显数据,清空总数和总面积 |
| | | totalArea.value = null; |
| | | totalCount.value = null; |
| | | } |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | |
| | | <div class="mapContainer"> |
| | | <div id="layMap" class="ztzf-cesium"></div> |
| | | <leftList |
| | | v-if="!layerParams.addNest && !layerParams.editNest&& !layerParams.addFolder && activeType !== '2'" |
| | | v-if=" |
| | | !layerParams.addNest && |
| | | !layerParams.editNest && |
| | | !layerParams.addFolder && |
| | | activeType !== '2' |
| | | " |
| | | @update:coverData="handleCoverDataUpdate" |
| | | @update:deitData="handleEdit" |
| | | @update:editFolder="handleFolder" |
| | | :activeName="activeName" |
| | | @newFencesMethods="newFencesMethods" |
| | | ></leftList> |
| | | <rightEdit |
| | | v-if="layerParams.addNest || layerParams.editNest && activeType !== '2'" |
| | | v-if="layerParams.addNest || (layerParams.editNest && activeType !== '2')" |
| | | @callParentMethod="parentMethod" |
| | | ></rightEdit> |
| | | <folderFile v-if="layerParams.addFolder || layerParams.editFolder && activeType !== '2'"></folderFile> |
| | | <folderFile |
| | | v-if="layerParams.addFolder || (layerParams.editFolder && activeType !== '2')" |
| | | ></folderFile> |
| | | <nationalSpatialPlanning v-if="activeType === '2'" /> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import * as turf from '@turf/turf' |
| | | import * as turf from '@turf/turf'; |
| | | import { dataFolderApi } from '@/api/layer/index'; |
| | | import folderFile from '@/views/layerManagement/components/folderFile.vue' |
| | | import folderFile from '@/views/layerManagement/components/folderFile.vue'; |
| | | import { parseGeoDataToPositions } from '@/utils/geoParseUtil'; |
| | | import { flyVisual } from '@/utils/cesium/mapUtil'; |
| | | import rightEdit from '@/views/layerManagement/components/rightEdit.vue'; |
| | | import leftList from '@/views/layerManagement/components/leftList.vue'; |
| | | import nationalSpatialPlanning from '@/views/layerManagement/components/nationalSpatialPlanning.vue' |
| | | import nationalSpatialPlanning from '@/views/layerManagement/components/nationalSpatialPlanning.vue'; |
| | | import { DrawPolygon } from '@/views/layerManagement/components/utils'; |
| | | import * as Cesium from 'cesium'; |
| | | import { PublicCesium } from '@/utils/cesium/publicCesium'; |
| | |
| | | editDetailData: null, |
| | | total_count: 0, |
| | | total_area: 0, |
| | | polygonPosition:null, |
| | | decideWhetherToAddOrEdit:null,//新增or编辑围栏 |
| | | addAnEditingFolder:null,//新增or编辑文件夹 |
| | | addFolder:false, |
| | | editFolder:false, |
| | | folderOption:[] ,//文件夹选项 |
| | | fenceType:1, |
| | | fenceArea:0,//围栏面积 |
| | | polygonPosition: null, |
| | | decideWhetherToAddOrEdit: null, //新增or编辑围栏 |
| | | addAnEditingFolder: null, //新增or编辑文件夹 |
| | | addFolder: false, |
| | | editFolder: false, |
| | | folderOption: [], //文件夹选项 |
| | | fenceType: 1, |
| | | fenceArea: 0, //围栏面积 |
| | | fileType: 1, //文件夹类型 |
| | | editFolderData: null, |
| | | }); |
| | | |
| | | const handleClick = tab => { |
| | |
| | | |
| | | activeType.value = clickedTab.type; |
| | | activeName.value = clickedTab.name; |
| | | getdataFolderApi(); |
| | | getdataFolderApi(); |
| | | }; |
| | | |
| | | const getdataFolderApi=()=>{ |
| | | let id; |
| | | const getdataFolderApi = () => { |
| | | let id; |
| | | if (activeName.value === '电子围栏') { |
| | | id = 1; |
| | | } else if (activeName.value === '自定义禁飞区') { |
| | | id = 2; |
| | | } else { |
| | | |
| | | return; |
| | | } |
| | | dataFolderApi(id).then(res=>{ |
| | | const originalFolderList = res.data.data || []; |
| | | const formattedFolderOption = originalFolderList.map(folder => ({ |
| | | label: folder.name, |
| | | value: folder.id.toString() |
| | | })); |
| | | layerParams.value.folderOption = formattedFolderOption; |
| | | }) |
| | | } |
| | | dataFolderApi(id).then(res => { |
| | | const originalFolderList = res.data.data || []; |
| | | const formattedFolderOption = originalFolderList.map(folder => ({ |
| | | label: folder.name, |
| | | value: folder.id.toString(), |
| | | })); |
| | | layerParams.value.folderOption = formattedFolderOption; |
| | | }); |
| | | }; |
| | | // 编辑围栏区域 |
| | | const handleEdit = val => { |
| | | viewer.entities.removeAll(); |
| | | viewer.entities.removeAll(); |
| | | layerParams.value.editDetailData = val; |
| | | drawPolygonExample.editThePatch(true); |
| | | const positions = parseGeoDataToPositions(val.geo_data, val.altitude); |
| | | const positions = parseGeoDataToPositions(val.geo_data, val.altitude); |
| | | if (positions.length < 3) return; // 少于3个点无法构成多边形 |
| | | drawPolygonExample.drawTheArea(true) |
| | | drawPolygonExample.drawTheArea(true); |
| | | drawPolygonExample.initPolygon(viewer, positions, true); |
| | | |
| | | }; |
| | | // 编辑文件夹 |
| | | const handleFolder = val => { |
| | | layerParams.value.editFolderData = val; |
| | | console.log('文件夹', layerParams.value.editFolderData); |
| | | }; |
| | | // 新增开启绘制 |
| | | const newFencesMethods =()=>{ |
| | | viewer.entities.removeAll(); |
| | | drawPolygonExample.initHandler(viewer); |
| | | drawPolygonExample.drawTheArea(true) |
| | | drawPolygonExample.startDrawing(); |
| | | } |
| | | const newFencesMethods = () => { |
| | | viewer.entities.removeAll(); |
| | | drawPolygonExample.initHandler(viewer); |
| | | drawPolygonExample.drawTheArea(true); |
| | | drawPolygonExample.startDrawing(); |
| | | }; |
| | | // 清除地图数据 |
| | | const parentMethod = () => { |
| | | drawPolygonExample.delPolygon() |
| | | drawPolygonExample.drawTheArea(false) |
| | | drawPolygonExample.delPolygon(); |
| | | drawPolygonExample.drawTheArea(false); |
| | | }; |
| | | // 点击显示区域 |
| | | const handleCoverDataUpdate = data => { |
| | |
| | | tbJwdList = []; |
| | | dataList.forEach(item => { |
| | | let positions = parseGeoDataToPositions(item.geo_data, item.altitude); |
| | | positions.push(positions[0]) |
| | | positions.push(positions[0]); |
| | | if (positions.length < 3) { |
| | | console.warn(`数据 ${item.name} 坐标点不足,无法绘制`); |
| | | return; |
| | |
| | | }); |
| | | }); |
| | | focusOnAllFeatures(); |
| | | viewInstance.value?.addLeftClickEvent(null, handleFenceClick, ); |
| | | viewInstance.value?.addLeftClickEvent(null, handleFenceClick); |
| | | }; |
| | | //计算所有图斑的包围球并定位 |
| | | const focusOnAllFeatures = () => { |
| | |
| | | viewInstance.value = publicCesiumInstance; |
| | | |
| | | const nanChangPosition = Cesium.Cartesian3.fromDegrees( |
| | | 115.892151, // 经度 |
| | | 28.676493, // 纬度 |
| | | 15000 // 相机高度 |
| | | 115.892151, // 经度 |
| | | 28.676493, // 纬度 |
| | | 15000 // 相机高度 |
| | | ); |
| | | |
| | | // 执行相机飞行 |
| | | viewer.camera.flyTo({ |
| | | destination: nanChangPosition, |
| | | duration: 0, |
| | | destination: nanChangPosition, |
| | | duration: 0, |
| | | orientation: { |
| | | heading: Cesium.Math.toRadians(0), |
| | | pitch: Cesium.Math.toRadians(-90), |
| | | roll: 0 |
| | | } |
| | | heading: Cesium.Math.toRadians(0), |
| | | pitch: Cesium.Math.toRadians(-90), |
| | | roll: 0, |
| | | }, |
| | | }); |
| | | |
| | | }; |
| | | |
| | | // 编辑/绘制 |
| | | const loadPlanarRoute = async (positions = null, save = false) => { |
| | | |
| | | if (positions) { |
| | | curPolygonPosition = positions.map(item => { |
| | | let cartographic = Cesium.Cartographic.fromCartesian(item); |
| | | let cartographic = Cesium.Cartographic.fromCartesian(item); |
| | | let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度 |
| | | let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度 |
| | | let height = Cesium.Math.toDegrees(cartographic.height); //高度 |
| | |
| | | }); |
| | | } |
| | | |
| | | |
| | | let polygon = curPolygonPosition.map(item => [item?.lng, item?.lat]); |
| | | |
| | | let polygonString = JSON.stringify(polygon); |
| | | // polygon.push([curPolygonPosition[0]?.lng, curPolygonPosition[0]?.lat]); |
| | | layerParams.value.polygonPosition = polygonString |
| | | if (polygon.length >= 3) { |
| | | layerParams.value.polygonPosition = polygonString; |
| | | if (polygon.length >= 3) { |
| | | // 确保多边形闭合:最后一个点与第一个点一致(避免计算偏差) |
| | | const firstPoint = polygon[0]; |
| | | const lastPoint = polygon[polygon.length - 1]; |
| | | const isClosed = ( |
| | | const isClosed = |
| | | _.round(firstPoint[0], 6) === _.round(lastPoint[0], 6) && |
| | | _.round(firstPoint[1], 6) === _.round(lastPoint[1], 6) |
| | | ); |
| | | _.round(firstPoint[1], 6) === _.round(lastPoint[1], 6); |
| | | // 若未闭合,手动添加闭合点 |
| | | const closedPolygon = isClosed ? polygon : [...polygon, firstPoint]; |
| | | |
| | | // 转换为 turf 支持的 GeoJSON 格式(Polygon 类型需外层嵌套数组) |
| | | const turfPolygon = turf.polygon([closedPolygon]); |
| | | |
| | | // 计算面积(turf.area() 返回平方米,保留2位小数) |
| | | const area = _.round(turf.area(turfPolygon), 2); |
| | | |
| | | // 赋值给 layerParams,供页面显示或提交使用 |
| | | // 赋值给 layerParams, |
| | | layerParams.value.fenceArea = area; |
| | | console.log('计算的多边形面积(平方米):', layerParams.value.fenceArea); |
| | | } else { |
| | | // 坐标点不足3个时,清空面积 |
| | | layerParams.value.fenceArea = 0; |
| | | } |
| | | }; |
| | | const throttleLoadPlanarRoute = throttle(loadPlanarRoute, 200); |
| | | drawPolygonExample.subscribe('getPolygonPositions', data => { |
| | | throttleLoadPlanarRoute(data); |
| | | }); |
| | | }; |
| | | const throttleLoadPlanarRoute = throttle(loadPlanarRoute, 200); |
| | | drawPolygonExample.subscribe('getPolygonPositions', data => { |
| | | throttleLoadPlanarRoute(data); |
| | | }); |
| | | |
| | | // 地图销毁 |
| | | const destroyMap = () => { |
| | |
| | | onMounted(() => { |
| | | initMap(); |
| | | cesiumContextMenu(); |
| | | getdataFolderApi() |
| | | getdataFolderApi(); |
| | | }); |
| | | |
| | | onBeforeUnmount(() => { |