| | |
| | | :row-class-name="tableRowClassName" |
| | | :data="tableData" |
| | | @row-click="handleLocationPolygon" |
| | | @current-change="handleTableRowChange" |
| | | |
| | | > |
| | | <el-table-column type="index" align="center" :width="pxToRemNum(30)" label="序号"> |
| | | <template #default="{ $index }"> |
| | | {{ |
| | | ($index + 1 + (params.page - 1) * params.pageSize).toString().padStart(2, '0') |
| | | }} |
| | | </template> |
| | | <template #default="{ $index }"> |
| | | {{ ($index + 1).toString().padStart(2, '0') }} |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column prop="dkbh" align="center" label="图斑名称" show-overflow-tooltip /> |
| | | <el-table-column prop="is_exception" :width="pxToRemNum(50)" align="center" label="图斑状态"> |
| | |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div class="pagination-container"> |
| | | <el-pagination |
| | | :current-page="params.page" |
| | | :page-size="params.pageSize" |
| | | background |
| | | layout="prev, pager, next, ..." |
| | | :pager-count="3" |
| | | prev-text="上一页" |
| | | next-text="下一页" |
| | | :total="total" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | |
| | | </div> |
| | | </div> |
| | | <!--绘制按钮--> |
| | |
| | | ref="drawPolygonRef" |
| | | v-if="isEditing" |
| | | @upDateDrawState="handleUpDateDrawState" |
| | | |
| | | /> |
| | | <!-- 完成/取消 --> |
| | | <div class="btnGroups" v-if="props.title === '图斑编辑'"> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { flyVisual } from '@/utils/cesium/mapUtil' |
| | | import { pxToRem, pxToRemNum } from '@/utils/rem' |
| | | import DrawPolygon from '@/views/resource/components/DrawPolygon.vue'; |
| | | import { ElMessage, ElMessageBox } from 'element-plus'; |
| | |
| | | page: 1, |
| | | pageSize: 10, |
| | | }); |
| | | const isInit = ref(true); |
| | | // 图斑管理表格 |
| | | const getTableList = () => { |
| | | const requestParams = { |
| | | patchesInfoId: props.detailid, |
| | | page: params.value.page, |
| | | pageSize: params.value.pageSize, |
| | | |
| | | }; |
| | | tableMapListApi(requestParams).then(res => { |
| | | tableData.value = res.data.data.records?.map(item => ({ |
| | | AlltableMapListApi(requestParams).then(res => { |
| | | tableData.value = res.data.data?.map(item => ({ |
| | | ...item, |
| | | dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw, |
| | | })); |
| | | total.value = res.data.data.total || res.data.data.length; |
| | | tbJwdList = []; |
| | | viewer?.entities.removeAll(); |
| | | if (!AlltableData.value) { |
| | | if (!tableData.value) { |
| | | viewInstance.value?.flyToContour(); |
| | | } else { |
| | | entitiesAddSpot(); |
| | | } |
| | | }); |
| | | }; |
| | | // 所有图斑数据 |
| | | const getAlltableMapListApi = () => { |
| | | loading.value = true; |
| | | const requestParams = { |
| | | patchesInfoId: props.detailid, |
| | | }; |
| | | AlltableMapListApi(requestParams).then(res => { |
| | | AlltableData.value = res.data.data?.map(item => ({ |
| | | ...item, |
| | | dkfw: item.sdfw && item.is_exception == 1 ? item.sdfw : item.dkfw, |
| | | })); |
| | | |
| | | tbJwdList = []; |
| | | viewer?.entities.removeAll(); |
| | | if (AlltableData.value.length < 1) { |
| | | viewInstance.value?.flyToContour(); |
| | | } else { |
| | | entitiesAddSpot(); |
| | | } |
| | | loading.value = false; |
| | | }); |
| | | }; |
| | | const handleSizeChange = val => { |
| | | params.value.pageSize = val; |
| | | params.value.page = 1; |
| | | getTableList(); |
| | | }; |
| | | const handleCurrentChange = val => { |
| | | params.value.page = val; |
| | | getTableList(); |
| | | }; |
| | | |
| | | |
| | | // 地图 |
| | | const initMap = () => { |
| | |
| | | viewer.scene.globe.depthTestAgainstTerrain = true; |
| | | viewInstance.value.switchContour(true); |
| | | }; |
| | | // 仅弹框初始化时执行的定位逻辑 |
| | | const initMapLocation = () => { |
| | | if (tbJwdList.length === 0 || !homeViewer.value) return; |
| | | |
| | | // 计算所有图斑的包围球(用于初始化定位) |
| | | const allPositions = tbJwdList.flatMap(item => |
| | | Cesium.Cartesian3.fromDegreesArray(item.grouped) |
| | | ); |
| | | const boundingSphere = Cesium.BoundingSphere.fromPoints(allPositions); |
| | | |
| | | // 初始化定位(仅执行一次) |
| | | homeViewer.value.camera.flyToBoundingSphere(boundingSphere, { |
| | | duration: 0, |
| | | offset: new Cesium.HeadingPitchRange( |
| | | Cesium.Math.toRadians(0), |
| | | Cesium.Math.toRadians(-90) |
| | | ), |
| | | }); |
| | | }; |
| | | // 初始化所有图斑 |
| | | const entitiesAddSpot = () => { |
| | | viewer?.entities.removeAll(); |
| | | AlltableData.value.forEach(item => { |
| | | // 取出当中经纬度 |
| | | tbJwdList = []; // 重置经纬度列表 |
| | | |
| | | 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); |
| | | // 根据 is_exception 设置颜色 |
| | | const color = |
| | | item.is_exception == 2 ? Cesium.Color.RED.withAlpha(0.5) : Cesium.Color.YELLOW.withAlpha(0.5); |
| | | const outlineColor = item.is_exception == 2 ? Cesium.Color.RED : Cesium.Color.YELLOW; |
| | | |
| | | const grouped = numbersWithCommas.map(Number); |
| | | tbJwdList.push({ ...item, grouped }); // 存储经纬度用于后续操作 |
| | | |
| | | // 绘制图斑(保留原有逻辑,仅移除定位相关代码) |
| | | const fillColor = item.is_exception === 2 |
| | | ? Cesium.Color.RED.withAlpha(0.5) |
| | | : Cesium.Color.YELLOW.withAlpha(0.5); |
| | | const outlineColor = item.is_exception === 2 |
| | | ? Cesium.Color.RED |
| | | : Cesium.Color.YELLOW; |
| | | |
| | | homeViewer.value?.entities?.add({ |
| | | id: 'polygon_dk' + item.id, |
| | | id: `polygon_dk${item.id}`, |
| | | customType: 'pattern_spot_polygon', |
| | | customInfo: { |
| | | ...item, |
| | | }, |
| | | customInfo: item, |
| | | polygon: { |
| | | hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(grouped)), |
| | | material: color, |
| | | material: fillColor, |
| | | outline: true, |
| | | outlineColor: outlineColor, |
| | | outlineWidth: 2, |
| | |
| | | polyline: { |
| | | positions: Cesium.Cartesian3.fromDegreesArray(grouped), |
| | | width: 2, |
| | | material: color, |
| | | material: outlineColor, |
| | | clampToGround: true, |
| | | }, |
| | | zIndex: 99, |
| | | }); |
| | | |
| | | if (tbJwdList.length > 0) { |
| | | const positions = tbJwdList.flatMap(item => Cesium.Cartesian3.fromDegreesArray(item.grouped)); |
| | | const boundingSphere = Cesium.BoundingSphere.fromPoints(positions); |
| | | homeViewer.value?.camera.flyToBoundingSphere(boundingSphere, { |
| | | duration: 0, |
| | | offset: new Cesium.HeadingPitchRange(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90)), |
| | | }); |
| | | } |
| | | viewInstance.value?.removeLeftClickEvent('spotHighlighting'); |
| | | viewInstance.value?.addLeftClickEvent(null, spotHighlighting, 'spotHighlighting'); |
| | | }); |
| | | |
| | | // 仅在初始化阶段执行定位(关键:通过isInit控制) |
| | | if (isInit.value) { |
| | | initMapLocation(); |
| | | isInit.value = false; // 初始化完成,后续不再执行定位 |
| | | } |
| | | |
| | | // 保留图斑点击高亮事件(原有逻辑不变) |
| | | viewInstance.value?.removeLeftClickEvent('spotHighlighting'); |
| | | viewInstance.value?.addLeftClickEvent(null, spotHighlighting, 'spotHighlighting'); |
| | | }; |
| | | |
| | | // 高亮当前选中图斑,并定位 |
| | |
| | | |
| | | updateMapSpotInfo(nowEntity); |
| | | } |
| | | |
| | | // 更新上一个和这一个信息 |
| | | function updateMapSpotInfo(nowEntity) { |
| | | const nowData = nowEntity.customInfo; |
| | | if (!nowEntity) return; |
| | | if (nowEntity.customInfo.id === lastEntity?.customInfo.id) return; |
| | | // 设置新的 |
| | | nowEntity.polygon.material = Cesium.Color.RED.withAlpha(0); |
| | | nowEntity.polyline.material = Cesium.Color.RED; |
| | | // 重置上一个 |
| | | if (lastEntity) { |
| | | const lastData = lastEntity.customInfo; |
| | | const originalFillColor = |
| | |
| | | : Cesium.Color.YELLOW.withAlpha(0.5); |
| | | const originalOutlineColor = |
| | | lastData.is_exception == 2 ? Cesium.Color.RED : Cesium.Color.YELLOW; |
| | | |
| | | lastEntity.polygon.material = originalFillColor; |
| | | lastEntity.polygon.outlineColor = originalOutlineColor; |
| | | lastEntity.polyline.material = originalOutlineColor; |
| | |
| | | lastEntity = nowEntity; |
| | | const numbersWithCommas = nowData.dkfw.match(/\d+(\.\d+)?/g); |
| | | if (numbersWithCommas) { |
| | | // 解析经纬度数组 |
| | | 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); |
| | | // 相机定位 |
| | | homeViewer.value.scene.camera.setView({ |
| | | destination: Cesium.Cartesian3.fromDegrees( |
| | | Number(polygonCenter.lng), |
| | | Number(polygonCenter.lat), |
| | | 1500 |
| | | ), |
| | | zIndex: 100, |
| | | |
| | | const positionsData = []; |
| | | for (let i = 0; i < numbersWithCommas.length; i += 2) { |
| | | const lon = Number(numbersWithCommas[i]); |
| | | const lat = Number(numbersWithCommas[i + 1]); |
| | | positionsData.push([lon, lat, 10]); |
| | | } |
| | | flyVisual({ |
| | | positionsData: positionsData, |
| | | viewer: homeViewer.value, |
| | | multiple: 15, |
| | | |
| | | }); |
| | | } |
| | | // flyMapSpot(nowEntity?.customInfo) |
| | | } |
| | | // 清空选中的数据 |
| | | const clearSelect = () => { |
| | |
| | | viewer?.entities.removeAll(); |
| | | }; |
| | | // 编辑 |
| | | |
| | | const handleSelectionChange = row => { |
| | | let curRowIsSelect = row; |
| | | curRowIsSelect && handleLocationPolygon(row); |
| | | // 如果是同一个图斑且正在编辑,则取消编辑 |
| | | if (selectionIds.value === row.id && isEditing.value) { |
| | | isEditing.value = false; |
| | | handleUpDateDrawState(false); |
| | | selectionIds.value = null; |
| | | selectionList.value = []; |
| | | return; |
| | | } |
| | | |
| | | // 定位到选中的图斑 |
| | | handleLocationPolygon(row); |
| | | |
| | | // 仅异常图斑可编辑 |
| | | if (row.is_exception !== 2) { |
| | | ElMessage.warning('仅异常图斑支持编辑绘制'); |
| | | return; |
| | | } |
| | | |
| | | // 设置编辑状态 |
| | | selectionIds.value = row.id; |
| | | selectionList.value = row; |
| | | |
| | | if (isEditing.value) { |
| | | //当前已编辑 → 取消编辑(关闭绘制、重置状态) |
| | | isEditing.value = false; |
| | | handleUpDateDrawState(false); // 通知DrawPolygon取消绘制 |
| | | } else { |
| | | // 当前未编辑 → 开启编辑(仅异常图斑可编辑) |
| | | if (row.is_exception === 2 && curRowIsSelect) { |
| | | isEditing.value = true; |
| | | handleUpDateDrawState(true); // 通知DrawPolygon开启绘制 |
| | | } else { |
| | | ElMessage.warning('仅异常图斑支持编辑绘制'); |
| | | isEditing.value = false; |
| | | } |
| | | } |
| | | isEditing.value = true; |
| | | handleUpDateDrawState(true); |
| | | }; |
| | | const handleUpDateDrawState = show => { |
| | | isEditing.value = show; // 同步编辑状态 |
| | |
| | | } |
| | | }; |
| | | // 删除 |
| | | const handleDelete = row => { |
| | | const handleDelete = (row) => { |
| | | ElMessageBox.confirm('确认删除当前行图斑?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | |
| | | deletePatches({ ids: row.id }).then(res => { |
| | | if (res.data.code !== 0) return ElMessage.warning('删除失败'); |
| | | ElMessage.success('删除成功'); |
| | | getTableList(); |
| | | getspotManagementTableApi(); |
| | | getAlltableMapListApi(); |
| | | tableData.value = tableData.value.filter(item => item.id !== row.id); |
| | | //从地图上移除对应的图斑实体 |
| | | const entityId = `polygon_dk${row.id}`; |
| | | viewer?.entities.removeById(entityId); |
| | | const exceptionCountItem = infoList.value.find(item => item.name === '异常图斑数量'); |
| | | if (exceptionCountItem && row.is_exception === 2) { |
| | | exceptionCountItem.value = Math.max(0, parseInt(exceptionCountItem.value) - 1); |
| | | } |
| | | const totalCountItem = infoList.value.find(item => item.name === '图斑数量'); |
| | | if (totalCountItem) { |
| | | totalCountItem.value = Math.max(0, parseInt(totalCountItem.value) - 1); |
| | | } |
| | | |
| | | // 清除选中状态 |
| | | if (selectionIds.value === row.id) { |
| | | selectionIds.value = null; |
| | | selectionList.value = []; |
| | | isEditing.value = false; |
| | | handleUpDateDrawState(false); |
| | | } |
| | | |
| | | }); |
| | | }); |
| | | }; |
| | |
| | | publicCesiumInstance = null; |
| | | }; |
| | | |
| | | |
| | | watch(uploadPatchDialog, newVal => { |
| | | if (newVal) { |
| | | |
| | | isInit.value = true; |
| | | setTimeout(() => { |
| | | initMap(); |
| | | getTableList(); |
| | | getAlltableMapListApi(); |
| | | initMap(); |
| | | getTableList(); |
| | | getspotManagementTableApi(); |
| | | }, 0); |
| | | } else { |
| | | tableData.value = []; |
| | | isEditing.value = false; |
| | | handleUpDateDrawState(false); |
| | | destroyMap(); |
| | | isInit.value = false; |
| | | clearSelect(); |
| | | } |
| | | refreshonload(); |
| | | }); |
| | |
| | | font-size: 16px !important; |
| | | color: #363636 !important; |
| | | } |
| | | :global(.spotDialog .el-dialog__body) { |
| | | padding: 2rem 2rem 0 !important; |
| | | |
| | | } |
| | | .container { |
| | | display: flex; |
| | | flex-direction: column; |
| | |
| | | // 表格主体 |
| | | .el-table__body { |
| | | tr:hover > td { |
| | | background-color: rgba(0, 0, 0, 0.6) !important; |
| | | background-color: rgba(64, 158, 255,0.3) !important; |
| | | } |
| | | |
| | | td { |
| | |
| | | |
| | | // 选中行 |
| | | .current-row td { |
| | | background-color: rgba(0, 0, 0, 0.6) !important; |
| | | |
| | | background-color: rgba(64, 158, 255,0.3) !important; |
| | | } |
| | | } |
| | | :deep(.el-table__body) { |