<template>
    <div>
        <el-dialog draggable destroy-on-close v-if="changeVisibilityState" :modal="false" v-model="changeVisibilityState"
            close-icon="" title="通视分析" width="20%" :before-close="handleClose" @opened="getIntervisOpen()"
            :close-on-click-modal="false">
            <div class="el-h-line">
                <p class="p">观察者信息</p>
                <el-row :gutter="10">
                    <el-col :span="6">
                        <p class="font-big">经度</p>
                    </el-col>
                    <el-col :span="18">
                        <div class="slider-demo-block">
                            <el-input v-model="longitude" placeholder="显示经度" :disabled="true" />
                        </div>
                    </el-col>
                </el-row>
            </div>

            <div class="el-h-line">
                <el-row :gutter="10">
                    <el-col :span="6">
                        <p class="font-big">纬度</p>
                    </el-col>
                    <el-col :span="18">
                        <div class="slider-demo-block">
                            <el-input v-model="latitude" placeholder="显示纬度" :disabled="true" />
                        </div>
                    </el-col>
                </el-row>
            </div>

            <div class="el-h-line">
                <el-row :gutter="10">
                    <el-col :span="6">
                        <p class="font-big">高程</p>
                    </el-col>
                    <el-col :span="18">
                        <div class="slider-demo-block">
                            <el-input v-model="height" placeholder="显示高程" :disabled="true" />
                        </div>
                    </el-col>
                </el-row>
            </div>
            <!--可见颜色-->
            <div class="el-h-line">
                <el-row :gutter="10">
                    <el-col :span="6">
                        <p class="font-big">可见颜色</p>
                    </el-col>
                    <el-col :span="18">
                        <div class="slider-demo-block">
                            <el-color-picker v-model="visibleColor" @change="visibleColorChange" />
                        </div>
                    </el-col>
                </el-row>
            </div>
            <!--不可见颜色-->
            <div class="el-h-line">
                <el-row :gutter="10">
                    <el-col :span="6">
                        <p class="font-big">不可见颜色</p>
                    </el-col>
                    <el-col :span="18">
                        <div class="slider-demo-block">
                            <div class="el-demo">
                                <el-color-picker v-model="hiddenColor" @change="hiddenColorChange" />
                            </div>
                        </div>
                    </el-col>
                </el-row>
            </div>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="addObserverPoint">添加观察点</el-button>
                    <el-button @click="addTargetPoint">添加目标点</el-button>
                    <el-button type="primary" @click="clearVisibility" style="background-color: #1d888b;">清除</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from 'vue'
// 组件传值
import emitter from "../../../utils/bus";
const changeVisibilityState = ref<Boolean>(true)
const longitude = ref()
const latitude = ref()
const height = ref()
const visibleColor = ref('#0e9dec')
const hiddenColor = ref('#ffb200')
const sightlineWidth = ref<number>()
const sightline = ref(null)
// 当前点击状态是否是 添加观察点
const addViewFlag = ref(false)
// 当前点击状态是否是 添加目标点
const addTargetFlag = ref(false)
// 添加的目标点的点号
const num = ref(0)
// 是否能移除目标点
const couldRemove = ref(false)
const handlerPoint = ref(null)
const pointEventHandler = ref(null)
const Cesium = window.Cesium

const handleClose = (done: () => void) => {
    done()
    clearVisibility()
}
// 接受layoutMenu传过来的值
emitter.on("visibilityState", (data: any) => {
    changeVisibilityState.value = data
});

const init = () => {
    if (!sightline.value) {
        sightline.value = new Cesium.Sightline(window.viewer.scene)
    }
    sightline.value.build()
    addViewFlag.value = false // 当前点击状态是否是 添加观察点
    addTargetFlag.value = false // 当前点击状态是否是 添加目标点
    num.value = 0 // 添加的目标点的点号
    couldRemove.value = false // 是否能移除目标点
}

const addObserverPoint = (): void => {
    addViewFlag.value = true
    sightline.value.lineWidth = 5
    handlerPoint.value = new Cesium.DrawHandler(
        window.viewer,
        Cesium.DrawMode.Point
    )

    handlerPoint.value.drawEvt.addEventListener((result: object) => {
        // 添加观察点
        if (addViewFlag.value) {
            var point = result.object
            // point.show = false;
            var position = result.object.position

            // 将获取的点的位置转化成经纬度
            var cartographic = Cartesian2toDegrees(position)

            longitude.value = cartographic[0]
            latitude.value = cartographic[1]
            height.value = cartographic[2]
            // 设置观察点
            sightline.value.viewPosition = cartographic
            addViewFlag.value = false
        }
        handlerPoint.value.deactivate()
    })
    if (handlerPoint.value.active) {
        return
    }
    window.viewer.entities.removeAll()
    if (couldRemove.value) {
        sightline.value.removeAllTargetPoint()
    }

    if (longitude.value && latitude.value && height.value) {
        sightline.value.viewPosition = [parseFloat(longitude.value), parseFloat(latitude.value), parseFloat(height.value)]
        addViewFlag.value = false
    } else {
        handlerPoint.value.activate()
    }

    if (addViewFlag.value || addTargetFlag.value) {
        window.viewer.enableCursorStyle = false
        window.viewer._element.style.cursor = ''
    }
}

const addTargetPoint = (): void => {
   
    addViewFlag.value = false
    addTargetFlag.value = true
    sightline.value.visibleColor = Cesium.Color.fromCssColorString(visibleColor.value)
    sightline.value.hiddenColor = Cesium.Color.fromCssColorString(hiddenColor.value)
    if (!pointEventHandler.value) {
        pointEventHandler.value = new Cesium.ScreenSpaceEventHandler(
            window.viewer.scene.canvas
        )
    }
    if (addViewFlag.value || addTargetFlag.value) {
        window.viewer.enableCursorStyle = false
        window.viewer._element.style.cursor = ''
    }

    // 鼠标点击事件,添加点
    pointEventHandler.value.setInputAction((e: any) => {
        var position = window.viewer.scene.pickPosition(e.position)
        addTarget(position)
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)

    // 鼠标移动事件,更新点
    pointEventHandler.value.setInputAction((evt: any) => {
        if (num.value > 0) {
            // 鼠标移动,更新最后一次添加的目标点的位置
            var position = window.viewer.scene.pickPosition(evt.endPosition)
            sightline.value.removeTargetPoint('point0')

            var cartographic = Cartesian2toDegrees(position)

            var flag = sightline.value.addTargetPoint({
                position: cartographic,
                name: 'point0'
            })
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)

    // 鼠标右键事件,结束
    pointEventHandler.value.setInputAction(() => {
        window.viewer.enableCursorStyle = true

        if (pointEventHandler.value) {
            pointEventHandler.value.removeInputAction(
                Cesium.ScreenSpaceEventType.MOUSE_MOVE
            )
            pointEventHandler.value.removeInputAction(
                Cesium.ScreenSpaceEventType.LEFT_CLICK
            )
        }
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
}

// 添加通视点
const addTarget = (CartesianPosition: object) => {
    if (addViewFlag.value === false && addTargetFlag.value) {
        num.value += 1
        // 将获取的点的位置转化成经纬度
        var cartographic = Cartesian2toDegrees(CartesianPosition)
        // 添加目标点
        var name = 'point' + num.value
        var flag = sightline.value.addTargetPoint({
            position: cartographic,
            name: name
        })
        couldRemove.value = true
    }
}

// 笛卡尔转换为经纬度
const Cartesian2toDegrees = (position: object) => {
    var cartographic = Cesium.Cartographic.fromCartesian(position)
    var longitude = Cesium.Math.toDegrees(cartographic.longitude)
    var latitude = Cesium.Math.toDegrees(cartographic.latitude)
    var height = cartographic.height

    return [longitude, latitude, height]
}

const clearVisibility = (): void => {
    addViewFlag.value = false
    addTargetFlag.value = false
    if (handlerPoint.value) {
        handlerPoint.value.clear()
    }
    num.value = 0
    window.viewer.entities.removeAll()
    if (couldRemove.value) {
        sightline.value.removeAllTargetPoint()
        couldRemove.value = false
    }
    window.viewer.enableCursorStyle = true
    longitude.value = null
    latitude.value = null
    height.value = null
    visibleColor.value = '#0e9dec'
    hiddenColor.value = '#ffb200'
}
// 可视线实时的颜色的改变,
const hiddenColorChange = (val: Number) => {
    sightline.value.visibleColor = Cesium.Color.fromCssColorString(val)
}
const visibleColorChange = (val: Number) => {
    sightline.value.hiddenColor = Cesium.Color.fromCssColorString(val)
}
onMounted(() => {
    init()
    onDialog()
});

// 弹框打开之后的回调再次穿透页面
const getIntervisOpen = () => {
    onDialog()
}

onBeforeUnmount(() => {
    clearVisibility()
    handlerPoint.value = null
    pointEventHandler.value = null
})

// 解决弹框打开时可操作操作其他Dom的问题
const onDialog = () => {
    var box = document.querySelector(".el-overlay-dialog");
    // 获取.el-overlay-dialog父级
    var boxa = box.parentNode;
    //  使用pointerEvents 进行页面穿透
    boxa.style.pointerEvents = "none";
}
</script>
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐