vue3+vite+superMap(超图)实现通视分析
<!--通视分析--><template><div><P>通视分析</P><el-dialog draggable destroy-on-close v-if="changeVisibilityState" :modal="false" v-model="changeVisibilityState"close-icon="" tit
·
<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>
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)