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>
	<s-mousetip v-if="tip.visible">{{ tip.text }}</s-mousetip>
</template>
<script setup>
import {onMounted, ref} from "vue";
import * as Cesium from "cesium";
import InitCesium from "../js/InitCesiumHide.js";
import DrawStraightLineDistance from "@/assets/utils/measure/DrawStraightLineDistance.js";
import SMousetip from '@/view/cesiumDemo/components/s-mousetip.vue'

let viewer = null;
let drawStraightLine = null;
let tip = ref({
	text: '',
	visible: false
})

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

const handleDrawPolyline = () => {
	tip.value.text = '左键点击确定起点,再次点击确定终点并结束';
	tip.value.visible = true;
	drawStraightLine = new DrawStraightLineDistance({Cesium: Cesium, viewer: viewer, callback: handleDrawPolylineEnd});
	drawStraightLine.startCreate();
}

const handleDrawPolylineEnd = (polylineData) => {
	tip.value.text = '';
	tip.value.visible = false;
}

const handleDrawPolylineCancel = () => {
	drawStraightLine.clear();
}

const flyToRight2 = () => {
	let camera = viewer.scene.camera;
	camera.flyTo({
		destination: Cesium.Cartesian3.fromDegrees(115.2766, 36.5522, 1500.34),
	});
}
</script>
<style scoped>
#cesiumContainer {
	overflow: hidden;
}
</style>
<style>
.el-breadcrumb__inner {
	color: #ffffff !important;
}
</style>
复制代码
DrawStraightLineDistance.js
复制代码
/* 绘制直线  水平距离 */
class DrawStraightLineDistance {
	constructor(arg) {
		this.viewer = arg.viewer;
		this.Cesium = arg.Cesium;
		this.callback = arg.callback;
		this._polyline = null; //活动线
		this._polylineLast = null; //最后一条线
		this._positions = [];  //活动点
		this._entities_point = [];  //脏数据
		this._entities_md_point = [];  //脏数据
		this._entities_md1_point = [];  //脏数据
		this._entities_line = [];  //脏数据
		this._polylineData = null; //用于构造线数据
	}

	//返回最后活动线
	get line() {
		return this._polylineLast;
	}

	//返回线数据用于加载线
	getData() {
		return this._polylineData;
	}

	//加载线
	loadPolyline(data) {
		let that = this;
		let polyline = that.viewer.entities.add({
			polyline: {
				positions: data,
				show: true,
				material: that.Cesium.Color.RED,
				width: 3,
				clampToGround: true
			}
		});
		return polyline;
	}

	//开始创建
	startCreate() {
		let that = this;
		that.handler = new that.Cesium.ScreenSpaceEventHandler(that.viewer.scene.canvas);
		that.handler.setInputAction(function (evt) { //单击开始绘制
			//屏幕坐标转地形上坐标
			let cartesian = that.getCatesian3FromPX(evt.position);
			if (that._positions.length === 0) {
				that._positions.push(cartesian.clone());
			}
			that._positions.push(cartesian);
			that.createPoint(cartesian);// 绘制点
			if (that._positions.length > 2) {
				if (!that._polyline) {
					return;
				}
				that._positions.pop();
				// that._positions.push(cartesian);
				that.createPoint(cartesian);// 绘制点
				that._polylineData = that._positions.concat();
				that.viewer.entities.remove(that._polyline); //移除
				that._polyline = null;
				that._positions = [];
				let line = that.loadPolyline(that._polylineData); //加载线
				that._entities_line.push(line);
				that._polylineLast = line;
				if (typeof that.callback == "function") {
					that.callback(that._polylineData);
				}
				for (let i = 0; i < that._entities_md1_point.length; i++) {
					that.viewer.entities.remove(that._entities_md1_point[i]);
				}
				let distance = that.Cesium.Cartesian3.distance(that._polylineData[0], that._polylineData[1]).toFixed(2);

				// let midPoint = that.Cesium.Cartesian3.midpoint(that._polylineData[0], that._polylineData[1]);
				let midPoint = that.Cesium.BoundingSphere.fromPoints(that._polylineData).center
				that.createMdPoint(midPoint, distance);
				that.handler.destroy();
				that.handler = null;
			}
		}, that.Cesium.ScreenSpaceEventType.LEFT_CLICK);
		this.handler.setInputAction(function (evt) { //移动时绘制线
			if (that._positions.length < 1) return;
			let cartesian = that.getCatesian3FromPX(evt.endPosition);
			if (!that.Cesium.defined(that._polyline)) {
				that._polyline = that.createPolyline();
			}
			if (that._polyline) {
				that._positions.pop();
				that._positions.push(cartesian);
			}
			let distance = that.Cesium.Cartesian3.distance(that._positions[0], that._positions[1]).toFixed(2);

			// let midPoint = that.Cesium.Cartesian3.midpoint(that._polylineData[0], that._polylineData[1]);
			let midPoint = that.Cesium.BoundingSphere.fromPoints(that._positions).center
			that.createMdPoint11(midPoint, distance);
		}, that.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
	}

	//创建点
	createPoint(cartesian) {
		let that = this;
		let point = this.viewer.entities.add({
			position: cartesian,
			point: {
				pixelSize: 10,
				color: that.Cesium.Color.YELLOW,
			}
		});
		that._entities_point.push(point);
		return point;
	}

	//创建点
	createMdPoint(cartesian, distance) {
		let that = this;
		let point = this.viewer.entities.add({
			position: cartesian,
			point: {
				pixelSize: 1,
				color: that.Cesium.Color.YELLOW,
			},
			label: {
				text: '水平距离:' + distance + '米',    //描述内容
				font: '14px Sans-Serif',   //字体大小 类型
				fillColor: that.Cesium.Color.fromCssColorString('#ffffff'),  //颜色
				outlineColor: that.Cesium.Color.GOLD,
				//设置背景颜色透明
				backgroundColor: new that.Cesium.Color(0, 0, 0, 0.7),
				//打开背景  打开背景 (不会被线段覆盖)
				showBackground: true,
				// scaleByDistance: new that.Cesium.NearFarScalar(1000, 1.0, 2000, 0.01),
				// disableDepthTestDistance: Number.POSITIVE_INFINITY
			}
		});
		that._entities_md_point.push(point);
		return point;
	}

	//创建点
	createMdPoint11(cartesian, distance) {
		let that = this;
		for (let i = 0; i < that._entities_md1_point.length; i++) {
			that.viewer.entities.remove(that._entities_md1_point[i]);
		}
		let point = this.viewer.entities.add({
			position: cartesian,
			point: {
				pixelSize: 1,
				color: that.Cesium.Color.YELLOW,
			},
			label: {
				text: '水平距离:' + distance + '米',    //描述内容
				font: '14px Sans-Serif',   //字体大小 类型
				fillColor: that.Cesium.Color.fromCssColorString('#ffffff'),  //颜色
				outlineColor: that.Cesium.Color.GOLD,
				//设置背景颜色透明
				backgroundColor: new that.Cesium.Color(0, 0, 0, 0.7),
				//打开背景  打开背景 (不会被线段覆盖)
				showBackground: true,
				// scaleByDistance: new that.Cesium.NearFarScalar(1000, 1.0, 2000, 0.01),
				// disableDepthTestDistance: Number.POSITIVE_INFINITY
			}
		});
		that._entities_md1_point.push(point);
		return point;
	}

	//创建线
	createPolyline() {
		let that = this;
		let polyline = this.viewer.entities.add({
			polyline: {
				//使用cesium的peoperty
				positions: new that.Cesium.CallbackProperty(function () {
					return that._positions
				}, false),
				show: true,
				material: that.Cesium.Color.RED,
				width: 3,
				clampToGround: true
			}
		});
		that._entities_line.push(polyline);
		return polyline;
	}

	//销毁
	destroy() {
		if (this.handler) {
			this.handler.destroy();
			this.handler = null;
		}
	}

	//清空实体对象
	clear() {
		for (let i = 0; i < this._entities_point.length; i++) {
			this.viewer.entities.remove(this._entities_point[i]);
		}
		for (let i = 0; i < this._entities_md_point.length; i++) {
			this.viewer.entities.remove(this._entities_md_point[i]);
		}
		for (let i = 0; i < this._entities_md1_point.length; i++) {
			this.viewer.entities.remove(this._entities_md1_point[i]);
		}
		for (let i = 0; i < this._entities_line.length; i++) {
			this.viewer.entities.remove(this._entities_line[i]);
		}
		this._polyline = null;
		this._positions = [];
		this._entities_point = [];  //脏数据
		this._entities_md_point = [];  //脏数据
		this._entities_md1_point = [];  //脏数据
		this._entities_line = [];  //脏数据
		this._polylineData = null; //用于构造线数据
		this._polylineLast = null;
		this.destroy();
	}

	getCatesian3FromPX(px) {
		let cartesian;
		let ray = this.viewer.camera.getPickRay(px);
		if (!ray) return null;
		cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
		return cartesian;
	}
}

export default DrawStraightLineDistance

效果图

InitCesiumHide.js

复制代码
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
相关推荐
dsyyyyy11018 小时前
JavaScript变量
开发语言·javascript·ecmascript
kyriewen8 小时前
手写 Promise.all、race、any:不到 30 行代码,解决并发异步的所有姿势
前端·javascript·面试
胡志辉的博客10 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·chrome·chromium·event loop
代码不加糖10 小时前
js中不会冒泡的事件有哪些?
前端·javascript·vue.js
懂懂tty10 小时前
Vue2与Vue3之间API差异
前端·javascript·vue.js
老毛肚11 小时前
软件测试期末考试
vue.js
小二·11 小时前
Next.js 15 全栈开发实战
开发语言·javascript·ecmascript
杨若瑜12 小时前
本地开发环境慢?localhost的锅!
vue.js
Rain50912 小时前
2.1 Nest.js 项目初始化与模块化架构
开发语言·前端·javascript·后端·架构·数据分析·node.js
拾年27513 小时前
从零手写 Ajax:用原生 XHR 搭建前后端交互全流程
前端·javascript·ajax