吉安感知网项目-前端
shuishen
2026-01-28 046a69a1a3b50079eae3663cd631bd062748ec4f
feat:多边形绘制相关处理
9 files modified
149 ■■■■■ changed files
applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue 101 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawBufferCircleTool.js 7 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js 7 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawPolygonTool.js 8 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawRectangleTool.js 8 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditBufferCircleTool.js 5 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditEllipseTool.js 5 ●●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditPolygonTool.js 4 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditRectangleTool.js 4 ●●●● patch | view | raw | blame | history
applications/drone-command/src/views/areaManage/partition/FormDiaLog.vue
@@ -18,7 +18,7 @@
                >
                    <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>
@@ -27,7 +27,6 @@
                            popper-class="command-select-popper"
                            v-model="formData.areaType"
                            placeholder="请选择"
                            clearable
                            @change="handleAreaTypeChange"
                        >
                            <el-option
@@ -301,12 +300,15 @@
    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),
@@ -399,6 +401,7 @@
            viewEntity = null
            clearActiveTool()
            hideTypePanel()
            clearShapeDisplay()
        }
    }
)
@@ -436,10 +439,72 @@
    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
@@ -459,7 +524,10 @@
            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)}`
@@ -476,6 +544,7 @@
    } else {
        shapeList.value.splice(targetIndex, 1, shapePayload)
    }
    renderShapeList()
}
function applyPolygonMetrics(points) {
@@ -508,6 +577,18 @@
    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)
}
@@ -529,10 +610,13 @@
    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)
@@ -540,6 +624,7 @@
function startEdit (type, points) {
    currentShapeType.value = type
    activeToolMode.value = 'edit'
    editManager ||= new EditManager(viewer)
    activeTool = editManager.start(type, points)
    activeTool?.subscribe('getPolygonPositions', drawFinished)
@@ -552,6 +637,7 @@
    viewEntity && viewer?.entities?.remove(viewEntity)
    viewEntity = null
    hideTypePanel()
    renderShapeList()
    if (dialogMode.value === 'edit' && pointList.length >= 3) {
        const editPoints = _.cloneDeep(pointList)
        if (editPoints.length > 1) {
@@ -581,10 +667,12 @@
    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)
@@ -592,11 +680,13 @@
    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()
@@ -673,6 +763,7 @@
    activeShapeId.value = null
    await nextTick()
    initMap()
    clearShapeDisplay()
    viewEntity && viewer?.entities?.remove(viewEntity)
    viewEntity = null
    clearActiveTool()
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawBufferCircleTool.js
@@ -41,6 +41,7 @@
            const positions = buildEllipsePositions(this.centerCartesian, this.radius, this.radius)
            this.notify('getPolygonPositions', positions)
            this.tooltip.hide()
            this.clearPreviewEntities()
        }
    }
@@ -71,6 +72,12 @@
        })
    }
    clearPreviewEntities() {
        if (!this.dataSource) return
        this.dataSource.entities.removeAll()
        this.circleEntity = null
    }
    getSurfaceDistance(startCartesian, endCartesian) {
        const start = Cesium.Cartographic.fromCartesian(startCartesian)
        const end = Cesium.Cartographic.fromCartesian(endCartesian)
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawEllipseTool.js
@@ -51,6 +51,7 @@
            const positions = buildEllipsePositions(this.centerCartesian, this.semiMajor, this.semiMinor)
            this.notify('getPolygonPositions', positions)
            this.tooltip.hide()
            this.clearPreviewEntities()
        }
    }
@@ -99,6 +100,12 @@
        })
    }
    clearPreviewEntities() {
        if (!this.dataSource) return
        this.dataSource.entities.removeAll()
        this.ellipseEntity = null
    }
    getPositionFromScreen(screenPosition) {
        const scene = this.viewer.scene
        const cartesian = scene.pickPosition(screenPosition)
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawPolygonTool.js
@@ -176,6 +176,14 @@
        this.floatPosition = null
        this.notify('getPolygonPositions', this.positions)
        this.tooltip.hide()
        this.clearPreviewEntities()
    }
    clearPreviewEntities() {
        if (!this.dataSource) return
        this.dataSource.entities.removeAll()
        this.polygonEntity = null
        this.polylineEntity = null
    }
    getPositionFromScreen(screenPosition) {
applications/drone-command/src/views/areaManage/partition/shapeTools/draw/DrawRectangleTool.js
@@ -45,6 +45,7 @@
            const positions = this.getRectanglePositions()
            this.notify('getPolygonPositions', positions)
            this.tooltip.hide()
            this.clearPreviewEntities()
        }
    }
@@ -94,6 +95,13 @@
        return rectanglePositionsFromBounds(bounds)
    }
    clearPreviewEntities() {
        if (!this.dataSource) return
        this.dataSource.entities.removeAll()
        this.rectangleEntity = null
        this.outlineEntity = null
    }
    getPositionFromScreen(screenPosition) {
        const scene = this.viewer.scene
        const cartesian = scene.pickPosition(screenPosition)
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditBufferCircleTool.js
@@ -130,6 +130,11 @@
        this.radiusEntity.position = this.getRadiusPoint()
    }
    getPositions() {
        if (!this.centerCartesian) return []
        return buildEllipsePositions(this.centerCartesian, this.radius, this.radius)
    }
    getRadiusPoint() {
        const frame = Cesium.Transforms.eastNorthUpToFixedFrame(this.centerCartesian)
        const local = new Cesium.Cartesian3(this.radius, 0, 0)
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditEllipseTool.js
@@ -154,6 +154,11 @@
        this.minorEntity.position = this.getAxisPoint(0, this.semiMinor)
    }
    getPositions() {
        if (!this.centerCartesian) return []
        return buildEllipsePositions(this.centerCartesian, this.semiMajor, this.semiMinor)
    }
    getAxisPoint(eastMeters, northMeters) {
        const frame = Cesium.Transforms.eastNorthUpToFixedFrame(this.centerCartesian)
        const local = new Cesium.Cartesian3(eastMeters, northMeters, 0)
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditPolygonTool.js
@@ -142,6 +142,10 @@
        })
    }
    getPositions() {
        return this.positions.slice()
    }
    getPositionFromScreen(screenPosition) {
        const scene = this.viewer.scene
        const cartesian = scene.pickPosition(screenPosition)
applications/drone-command/src/views/areaManage/partition/shapeTools/edit/EditRectangleTool.js
@@ -124,6 +124,10 @@
        })
    }
    getPositions() {
        return rectanglePositionsFromBounds(this.bounds)
    }
    getCornerCartographics() {
        return rectanglePositionsFromBounds(this.bounds).map(position =>
            Cesium.Cartographic.fromCartesian(position)