| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import * as turf from '@turf/turf' |
| | | import { dataFolderApi } from '@/api/layer/index'; |
| | | import folderFile from '@/views/layerManagement/components/folderFile.vue' |
| | | import { parseGeoDataToPositions } from '@/utils/geoParseUtil'; |
| | |
| | | import _, { cloneDeep, throttle } from 'lodash'; |
| | | import { ElButton } from 'element-plus'; |
| | | import { provide } from 'vue'; |
| | | import { useStore } from 'vuex'; |
| | | const store = useStore(); |
| | | const userInfo = computed(() => store.getters.userInfo); |
| | | const areaCode = userInfo.value?.detail?.areaCode || ''; |
| | | // console.log('用户信息',areaCode); |
| | | |
| | | const activeName = ref('电子围栏'); |
| | | const activeType = ref('0'); |
| | | let tbJwdList = []; |
| | |
| | | editFolder:false, |
| | | folderOption:[] ,//文件夹选项 |
| | | fenceType:1, |
| | | fenceArea:0,//围栏面积 |
| | | }); |
| | | |
| | | const handleClick = tab => { |
| | |
| | | }); |
| | | }); |
| | | focusOnAllFeatures(); |
| | | // 添加点击事件(参考 entitiesAddSpot 的 spotHighlighting 逻辑) |
| | | // 移除已有点击事件,避免重复绑定 |
| | | // viewInstance.value?.removeLeftClickEvent('fenceHighlighting'); |
| | | // 绑定新的点击事件,用于高亮选中的围栏 |
| | | // viewInstance.value?.addLeftClickEvent(null, handleFenceClick, 'fenceHighlighting'); |
| | | viewInstance.value?.addLeftClickEvent(null, handleFenceClick, ); |
| | | }; |
| | | //计算所有图斑的包围球并定位 |
| | | const focusOnAllFeatures = () => { |
| | |
| | | ), |
| | | }); |
| | | }; |
| | | // 围栏点击处理函数(高亮选中项 + 可联动右侧编辑组件) |
| | | // 围栏点击处理函数 |
| | | const handleFenceClick = movement => { |
| | | if (!viewer) return; |
| | | |
| | | // 拾取点击的实体 |
| | | const pickedObject = viewer.scene.pick(movement.position); |
| | | if (Cesium.defined(pickedObject) && pickedObject.id?.customType === 'fence_polygon') { |
| | | const selectedEntity = pickedObject.id; |
| | | console.log('选中的围栏数据:', selectedEntity.customInfo); |
| | | |
| | | // 1. 高亮处理(清除其他实体高亮,仅高亮当前选中) |
| | | viewer.entities.values.forEach(entity => { |
| | | if (entity.customType === 'fence_polygon') { |
| | | // 恢复默认样式 |
| | | entity.polygon.material = |
| | | entity === selectedEntity |
| | | ? selectedEntity.polygon.material.color.withAlpha(0.8) // 选中时加深透明度 |
| | | : selectedEntity.polygon.material.color.withAlpha(0.5); // 未选中恢复默认 |
| | | } |
| | | }); |
| | | // // 1. 高亮处理(清除其他实体高亮,仅高亮当前选中) |
| | | // viewer.entities.values.forEach(entity => { |
| | | // if (entity.customType === 'fence_polygon') { |
| | | // // 恢复默认样式 |
| | | // entity.polygon.material = |
| | | // entity === selectedEntity |
| | | // ? selectedEntity.polygon.material.color.withAlpha(0.8) // 选中时加深透明度 |
| | | // : selectedEntity.polygon.material.color.withAlpha(0.5); // 未选中恢复默认 |
| | | // } |
| | | // }); |
| | | |
| | | // 2. 联动右侧编辑组件(假设 rightEdit 有接收数据的方法) |
| | | // 例如:通过 ref 调用 rightEdit 的 setData 方法 |
| | |
| | | const drawPolygonExample = new DrawPolygon(); |
| | | |
| | | // 地图初始化 |
| | | // 地图初始化 |
| | | const initMap = () => { |
| | | publicCesiumInstance = new PublicCesium({ |
| | | dom: 'layMap', |
| | |
| | | |
| | | viewer = publicCesiumInstance.getViewer(); |
| | | viewInstance.value = publicCesiumInstance; |
| | | |
| | | const nanChangPosition = Cesium.Cartesian3.fromDegrees( |
| | | 115.892151, // 经度 |
| | | 28.676493, // 纬度 |
| | | 15000 // 相机高度 |
| | | ); |
| | | |
| | | // 执行相机飞行 |
| | | viewer.camera.flyTo({ |
| | | destination: nanChangPosition, |
| | | duration: 0, |
| | | orientation: { |
| | | heading: Cesium.Math.toRadians(0), |
| | | pitch: Cesium.Math.toRadians(-90), |
| | | roll: 0 |
| | | } |
| | | }); |
| | | |
| | | }; |
| | | |
| | |
| | | |
| | | |
| | | 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) { |
| | | // 确保多边形闭合:最后一个点与第一个点一致(避免计算偏差) |
| | | const firstPoint = polygon[0]; |
| | | const lastPoint = polygon[polygon.length - 1]; |
| | | const isClosed = ( |
| | | _.round(firstPoint[0], 6) === _.round(lastPoint[0], 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.value.fenceArea = area; |
| | | console.log('计算的多边形面积(平方米):', layerParams.value.fenceArea); |
| | | } else { |
| | | // 坐标点不足3个时,清空面积 |
| | | layerParams.value.fenceArea = 0; |
| | | } |
| | | }; |
| | | const throttleLoadPlanarRoute = throttle(loadPlanarRoute, 200); |
| | | drawPolygonExample.subscribe('getPolygonPositions', data => { |