本人小白一枚,文章如有问题还请各位大神评论区指出。整体实现是参考SuperMap iClient3D for Cesium的可视域分析功能源码~
文章目录
前言
一、主要功能
二、使用步骤
1.HTML主要结构
2.javascript
前言
SuperMap iClient3D for Cesium中的ViewShed3D类提供了可视域分析,设置观察点、目标的位置,水平、垂直视角范围,建立可视区域分析并在指定的场景中显示分析结果的功能。具体下方代码都有详细注释。
一、主要功能
效果图:
文章来源:https://www.toymoban.com/news/detail-557551.html
较官网示例去掉了环境设置及裁剪功能(个人感觉比较鸡肋),增加了拖动滑块动态修改可视域参数功能。文章来源地址https://www.toymoban.com/news/detail-557551.html
二、具体实现
1.HTML主要结构
<div id="content">
<p class="angletext">水平视角 (单位:度)</p>
<el-slider
id="horizontalFov"
show-input
size="small"
:min="10"
:max="179"
v-model="viewModel.horizontalFov"
/>
<p class="angletext">垂直视角 (单位:度)</p>
<el-slider
id="verticalFov"
show-input
size="small"
:min="10"
:max="90"
v-model="viewModel.verticalFov"
/>
<p class="angletext">俯仰角 (单位:度)</p>
<el-slider
id="pitch"
show-input
size="small"
:min="0"
:max="90"
v-model="viewModel.pitch"
/>
<p class="angletext">可视距离 (单位:米)</p>
<el-slider
id="distance"
show-input
size="small"
:min="1"
:max="10000"
v-model="viewModel.distance"
/>
<el-button type="primary" @click="addView">创建可视域</el-button>
<el-button type="primary" @click="clear">清除可视域</el-button>
</div>
2.javascript
<script setup>
import { reactive, watchEffect, onBeforeUnmount } from "vue";
import { useStore } from "vuex";
const store = useStore();
let viewer = window.viewer;
let scene = viewer.scene;
let viewPosition; //鼠标绘制的点
if (!scene.pickPositionSupported) {
alert("不支持深度纹理,可视域分析功能无法使用(无法添加观测)!");
}
// 先将此标记置为true,不激活鼠标移动事件中对可视域分析对象的操作
scene.viewFlag = true;
//创建绘制处理器对象类。
var pointHandler = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Point);
// 创建可视域分析对象
var viewshed3D = new Cesium.ViewShed3D(scene); //可视域分析,设置观察点、目标的位置,水平、垂直视角范围,建立可视区域分析并在指定的场景中显示分析结果。
//处理用户输入事件。
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
// 声明可视域参数(只选取了部分)
let viewModel = reactive({
pitch: 0, //相机俯仰角
distance: 500, //可视距离
verticalFov: 60, //垂直视角范围
horizontalFov: 80, //水平视角范围
});
//绘制完成事件,监听绘制完成的事件,获取当前绘制结果。
pointHandler.drawEvt.addEventListener(function (result) {
var point = result.object;
var position = point.position;
viewPosition = position; //鼠标绘制点赋值
// 将获取的点的位置转化成经纬度
var cartographic = Cesium.Cartographic.fromCartesian(position); //根据笛卡尔坐标(Cartesian3)位置创建一个Cartographic实例。结果数据以弧度为单位。
//将弧度转换为度
var longitude = Cesium.Math.toDegrees(cartographic.longitude);
var latitude = Cesium.Math.toDegrees(cartographic.latitude);
var height = cartographic.height + 1.8;
point.position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
if (scene.viewFlag) {
// 设置视口位置
viewshed3D.viewPosition = [longitude, latitude, height]; //观测点位置
viewshed3D.build();
// 将标记置为false以激活鼠标移动回调里面的设置可视域操作
scene.viewFlag = false;
}
});
// 鼠标移动时回调
handler.setInputAction(function (e) {
// 若此标记为false,则激活对可视域分析对象的操作
if (!scene.viewFlag) {
//获取鼠标屏幕坐标,并将其转化成笛卡尔坐标
var position = e.endPosition;
var last = scene.pickPosition(position); //位置拾取,根据窗口坐标,从场景的深度缓冲区中拾取相应的位置,返回笛卡尔坐标,需要支持深度纹理。
//计算该点与视口位置点坐标的距离
var distance = Cesium.Cartesian3.distance(viewPosition, last);
// 将鼠标当前点坐标转化成经纬度
var cartographic = Cesium.Cartographic.fromCartesian(last);
var longitude = Cesium.Math.toDegrees(cartographic.longitude);
var latitude = Cesium.Math.toDegrees(cartographic.latitude);
var height = cartographic.height;
voluation();
viewshed3D.setDistDirByPoint([longitude, latitude, height]);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 鼠标右键事件回调
handler.setInputAction(function (e) {
//不再执行鼠标移动事件中对可视域的操作
scene.viewFlag = true;
voluation();
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
//赋值
function voluation() {
viewshed3D.pitch = viewModel.pitch;
viewshed3D.distance = viewModel.distance;
viewshed3D.horizontalFov = viewModel.horizontalFov;
viewshed3D.verticalFov = viewModel.verticalFov;
}
//创建可视域
function addView() {
if (pointHandler.active) {
return;
}
//清除之前的可视域分析
clear();
//激活绘制点类
pointHandler.activate();
}
//移除可视域
function clear() {
viewshed3D.distance = 0.0000001;
viewshed3D = new Cesium.ViewShed3D(scene); //初始化
scene.viewFlag = true;
pointHandler.clear();
}
//监听可视域参数变化
watchEffect(() => {
voluation();
});
//销毁
onBeforeUnmount(() => {
clear();
pointHandler.deactivate();
});
</script>
到了这里,关于vue3+SuperMap iClient3D for Cesium实现可视域分析功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!