forked from drone/command-center-dashboard

罗广辉
2025-04-07 29d29e11c4d85922f6615de7676fabbaeb19f450
feat: 历史任务详情
2 files modified
120 ■■■■■ changed files
src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetails.vue 2 ●●● patch | view | raw | blame | history
src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue 118 ●●●●● patch | view | raw | blame | history
src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetails.vue
@@ -33,7 +33,7 @@
                    />
                </div>
            </div>
            <DeviceJobDetailsMap class="contentRight" :detailsData="detailsData"/>
            <DeviceJobDetailsMap v-if="isShow" class="contentRight" :detailsData="detailsData"/>
        </div>
    </el-dialog>
</template>
src/views/SignMachineNest/MachineRight/MachineTableDetails/DeviceJob/DeviceJobDetails/DeviceJobDetailsMap.vue
@@ -2,14 +2,16 @@
    <div id="deviceJobDetailsMap" />
</template>
<script setup>
import { Cartesian3, Terrain, Viewer } from 'cesium'
import * as Cesium from 'cesium'
import { Cartesian3, Math as CesiumMath, Terrain, Viewer } from 'cesium'
import AmapMercatorTilingScheme from '@/utils/cesium/AmapMercatorTilingScheme'
import { analyzeKmzFile, removeTextKey, XMLToJSON } from '@/utils/cesium/kmz'
import ImageTrailMaterial from '@/utils/cesium/ImageTrailMaterial'
import lineImg from '@/assets/images/arrow-right-blue.png'
import uavImg from '@/assets/images/home/useUavHome/uavImg.png'
import { getCenterPoint } from '@/utils/cesium/mapUtil'
const props = defineProps(['detailsData'])
const imageryProvider_ammapSL = new Cesium.UrlTemplateImageryProvider({
    url: 'https://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
@@ -23,7 +25,7 @@
    credit: 'amap_SL',
})
let viewer = null
const init = () => {
const initMap = () => {
    viewer = new Viewer('deviceJobDetailsMap', {
        terrain: Terrain.fromWorldTerrain(),
        infoBox: false, // 禁用沙箱,解决控制台报错
@@ -40,56 +42,98 @@
    })
    viewer.imageryLayers.addImageryProvider(imageryProvider_ammapSL)
    viewer.scene.morphTo2D(0)
    //设置默认点
    viewer.camera.setView({
        destination: Cartesian3.fromDegrees(115.763819, 28.787374),
    })
}
import  imgtst from '@/assets/images/arrow-right-blue.png'
const renderingLine = (lineObj) =>{
    console.log(lineObj)
// 渲染线和点
const renderingLine = lineObj => {
    const positions = lineObj.Placemark.map(item => {
        const [lon,lat] = item.Point.coordinates.split(',')
        return Cartesian3.fromDegrees(Number(lon), Number(lat) )
        const [lon, lat] = item.Point.coordinates.split(',')
        return Cartesian3.fromDegrees(Number(lon), Number(lat))
    })
    viewer.entities.add({
        name: 'ls_wayline',
        id: 'ls_wayline',
        position: positions[0],
        billboard: {
            image: new Cesium.ConstantProperty(uavImg),
            width: 24,
            height: 24,
        },
    })
    viewer.entities.add({
        polyline: {
            width: 4,
            positions: positions,
            material: new ImageTrailMaterial({
                color: {
                    alpha: 1,
                    blue: 1,
                    green: 1,
                    red: 1
                },
                color: { alpha: 1, blue: 1, green: 1, red: 1 },
                speed: 20,
                image: imgtst,
                repeat: { x: Math.floor(40), y: 1 }
                image: lineImg,
                repeat: { x: Math.floor(40), y: 1 },
            }),
            clampToGround: false
            clampToGround: false,
        },
    })
}
// 飞到中心点
function flyToPoints(lngLatArr) {
    if (!Array.isArray(lngLatArr) || lngLatArr.length === 0) return
    const positions = lngLatArr.map(([lon, lat]) =>
        Cesium.Cartesian3.fromDegrees(Number(lon), Number(lat))
    )
    // 计算包围盒 BoundingSphere(所有点的外接球)
    const boundingSphere = Cesium.BoundingSphere.fromPoints(positions)
    viewer.camera.flyToBoundingSphere(boundingSphere, {
        duration: 0,
        offset: new Cesium.HeadingPitchRange(0, 0, boundingSphere.radius * 2),
    })
}
// 异步解析kmz文件
const analysis = async url => {
    return new Promise(async resolve => {
        const res = await analyzeKmzFile(`${url}?_t=${new Date().getTime()}`)
        const templateXML = await res.fileInfoObj['wpmz/template.kml']
        const templateXMLJSON = XMLToJSON(templateXML)?.['Document']
        const templateXMLObj = removeTextKey(templateXMLJSON.Folder)
        resolve(templateXMLObj)
    })
}
// 绘制线和飞行
const drawLine = async () => {
    const res = await Promise.all(props.detailsData.way_lines.map(item => analysis(item.url)))
    res.map(item => renderingLine(item))
    const allPoint = res
        .flatMap(item => item.Placemark)
        .map(item => item.Point.coordinates.split(','))
    flyToPoints(allPoint)
}
const removeMap = () => {
    console.log('yichu')
    viewer.entities.removeAll()
    viewer.destroy()
}
watch(
    () => props.detailsData,
    (newValue, oldValue) => {
        if (newValue) {
            drawLine()
        }
    })
}
const drawLine = () => {
    props.detailsData.way_lines.forEach(item => {
        analyzeKmzFile(`${item.url}?_t=${new Date().getTime()}`).then(async res => {
            const templateXML = await res.fileInfoObj['wpmz/template.kml']
            const templateXMLJSON = XMLToJSON(templateXML)?.['Document']
            const templateXMLObj = removeTextKey(templateXMLJSON.Folder)
            renderingLine(templateXMLObj)
        })
    })
}
watch(() => props.detailsData, (newValue, oldValue) => {
    if(newValue){
        drawLine()
    }
)
onBeforeUnmount(() => {
    removeMap()
})
onMounted(() => {
    nextTick(() => {
        init()
        initMap()
    })
})
</script>