cesium-通视

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>
相关推荐
如若12335 分钟前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~1 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语1 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport1 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg1 小时前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全
胡西风_foxww2 小时前
【es6复习笔记】rest参数(7)
前端·笔记·es6·参数·rest
m0_748254882 小时前
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
前端·vue.js·elementui
星就前端叭2 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
m0_748234522 小时前
前端Vue3字体优化三部曲(webFont、font-spider、spa-font-spider-webpack-plugin)
前端·webpack·node.js
Web阿成2 小时前
3.学习webpack配置 尝试打包ts文件
前端·学习·webpack·typescript