<template>
<div class="dialog-draggable">
<el-dialog draggable destroy-on-close v-if="changeRangeVisibility" :modal="false" v-model="changeRangeVisibility"
title="可视域分析" width="24%" :before-close="handleClose" @opened="getOpen()" :close-on-click-modal="false">
<div class="el-h-line">
<el-row :gutter="10">
<el-col :span="5">
<p class="font-big">方向(度)</p>
</el-col>
<el-col :span="19">
<div class="slider-demo-block">
<el-slider v-model="viewedModel.direction" show-input :step="1" :min=0 :max=360 @change="directionChange"/>
</div>
</el-col>
</el-row>
</div>
<div class="el-h-line">
<el-row :gutter="10">
<el-col :span="5">
<p class="font-big">翻转(度)</p>
</el-col>
<el-col :span="19">
<div class="slider-demo-block">
<el-slider v-model="viewedModel.pitch" show-input :min=-90 :max=90 @change="pitchChange"/>
</div>
</el-col>
</el-row>
</div>
<div class="el-h-line">
<el-row :gutter="10">
<el-col :span="5">
<p class="font-big">距离(米)</p>
</el-col>
<el-col :span="19">
<div class="slider-demo-block">
<el-slider v-model="viewedModel.distance" show-input :min=1 :max=500 @change="distanceChange" />
</div>
</el-col>
</el-row>
</div>
<div class="el-h-line">
<el-row :gutter="10">
<el-col :span="5">
<p class="font-big">水平视场角</p>
</el-col>
<el-col :span="19">
<div class="slider-demo-block">
<el-slider v-model="viewedModel.horizontalFov" show-input :min=1 :max=120 @change='horizontalFovChange' />
</div>
</el-col>
</el-row>
</div>
<div class="el-h-line">
<el-row :gutter="10">
<el-col :span="5">
<p class="font-big">垂直视场角</p>
</el-col>
<el-col :span="19">
<div class="slider-demo-block">
<el-slider v-model="viewedModel.verticalFov" show-input :min=1 :max=90 @change='verticalFovChange' />
</div>
</el-col>
</el-row>
</div>
<div class="el-h-line">
<el-row :gutter="10">
<el-col :span="5">
<p class="font-big">可见颜色</p>
</el-col>
<el-col :span="19">
<div class="slider-demo-block">
<el-color-picker v-model="viewedModel.visibleAreaColor" />
</div>
</el-col>
</el-row>
</div>
<div class="el-h-line">
<el-row :gutter="10">
<el-col :span="5">
<p class="font-big">不可见颜色</p>
</el-col>
<el-col :span="19">
<div class="slider-demo-block">
<div class="el-demo">
<el-color-picker v-model="viewedModel.invisibleAreaColor" />
</div>
</div>
</el-col>
</el-row>
</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="drawViewshed">绘制分析</el-button>
<el-button type="primary" @click="clearViewshed" style="background-color: #1d888b;">
清除
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, unref, toRaw } from 'vue'
import { ElMessage } from 'element-plus'
import emitter from "../../../utils/bus";
const changeRangeVisibility = ref<Boolean>(true)
interface viewedModelValue {
direction: number
pitch: number
distance: number
horizontalFov: number
verticalFov:number
visibleAreaColor:string
invisibleAreaColor:string
}
const viewedModel = ref<viewedModelValue>({
direction: 0,
pitch: -90,
distance: 1,
horizontalFov: 120,
verticalFov: 90,
visibleAreaColor: '#009eff',
invisibleAreaColor: '#ffb200'
})
const viewPosition = ref()
const viewPointHandler = ref()
const viewshed3D = ref()
const viewEventHandler = ref()
const Cesium = window.Cesium
const handleClose = (done: () => void) => {
done()
clearViewshed()
}
emitter.on("rangeState", (data: any) => {
changeRangeVisibility.value = data
});
const drawViewshed = (): void => {
if (!window.scene.pickPositionSupported) {
ElMessage({
showClose: true,
message: '不支持深度纹理,可视域分析功能无法使用(无法添加观测)!',
type: 'error',
})
return
}
window.scene.viewFlag = true
if (!viewPointHandler.value) {
viewPointHandler.value = new Cesium.DrawHandler(
window.viewer,
Cesium.DrawMode.Point
)
}
if (!viewshed3D.value) {
viewshed3D.value = new Cesium.ViewShed3D(window.scene)
}
Cesium.knockout.track(toRaw(unref(viewedModel)))
Cesium.knockout
.getObservable(toRaw(unref(viewedModel)), 'direction')
.subscribe((newValue: string) => {
viewshed3D.value.direction = parseFloat(newValue)
})
Cesium.knockout
.getObservable(toRaw(unref(viewedModel)), 'pitch')
.subscribe((newValue: string) => {
viewshed3D.value.pitch = parseFloat(newValue)
})
Cesium.knockout
.getObservable(toRaw(unref(viewedModel)), 'distance')
.subscribe((newValue: string) => {
viewshed3D.value.distance = parseFloat(newValue)
})
Cesium.knockout
.getObservable(toRaw(unref(viewedModel)), 'verticalFov')
.subscribe((newValue: string) => {
viewshed3D.value.verticalFov = parseFloat(newValue)
})
Cesium.knockout
.getObservable(toRaw(unref(viewedModel)), 'horizontalFov')
.subscribe((newValue: string) => {
viewshed3D.value.horizontalFov = parseFloat(newValue)
})
Cesium.knockout
.getObservable(toRaw(unref(viewedModel)), 'visibleAreaColor')
.subscribe((newValue: string) => {
var color = Cesium.Color.fromCssColorString(newValue)
viewshed3D.value.visibleAreaColor = color
})
Cesium.knockout
.getObservable(toRaw(unref(viewedModel)), 'invisibleAreaColor')
.subscribe((newValue: string) => {
var color = Cesium.Color.fromCssColorString(newValue)
viewshed3D.value.hiddenAreaColor = color
})
if (!viewEventHandler.value) {
viewEventHandler.value = new Cesium.ScreenSpaceEventHandler(
window.scene.canvas
)
}
viewEventHandler.value.setInputAction((e: object) => {
if (!window.scene.viewFlag) {
var position = e.endPosition
var last = window.scene.pickPosition(position)
var distance = Cesium.Cartesian3.distance(viewPosition.value, last)
if (distance > 0) {
var cartographic = Cesium.Cartographic.fromCartesian(last)
var longitude = Cesium.Math.toDegrees(cartographic.longitude)
var latitude = Cesium.Math.toDegrees(cartographic.latitude)
var height = cartographic.height
viewshed3D.value.setDistDirByPoint([longitude, latitude, height])
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
viewEventHandler.value.setInputAction((e: any) => {
window.scene.viewFlag = true
viewedModel.value.direction = viewshed3D.value.direction
viewedModel.value.pitch = viewshed3D.value.pitch
viewedModel.value.distance = viewshed3D.value.distance
viewedModel.value.horizontalFov = viewshed3D.value.horizontalFov
viewedModel.value.verticalFov = viewshed3D.value.verticalFov
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
viewPointHandler.value.drawEvt.addEventListener((result: any) => {
var point = result.object
var position = point.position
viewPosition.value = position
var cartographic = Cesium.Cartographic.fromCartesian(position)
var longitude = Cesium.Math.toDegrees(cartographic.longitude)
var latitude = Cesium.Math.toDegrees(cartographic.latitude)
var height = cartographic.height
point.position = Cesium.Cartesian3.fromDegrees(
longitude,
latitude,
height
)
if (window.scene.viewFlag) {
viewshed3D.value.viewPosition = [longitude, latitude, height]
viewshed3D.value.hiddenAreaColor = Cesium.Color.fromCssColorString(viewedModel.value.invisibleAreaColor)
viewshed3D.value.visibleAreaColor = Cesium.Color.fromCssColorString(viewedModel.value.visibleAreaColor)
viewshed3D.value.build()
window.scene.viewFlag = false
}
})
if (viewPointHandler.value.active) {
return
}
window.viewer.entities.removeAll()
viewshed3D.value.distance = 1
window.scene.viewFlag = true
viewPointHandler.value.activate()
}
const clearViewshed = (): void => {
window.viewer.entities.removeAll()
if (viewshed3D.value) {
viewshed3D.value.distance = 0.1
}
window.scene.viewFlag = true
if (viewPointHandler.value) {
viewPointHandler.value.clear()
}
viewedModel.value.direction = 0
viewedModel.value.pitch = -90
viewedModel.value.distance = 1
viewedModel.value.horizontalFov = 120
viewedModel.value.verticalFov = 90
viewedModel.value.visibleAreaColor = '#009eff',
viewedModel.value.invisibleAreaColor = '#ffb200'
}
onMounted(() => {
onDialog()
});
const getOpen = () => {
onDialog()
}
const directionChange = (val:number) =>{
viewedModel.value.direction = val
}
const pitchChange = (val:number) =>{
viewedModel.value.pitch = val
}
const distanceChange = (val:number)=>{
viewedModel.value.distance = val
}
const horizontalFovChange = (val:number)=>{
viewedModel.value.horizontalFov = val
}
const verticalFovChange = (val:number) =>{
viewedModel.value.verticalFov =val
}
onBeforeUnmount(() => {
clearViewshed()
viewPosition.value = undefined
viewPointHandler.value = undefined
viewshed3D.value = undefined
viewEventHandler.value = undefined
})
const onDialog = () => {
var box = document.querySelector(".el-overlay-dialog");
var boxa = box.parentNode;
boxa.style.pointerEvents = "none";
}
</script>