| | |
| | | > |
| | | <div class="panel-header"> |
| | | <span>{{ drawTypeLabelMap[currentShapeType] || '区域' }}</span> |
| | | <el-icon class="panel-close" @click.stop="showTypePanel = false"><Close /></el-icon> |
| | | <el-icon class="panel-close" @click.stop="handleTypePanelClose"><Close /></el-icon> |
| | | </div> |
| | | <div class="panel-body"> |
| | | <span class="panel-label">区域类型</span> |
| | |
| | | popper-class="command-select-popper" |
| | | v-model="formData.areaType" |
| | | placeholder="请选择" |
| | | clearable |
| | | @change="handleAreaTypeChange" |
| | | > |
| | | <el-option |
| | |
| | | buffer: '缓冲圆', |
| | | } |
| | | const showTypePanel = ref(false) |
| | | const suppressTypePanelOnce = ref(false) |
| | | let viewer |
| | | let drawManager |
| | | let editManager |
| | | let activeTool |
| | | let pointList = [] |
| | | let viewEntity |
| | | let shapeDisplaySource |
| | | const activeToolMode = ref('') |
| | | |
| | | const rules = { |
| | | areaName: fieldRules(true, 50), |
| | |
| | | viewEntity = null |
| | | clearActiveTool() |
| | | hideTypePanel() |
| | | clearShapeDisplay() |
| | | } |
| | | } |
| | | ) |
| | |
| | | viewer = map?.viewer || null |
| | | } |
| | | |
| | | function ensureShapeDisplaySource () { |
| | | if (!viewer) return null |
| | | if (!shapeDisplaySource) { |
| | | shapeDisplaySource = new Cesium.CustomDataSource('partition-shape-display') |
| | | viewer.dataSources.add(shapeDisplaySource) |
| | | } |
| | | return shapeDisplaySource |
| | | } |
| | | |
| | | function clearShapeDisplay () { |
| | | if (!shapeDisplaySource) return |
| | | shapeDisplaySource.entities.removeAll() |
| | | } |
| | | |
| | | function normalizeShapePoint (point) { |
| | | const lng = point?.lng ?? point?.longitude |
| | | const lat = point?.lat ?? point?.latitude |
| | | if (!Number.isFinite(Number(lng)) || !Number.isFinite(Number(lat))) return null |
| | | return { |
| | | lng: Number(lng), |
| | | lat: Number(lat), |
| | | height: Number.isFinite(Number(point?.height)) ? Number(point.height) : 0, |
| | | } |
| | | } |
| | | |
| | | function buildShapePositions (points = []) { |
| | | const normalized = points.map(normalizeShapePoint).filter(Boolean) |
| | | return normalized.map(point => |
| | | Cesium.Cartesian3.fromDegrees(point.lng, point.lat, point.height) |
| | | ) |
| | | } |
| | | |
| | | function renderShapeList () { |
| | | if (!viewer || !visible.value || readonly.value) { |
| | | clearShapeDisplay() |
| | | return |
| | | } |
| | | const dataSource = ensureShapeDisplaySource() |
| | | if (!dataSource) return |
| | | dataSource.entities.removeAll() |
| | | shapeList.value.forEach(shape => { |
| | | if (!shape?.points?.length) return |
| | | if (activeToolMode.value === 'edit' && shape.id === activeShapeId.value) return |
| | | const positions = buildShapePositions(shape.points) |
| | | if (positions.length < 3) return |
| | | dataSource.entities.add({ |
| | | name: 'shape-display', |
| | | customData: { shapeId: shape.id, drawType: shape.drawType }, |
| | | polygon: { |
| | | hierarchy: new Cesium.PolygonHierarchy(positions), |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 99), |
| | | outline: false, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | | polyline: { |
| | | positions: positions.length ? [...positions, positions[0]] : positions, |
| | | clampToGround: true, |
| | | width: 2, |
| | | material: Cesium.Color.fromBytes(45, 140, 240, 255), |
| | | }, |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | // 绘制完成回调 |
| | | const drawFinished = async data => { |
| | | console.log(1) |
| | | |
| | | if (!Array.isArray(data) || data.length < 3) { |
| | | pointList = [] |
| | | formData.value.areaSize = null |
| | |
| | | formData.value.areaType = alarmAreaType |
| | | } |
| | | } |
| | | showTypePanelAtCurrent() |
| | | if (!suppressTypePanelOnce.value) { |
| | | showTypePanelAtCurrent() |
| | | } |
| | | suppressTypePanelOnce.value = false |
| | | |
| | | if (!activeShapeId.value) { |
| | | activeShapeId.value = `shape_${Date.now()}_${Math.random().toString(16).slice(2, 6)}` |
| | |
| | | } else { |
| | | shapeList.value.splice(targetIndex, 1, shapePayload) |
| | | } |
| | | renderShapeList() |
| | | } |
| | | |
| | | function applyPolygonMetrics(points) { |
| | |
| | | showTypePanel.value = false |
| | | } |
| | | |
| | | function handleTypePanelClose () { |
| | | hideTypePanel() |
| | | if (readonly.value) return |
| | | if (activeToolMode.value !== 'edit') return |
| | | const positions = activeTool?.getPositions?.() |
| | | if (Array.isArray(positions) && positions.length >= 3) { |
| | | suppressTypePanelOnce.value = true |
| | | drawFinished(positions) |
| | | } |
| | | clearActiveTool() |
| | | } |
| | | |
| | | function handleAreaTypeChange (value) { |
| | | updateActiveShapeAreaType(value) |
| | | } |
| | |
| | | activeTool = null |
| | | drawManager?.destroy() |
| | | editManager?.destroy() |
| | | activeToolMode.value = '' |
| | | renderShapeList() |
| | | } |
| | | |
| | | function startDraw (type) { |
| | | currentShapeType.value = type |
| | | activeToolMode.value = 'draw' |
| | | drawManager ||= new DrawManager(viewer) |
| | | activeTool = drawManager.start(type) |
| | | activeTool?.subscribe('getPolygonPositions', drawFinished) |
| | |
| | | |
| | | function startEdit (type, points) { |
| | | currentShapeType.value = type |
| | | activeToolMode.value = 'edit' |
| | | editManager ||= new EditManager(viewer) |
| | | activeTool = editManager.start(type, points) |
| | | activeTool?.subscribe('getPolygonPositions', drawFinished) |
| | |
| | | viewEntity && viewer?.entities?.remove(viewEntity) |
| | | viewEntity = null |
| | | hideTypePanel() |
| | | renderShapeList() |
| | | if (dialogMode.value === 'edit' && pointList.length >= 3) { |
| | | const editPoints = _.cloneDeep(pointList) |
| | | if (editPoints.length > 1) { |
| | |
| | | formData.value.longitude = null |
| | | formData.value.latitude = null |
| | | hideTypePanel() |
| | | clearShapeDisplay() |
| | | } |
| | | |
| | | function handleShapeEdit (row) { |
| | | if (!row?.points?.length) return |
| | | if (activeToolMode.value === 'edit' && activeShapeId.value === row.id) return |
| | | activeShapeId.value = row.id |
| | | currentShapeType.value = row.drawType |
| | | pointList = _.cloneDeep(row.points) |
| | |
| | | startEdit(row.drawType, row.points) |
| | | applyPolygonMetrics(pointList) |
| | | showTypePanelAtCurrent() |
| | | renderShapeList() |
| | | } |
| | | |
| | | function handleShapeDelete (row) { |
| | | if (!row) return |
| | | shapeList.value = shapeList.value.filter(item => item.id !== row.id) |
| | | renderShapeList() |
| | | if (activeShapeId.value === row.id) { |
| | | activeShapeId.value = null |
| | | clearActiveTool() |
| | |
| | | activeShapeId.value = null |
| | | await nextTick() |
| | | initMap() |
| | | clearShapeDisplay() |
| | | viewEntity && viewer?.entities?.remove(viewEntity) |
| | | viewEntity = null |
| | | clearActiveTool() |