cesium-测量高度垂直距离

cesium做垂直测量

完整代码

复制代码
<template>
	<div id="cesiumContainer" style="height: 100vh;"></div>
	<div id="toolbar" style="position: fixed;top:20px;left:220px;">
		<el-breadcrumb>
			<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="handleDrawPolyline">画线</el-button>
			<el-button type="primary" @click="handleDrawPolylineCancel">清除</el-button>
		</el-row>
	</div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import * as Cesium from "cesium";
import InitCesium from "../js/InitCesiumHide.js";
import DrawVerticalDistance from "@/assets/utils/measure/DrawVerticalDistance.js";

let viewer = null;
let verticalDistance = null;

onMounted(() => {
	let initCesium = new InitCesium('cesiumContainer')
	viewer = initCesium.initViewer({});
	verticalDistance = new DrawVerticalDistance(viewer);
	flyToRight2();
})

const handleDrawPolyline = () => {
	if (verticalDistance) {
		// 开始量算
		verticalDistance.start();
	}
}

const handleDrawPolylineCancel = () => {
	if (!verticalDistance) return;
	verticalDistance.destroy();
}

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);
}

function update3dtilesMaxtrix(tileSet) {
	//调整参数
	let params = {
		tx: 113.06265738392063, //模型中心X轴坐标(经度,单位:十进制度)
		ty: 22.646803971034342, //模型中心Y轴坐标(纬度,单位:十进制度)
		tz: 40, //模型中心Z轴坐标(高程,单位:米)
		rx: 0, //X轴(经度)方向旋转角度(单位:度)
		ry: 0, //Y轴(纬度)方向旋转角度(单位:度)
		rz: 2, //Z轴(高程)方向旋转角度(单位:度)
		scale: 1.3, //缩放比例
	};
	//旋转
	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 {
	color: #ffffff !important;
}
</style>
复制代码
InitCesiumHide
复制代码
import * as Cesium from "cesium";

class InitCesiumHide {

	constructor(cesiumContainer, options) {
		this.cesiumContainer = cesiumContainer;
	}

	initViewer(options) {
		Cesium.Ion.defaultAccessToken = 'token';
		// 西南东北,默认显示中国
		Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(90, -20, 110, 90);
		return new Cesium.Viewer(this.cesiumContainer, {
			animation: false, // 隐藏动画控件
			baseLayerPicker: false, // 隐藏图层选择控件
			fullscreenButton: false, // 隐藏全屏按钮
			vrButton: false, // 隐藏VR按钮,默认false
			geocoder: false, // 隐藏地名查找控件  地理编码
			homeButton: false, // 隐藏Home按钮
			infoBox: false, // 隐藏点击要素之后显示的信息窗口
			sceneModePicker: false, // 隐藏场景模式选择控件
			selectionIndicator: false, // 显示实体对象选择框,默认true
			timeline: false, // 隐藏时间线控件
			navigationHelpButton: false, // 隐藏帮助按钮
			scene3DOnly: true, // 每个几何实例将只在3D中呈现,以节省GPU内存
			shouldAnimate: true, // 开启动画自动播放
			sceneMode: 3, // 初始场景模式 1:2D 2:2D循环 3:3D,默认3
			requestRenderMode: true, // 减少Cesium渲染新帧总时间并减少Cesium在应用程序中总体CPU使用率
			...options
		});
	}
}

export default InitCesiumHide
复制代码
DrawVerticalDistance
复制代码
import BaseMeasure from "./baseMeasure";
import '../prompt/prompt.css'
import Prompt from '../prompt/prompt.js'
import * as Cesium from "cesium";

/**
 * 三角测量类
 * @class
 * @augments BaseMeasure
 * @alias BaseMeasure.MeasureTriangle
 */
class DrawVerticalDistance extends BaseMeasure {
	constructor(viewer, opt) {
		super(viewer, opt);
		if (!opt) opt = {};
		this.unitType = "length";
		this.style = opt.style || {};
		//线
		this.heightfloatLabel = null;
		this.spaceDistancefloatLabel = null;
		this.horizonDistancefloatLabel = null;
		this.heightLine = null;
		this.spaceLine = null;
		this.horizonLine = null;
		this.firstPosition = null;
		this.endPosition = null;
		this.midPosition = undefined;
		this.lowPosition = undefined;
		this.highPosition = undefined;

	}

	//开始测量
	start(callback) {
		if (!this.prompt && this.promptStyle.show) {
			this.prompt = new Prompt(this.viewer, this.promptStyle)
		}
		var that = this;
		this.state = 1;
		that.handler.setInputAction((evt) => { //单击开始绘制
			var cartesian = that.getCatesian3FromPX(evt.position, that.viewer);
			if (!cartesian) return;
			if (!that.firstPosition) {
				that.firstPosition = cartesian.clone();
				that.heightfloatLabel = that.createLabel(cartesian, "");
				that.spaceDistancefloatLabel = that.createLabel(cartesian, "", 10);
				that.horizonDistancefloatLabel = that.createLabel(cartesian, "");

				let point = that.createPoint(cartesian.clone());
				point.wz = 0;
				that.controlPoints.push(point);

			} else {
				that.endPosition = cartesian;
				that.computerPosition(that.firstPosition, that.endPosition);

				let point = that.createPoint(cartesian.clone());
				point.wz = 1;
				that.controlPoints.push(point);

				if (that.handler) {
					that.handler.destroy();
					that.handler = null;
				}

				if (that.prompt) {
					that.prompt.destroy();
					that.prompt = null;
				}
				that.state = "endCreate";
				if (callback) callback();
			}
		}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
		this.handler.setInputAction(function (evt) {
			that.state = "creating";
			if (!that.firstPosition) {
				that.prompt.update(evt.endPosition, "左键点击确定起点,再次点击确定终点并结束");
				return;
			}
			that.prompt.update(evt.endPosition, "左键点击确定起点,再次点击确定终点并结束");

			var cartesian = that.getCatesian3FromPX(evt.endPosition, that.viewer);
			if (!cartesian) return;
			that.endPosition = cartesian;
			that.computerPosition(that.firstPosition, that.endPosition);

			if (that.firstPosition && that.endPosition && !that.heightLine) {

				that.heightLine = that.viewer.entities.add({
					polyline: {
						positions: new Cesium.CallbackProperty(function () {
							return [that.lowPosition, that.midPosition]
						}, false),
						show: true,
						material: new Cesium.PolylineOutlineMaterialProperty({
							color: Cesium.Color.GOLD,
							outlineWidth: 2,
							outlineColor: Cesium.Color.BLACK,
						}),
						width: 3,
					}
				});
				that.heightLine.objId = that.objId;

				that.horizonLine = that.viewer.entities.add({
					polyline: {
						positions: new Cesium.CallbackProperty(function () {
							return [that.highPosition, that.midPosition]
						}, false),
						show: true,
						material: new Cesium.PolylineOutlineMaterialProperty({
							color: Cesium.Color.GOLD,
							outlineWidth: 2,
							outlineColor: Cesium.Color.BLACK,
						}),
						width: 3,
					}
				});
				that.horizonLine.objId = that.objId;
			}
			if (that.heightLine) that.createLabels();
		}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
	}

	//计算正上方的点
	computerPosition(p1, p2) {
		const cartographic1 = Cesium.Cartographic.fromCartesian(p1.clone());
		const cartographic2 = Cesium.Cartographic.fromCartesian(p2.clone());
		if (cartographic1.height > cartographic2.height) {
			this.highPosition = p1.clone();
			this.lowPosition = p2.clone();
			this.midPosition = Cesium.Cartesian3.fromRadians(cartographic2.longitude, cartographic2.latitude, cartographic1.height);
		} else {
			this.lowPosition = p1.clone();
			this.highPosition = p2.clone();
			this.midPosition = Cesium.Cartesian3.fromRadians(cartographic1.longitude, cartographic1.latitude, cartographic2.height);
		}
	}

	startEdit(callback) {
		if (!(this.state == "endCrerate" || this.state == "endEdit")) return;
		this.state = "startEdit";

		if (!this.modifyHandler) this.modifyHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
		let that = this;

		for (let i = 0; i < that.controlPoints.length; i++) {
			let point = that.controlPoints[i];
			if (point) point.show = true;
		}
		this.modifyHandler.setInputAction(function (evt) {
			let pick = that.viewer.scene.pick(evt.position);
			if (Cesium.defined(pick) && pick.id) {
				if (!pick.id.objId)
					that.modifyPoint = pick.id;
				that.forbidDrawWorld(true);
			}
		}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

		this.modifyHandler.setInputAction(function (evt) {
			if (!that.modifyPoint) return;
			let cartesian = that.getCatesian3FromPX(evt.endPosition, that.viewer);
			if (!cartesian) return;
			that.modifyPoint.position.setValue(cartesian.clone());

			if (that.modifyPoint.wz == 0) {
				that.firstPosition = cartesian.clone()
			} else {
				that.endPosition = cartesian.clone()
			}

			that.computerPosition(that.firstPosition, that.endPosition);
			that.createLabels();

		}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

		this.modifyHandler.setInputAction(function (evt) {
			if (!that.modifyPoint) return;
			that.modifyPoint = null;
			that.forbidDrawWorld(false);
			that.state = "endEdit";
			if (callback) callback();
		}, Cesium.ScreenSpaceEventType.LEFT_UP);
	}

	endEdit() {
		let that = this;
		this.state = "endEdit";

		if (this.modifyHandler) {
			this.modifyHandler.destroy();
			this.modifyHandler = null;
		}
		for (let i = 0; i < that.controlPoints.length; i++) {
			let point = that.controlPoints[i];
			if (point) point.show = false;
		}
	}

	createLabels() {
		let that = this;
		//高度差
		var height = Math.abs(Cesium.Cartographic.fromCartesian(that.highPosition).height - Cesium.Cartographic.fromCartesian(that.lowPosition).height);
		var height_mid = Cesium.Cartesian3.midpoint(that.lowPosition, that.midPosition, new Cesium.Cartesian3());
		that.heightfloatLabel.show = true;
		that.heightfloatLabel.position.setValue(height_mid);
		let text1 = that.formateLength(height, that.unit);
		that.heightfloatLabel.label.text = "垂直距离:" + text1;
		that.heightfloatLabel.length = height;
	}

	claer() {
		this.destroy();
	}

	//清除测量结果
	destroy() {
		this.state = "no";
		let that = this;

		if (that.heightLine) {
			that.viewer.entities.remove(that.heightLine);
			that.heightLine = null;
		}
		// if (this.spaceLine) {
		// 	this.viewer.entities.remove(this.spaceLine);
		// 	this.spaceLine = null;
		// }
		if (that.horizonLine) {
			that.viewer.entities.remove(that.horizonLine);
			that.horizonLine = null;
		}
		if (that.heightfloatLabel) {
			that.viewer.entities.remove(that.heightfloatLabel);
			that.heightfloatLabel = null;
		}
		that.heightfloatLabel = null;
		if (this.spaceDistancefloatLabel) {
			this.viewer.entities.remove(this.spaceDistancefloatLabel);
			this.spaceDistancefloatLabel = null;
		}
		that.spaceDistancefloatLabel = null;
		if (that.horizonDistancefloatLabel) {
			that.viewer.entities.remove(that.horizonDistancefloatLabel);
			that.horizonDistancefloatLabel = null;
		}
		that.horizonDistancefloatLabel = null;
		if (that.prompt) {
			that.prompt.destroy();
			that.prompt = null;
		}
		if (that.handler) {
			that.handler.destroy();
			that.handler = null;
		}
	}


	setUnit(unit) {
		if (this.heightfloatLabel) {
			let text1 = this.formateLength(this.heightfloatLabel.length, unit);
			this.heightfloatLabel.label.text = "垂直距离:" + text1;
		}


		this.unit = unit;
	}
}

export default DrawVerticalDistance;

效果图

相关推荐
冴羽31 分钟前
今日苹果 App Store 前端源码泄露,赶紧 fork 一份看看
前端·javascript·typescript
蒜香拿铁34 分钟前
Angular【router路由】
前端·javascript·angular.js
时间的情敌40 分钟前
Vite 大型项目优化方案
vue.js
brzhang1 小时前
读懂 MiniMax Agent 的设计逻辑,然后我复刻了一个MiniMax Agent
前端·后端·架构
西洼工作室1 小时前
高效管理搜索历史:Vue持久化实践
前端·javascript·vue.js
广州华水科技1 小时前
北斗形变监测传感器在水库安全中的应用及技术优势分析
前端
樱花开了几轉1 小时前
element ui下拉框踩坑
开发语言·javascript·ui
开发者如是说2 小时前
Compose 开发桌面程序的一些问题
前端·架构
故事不长丨2 小时前
【Java SpringBoot+Vue 实现视频文件上传与存储】
java·javascript·spring boot·vscode·后端·vue·intellij-idea
旺代2 小时前
Token 存储与安全防护
前端