cesium通视分析
全部代码
<template>
<div id="cesiumContainer" style="height: 100vh;"></div>
<div id="toolbar" style="position: fixed;top:20px;left:220px;">
<el-breadcrumb :separator-icon="ArrowRight">
<el-breadcrumb-item>三维分析</el-breadcrumb-item>
<el-breadcrumb-item>多点通视</el-breadcrumb-item>
</el-breadcrumb>
<el-row class="mb-4" style="margin-top: 15px">
<el-button type="primary" @click="handleIntervisibility">分析</el-button>
<el-button type="primary" @click="handleIntervisibilityCancel">清除</el-button>
</el-row>
</div>
</template>
<script setup>
import {ArrowRight} from '@element-plus/icons-vue'
import {onMounted, ref} from "vue";
import * as Cesium from "cesium";
import InitCesium from "../js/InitCesiumHide.js";
let viewer = null;
const clouds = new Cesium.CloudCollection();
let obj = {
startpointStyle: {
image: '/src/assets/image/shexiangji.png',
text: '观察点',
pixelOffsetX: 10,
pixelOffsetY: 10
},
endpointStyle: {
image: '/src/assets/image/qidian.png',
text: '目标点',
pixelOffsetX: 10,
pixelOffsetY: 10
}
}
onMounted(() => {
let initCesium = new InitCesium('cesiumContainer');
viewer = initCesium.initViewer({});
flyToRight2();
viewer.scene.globe.depthTestAgainstTerrain = false;
})
let positions = [];
let markers = [];//点实体
let lineEntity = [];
const handleIntervisibility = () => {
let CesiumEventHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
viewer.scene.globe.depthTestAgainstTerrain = true;
CesiumEventHandler.setInputAction(function (movement) {
let cartesian = viewer.scene.pickPosition(movement.position);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian)
let longitude = Cesium.Math.toDegrees(cartographic.longitude)
let latitude = Cesium.Math.toDegrees(cartographic.latitude)
let height = cartographic.height
let position1 = Cesium.Cartesian3.fromDegrees(longitude, latitude, 10);
if (cartesian) {
if (markers.length === 0) {
positions.push(position1);//加点
//创建点实体
const startpoint = viewer.entities.add({
position: position1,
// position: cartesian,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
point: {
color: Cesium.Color.RED,
pixelSize: 10,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2
}
});
console.log(startpoint);
markers.push(startpoint);
} else if (markers.length >= 1) {
positions.push(cartesian);//加点
const endpoint = viewer.entities.add({
position: cartesian,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
point: {
color: Cesium.Color.YELLOW,
pixelSize: 10,
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2
}
});
markers.push(endpoint);
// CesiumEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)//移除左键事件
let linePoint = [];
linePoint.push(positions[0]);
linePoint.push(positions[positions.length - 1]);
analysisVisible(linePoint);//开始分析
}
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
CesiumEventHandler.setInputAction(function (movement) {
CesiumEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)//移除左键事件
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
const analysisVisible = (positions) => {
// 计算射线的方向
let direction = Cesium.Cartesian3.normalize(
Cesium.Cartesian3.subtract(
positions[1],
positions[0],
new Cesium.Cartesian3()
),
new Cesium.Cartesian3()
);
// 建立射线
let ray = new Cesium.Ray(positions[0], direction);
// 计算交互点,返回第一个
let result = viewer.scene.pickFromRay(ray);
// console.log(result)
if (Cesium.defined(result) && Cesium.defined(result.object)) {
drawLine(result.position, positions[0], Cesium.Color.GREEN); // 可视区域
drawLine(result.position, positions[1], Cesium.Color.RED); // 不可视区域
} else {
drawLine(positions[0], positions[1], Cesium.Color.GREEN);
console.log("不在模型上")
}
}
function drawLine(leftPoint, secPoint, color) {
let line = viewer.entities.add({
polyline: {
positions: [leftPoint, secPoint],
width: 2,
material: color,
depthFailMaterial: color 被地形遮挡部分的颜色
}
});
lineEntity.push(line)
}
const handleIntervisibilityCancel = () => {
if (lineEntity.length > 0) {
let len = lineEntity.length;
for (let i = 0; i < len; i++) {
viewer.entities.remove(lineEntity[i]);
}
}
if (markers.length > 0) {
let len = markers.length;
for (let i = 0; i < len; i++) {
viewer.entities.remove(markers[i]);
}
}
positions = [];
lineEntity = [];
markers = [];//点实体
}
const flyToRight2 = async () => {
let tileset = await Cesium.Cesium3DTileset.fromUrl('/src/assets/tileset/12/tileset.json', {});
update3dtilesMaxtrix(tileset);
viewer.scene.primitives.add(tileset);
viewer.flyTo(tileset);
/*viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(113.05965738392063, 22.638603971034342, 300.0), // 设置位置
orientation: {
heading: Cesium.Math.toRadians(20.0), // 方向
pitch: Cesium.Math.toRadians(-30.0),// 倾斜角度
roll: 0
},
duration: 5, // 设置飞行持续时间,默认会根据距离来计算
complete: function () {
// 到达位置后执行的回调函数
},
cancle: function () {
// 如果取消飞行则会调用此函数
},
pitchAdjustHeight: -90, // 如果摄像机飞越高于该值,则调整俯仰俯仰的俯仰角度,并将地球保持在视口中。
maximumHeight: 5000, // 相机最大飞行高度
flyOverLongitude: 100, // 如果到达目的地有2种方式,设置具体值后会强制选择方向飞过这个经度(这个,很好用)
});*/
}
function update3dtilesMaxtrix(tileSet) {
//调整参数
let params = {
tx: 113.06265738392063, //模型中心X轴坐标(经度,单位:十进制度)
ty: 22.646603971034342, //模型中心Y轴坐标(纬度,单位:十进制度)
tz: 45, //模型中心Z轴坐标(高程,单位:米)
rx: 0, //X轴(经度)方向旋转角度(单位:度)
ry: 0, //Y轴(纬度)方向旋转角度(单位:度)
rz: 2, //Z轴(高程)方向旋转角度(单位:度)
scale: 1.35, //缩放比例
};
//旋转
const mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(params.rx));
const my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(params.ry));
const mz = Cesium.Matrix3.fromRotationZ(Cesium.Math.toRadians(params.rz));
const rotationX = Cesium.Matrix4.fromRotationTranslation(mx);
const rotationY = Cesium.Matrix4.fromRotationTranslation(my);
const rotationZ = Cesium.Matrix4.fromRotationTranslation(mz);
//平移
const position = Cesium.Cartesian3.fromDegrees(
params.tx,
params.ty,
params.tz
);
const m = Cesium.Transforms.eastNorthUpToFixedFrame(position);
//旋转、平移矩阵相乘
Cesium.Matrix4.multiply(m, rotationX, m);
Cesium.Matrix4.multiply(m, rotationY, m);
Cesium.Matrix4.multiply(m, rotationZ, m);
//比例缩放
const scale = Cesium.Matrix4.fromUniformScale(params.scale);
Cesium.Matrix4.multiply(m, scale, m);
// console.log("矩阵m:", m);
//赋值给tileset
tileSet._root.transform = m;
}
</script>
<style scoped>
#cesiumContainer {
overflow: hidden;
}
</style>
<style>
.el-breadcrumb__inner, .el-breadcrumb__separator {
color: #ffffff !important;
}
</style>