cesium-测量高度垂直距离

news2024/11/25 18:35:10

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;

效果图

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1433648.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

情人节送什么礼物合适?情人节礼物最佳排行榜

​马上就要到情人节了&#xff0c;大家是否已经选好了送给爱人的礼物呢&#xff1f;如果没有&#xff0c;或许可以考虑一些优质的数码产品。随着科技的发展&#xff0c;数码产品已经成为我们生活中不可或缺的一部分。接下来&#xff0c;我将为大家推荐几款非常适合作为情人节礼…

LeetCode:2.两数相加

目录 题目&#xff1a;​编辑2. 两数相加 - 力扣&#xff08;LeetCode&#xff09; 分析问题&#xff1a; 官方的优秀代码博主的注释&#xff1a; 博主的辣眼代码&#xff0c;无注释&#xff0c;拉出来拷打自己&#xff1a; 每日表情包&#xff1a; 2. 两数相加 - 力扣&am…

什么是信创业态支持?支持信创的数据库防水坝哪家好?

随着国产化信创化的崛起&#xff0c;出现了很多新名词&#xff0c;例如信创业态支持、国产信创化等等。今天我们就来聊聊什么是信创业态支持&#xff1f;支持信创的数据库防水坝哪家好&#xff1f; 什么是信创业态支持&#xff1f; 大范围而言&#xff0c;信创业态支持可以理解…

【404App】一篇文章搞定SSL证书更换,赶紧收藏吧!

场景:阿里云服务器,nginx 第一步:下载免费证书,登录购买域名的阿里云账户,选择免费证书申请、下载(https://yundun.console.aliyun.com/?spm=5176.12818093_-1363046575.ProductAndResource–ali–widget-product-recent.2.3be916d0qj5Z8O&p=cas#/certExtend/free/…

uniapp中配置开发环境和生产环境

uniapp在开发的时候&#xff0c;可以配置多种环境&#xff0c;用于自动切换IP地址&#xff0c;用HBuilder X直接运行的就是开发环境&#xff0c;用HBuilder X发布出来的&#xff0c;就是生产环境。 1.使用HBuilder X创建原生的uniapp程序 选择vue3 2.什么都不改&#xff0c;就…

ChatGPT辅助编程,一次有益的尝试

如果大家想学习PCIe&#xff0c;搜索网上的信息&#xff0c;大概率会看到chinaaet上Felix的PCIe扫盲系列的博文 Felix-PCIe扫盲 每次看这个系列博文的时候&#xff0c;我都在想有没有什么方法可以把这个系列的博文都保存到一个pdf文件中&#xff0c;这样方便阅读。于是有了下…

嵌入式 - UART Flow Control

简介 / Introduction UART 流量控制是一种让慢速和快速设备通过 UART 相互通信而不会丢失数据的方法。 考虑两个设备通过 UART 通信的情况。发送器 T 正在向接收器 R 发送一长串字节。R 是一个比 T 慢的设备&#xff0c;在某些时候 R 无法跟上。它需要对数据进行一些处理或清空…

项目02《游戏-07-开发》Unity3D

基于 项目02《游戏-06-开发》Unity3D &#xff0c; 接下来做UI框架的逻辑系统&#xff0c;管理器和UI背包&#xff0c; 首先闯将UI框架的两个重要脚本 BasePanel.cs 和 UIManager.cs &#xff0c; 双击BasePanel.cs脚本修改代码&#xff1a; using UnityEngine; pu…

基于Java SSM框架实现网上租车系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现网上租车系统演示 摘要 随着现在网络的快速发展&#xff0c;网上管理系统也逐渐快速发展起来&#xff0c;网上管理模式很快融入到了许多商家的之中&#xff0c;随之就产生了“网上租车系统”&#xff0c;这样就让网上租车系统更加方便简单。 对于本网上…

架构篇33:传统的可扩展架构模式-分层架构和SOA

文章目录 分层架构SOA小结相比于高性能、高可用架构模式在最近几十年的迅猛发展来说,可扩展架构模式的发展可以说是步履蹒跚,最近几年火热的微服务模式算是可扩展模式发展历史中为数不多的亮点,但这也导致了现在谈可扩展的时候必谈微服务,甚至微服务架构都成了架构设计的银…

Undertow使用详解

简介 Undertow是一个开源的、灵活的、高性能的非阻塞性应用服务器&#xff0c;由JBoss提供。它可以用作嵌入式服务器&#xff0c;也可以用作大型项目的全功能应用服务器。Undertow的设计以提供最高的性能和最大的灵活性为主要目标&#xff0c;支持非阻塞性和阻塞性处理方式&…

乐意购项目前端开发 #6

一、商品详情页面 代码模版 创建Detail文件夹, 然后创建index.vue文件 <script setup> import { getDetail } from "/api/goods/index"; import { ref, onMounted } from "vue"; import { useRoute } from "vue-router"; import { useCar…

手写分布式存储系统v0.3版本

引言 承接 手写分布式存储系统v0.2版本 &#xff0c;今天开始新的迭代开发。主要实现 服务发现功能 一、什么是服务发现 由于咱们的服务是分布式的&#xff0c;那从服务管理的角度来看肯定是要有一个机制来知道具体都有哪些实例可以提供服务。举个例子就是&#xff0c;张三家…

《大魔界村》中的人物性格——亚瑟

《大魔界村》作为一款经典的街机动作游戏,其主角——勇敢的骑士亚瑟,以其独特的性格特点和坚定的信念,在玩家心中留下了深刻印象。本文将深入探讨亚瑟这一角色的性格特质,通过分析他在游戏中的行为表现及决策过程,展现他身上的勇气、坚韧与智慧三大要点。 一、无畏挑战的…

全套电气自动化样例图纸分享,使用SuperWorks自动化版免费设计软件!

今天给大家分享一套完备的电气自动化样例图纸&#xff0c;结构准确、内容清晰&#xff0c;适合初学者入门操作练习。 整套图纸包含图纸目录、原理图、端子列表、连接列表、元件列表、接线图&#xff0c;具有较高的参考价值&#xff0c;请大家点击自行下载文件&#xff01; 1e8…

【51单片机】直流电机实验和步进电机实验

目录 直流电机实验直流电机介绍ULN2003 芯片介绍硬件设计软件设计实验现象 步进电机实验步进电机简介步进电机的工作原理步进电机极性区分双极性步进电机驱动原理单极性步进电机驱动原理细分驱动原理 28BYJ-48 步进电机简介软件设计 橙色 直流电机实验 在未学习 PWM 之前&…

出海企业应用CRM系统可行吗?有哪些好处?

近年来许多企业都涌现出了出海需求&#xff0c;在不同国家设置了办事处。企业在管理业务和客户时&#xff0c;不可避免用到CRM管理系统。对于这样的跨国企业&#xff0c;是否有一个CRM系统可以满足其需求&#xff1f;——答案是有的&#xff0c;这篇文章将为您介绍跨国协作CRM的…

Palworld幻兽帕鲁自建服务器32人联机开黑!

玩转幻兽帕鲁服务器&#xff0c;阿里云推出新手0基础一键部署幻兽帕鲁服务器教程&#xff0c;傻瓜式一键部署&#xff0c;3分钟即可成功创建一台Palworld专属服务器&#xff0c;成本仅需26元&#xff0c;阿里云服务器网aliyunfuwuqi.com分享2024年新版基于阿里云搭建幻兽帕鲁服…

Java实现康复中心管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 普通用户模块2.2 护工模块2.3 管理员模块 三、系统展示四、核心代码4.1 查询康复护理4.2 新增康复训练4.3 查询房间4.4 查询来访4.5 新增用药 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的康复中…

vue项目中的 package.json 的文件是什么

在 Vue.js 项目中&#xff0c;package.json 文件是一个 JSON 文件&#xff0c;用于存储项目的元数据和依赖关系。这个文件应该位于项目的根目录下。 以下是一个简单的 package.json 文件示例&#xff1a; {"name": "my-vue-project","version"…