cesium教程4-测量工具
测量是cesium系统必要的模块,一般测量则是这几个(下图)长度测量,面积测量,还有直线,水平,垂直的测量,现在我就把测量基本原理和代码分享给大家
先看一下效果
长度测量
面积测量
直线,水平,垂直测量
1.距离测量
距离测量其实就是测量两个点之间的距离,通过直角三角形求斜边 的原理求距离.但是我们不用这么麻烦,cesium官方提供了
//传入两点返回长度Cesium.Cartesian3.distance(firstPoint, secondPoint);//逻辑代码如下getLengthText(firstPoint, secondPoint) {// 计算距离var length = Cesium.Cartesian3.distance(firstPoint, secondPoint);if (length > 1000) {length = (length / 1000).toFixed(2) + " 公里";} else {length = length.toFixed(2) + " 米";}return length;};
那么好了现在已经有计算两个点的距离了,现在需要吧计算的结果展示到两个点的中心位置,
计算两个点中心点方法,cesium官方也是提供的
//传入两点返回中心坐标
Cesium.Cartesian3.midpoint(positions[0], positions[1], new Cesium.Cartesian3())
还需要创建一个label显示一下
/*** 添加标签* @param position* @param text*/addLabel(centerPoint, text) {return this.viewer.entities.add(new Cesium.Entity({position: centerPoint,label: {text: text,font: '14px sans-serif',style: Cesium.LabelStyle.FILL_AND_OUTLINE, //FILL FILL_AND_OUTLINE OUTLINEfillColor: Cesium.Color.YELLOW,showBackground: true, //指定标签后面背景的可见性backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.8), // 背景颜色backgroundPadding: new Cesium.Cartesian2(6, 6), //指定以像素为单位的水平和垂直背景填充paddingpixelOffset: new Cesium.Cartesian2(0, -25),disableDepthTestDistance: Number.POSITIVE_INFINITY}}));};
那我们结合操作事件看一下代码
measurePolyLine() {var positions = [];var labelEntity = null; // 标签实体// 注册鼠标左击事件this.viewer.screenSpaceEventHandler.setInputAction((clickEvent) => {var cartesian = this.viewer.scene.pickPosition(clickEvent.position); // 坐标// 存储第一个点if(!cartesian){return false;}if (positions.length == 0) {positions.push(cartesian.clone());//添加一个蓝点this.addPoint(cartesian);// 注册鼠标移动事件this.viewer.screenSpaceEventHandler.setInputAction((moveEvent) => {//var movePosition = this.viewer.scene.pickPosition(moveEvent.endPosition); // 鼠标移动的点var movePosition = this.viewer.scene.globe.pick(this.viewer.camera.getPickRay(moveEvent.endPosition), this.viewer.scene);if(!movePosition){return false;}if (positions.length == 2) {positions.pop();positions.push(movePosition);// 绘制labelif (labelEntity) {this.viewer.entities.remove(labelEntity);this.entityCollection.splice(this.entityCollection.indexOf(labelEntity), 1);}// 计算中点var centerPoint = Cesium.Cartesian3.midpoint(positions[0], positions[1], new Cesium.Cartesian3());// 计算距离var lengthText = "距离:" + this.getLengthText(positions[0], positions[1]);labelEntity = this.addLabel(centerPoint, lengthText);this.entityCollection.push(labelEntity);} else {positions.push(movePosition);// 绘制线this.addLine(positions);}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);} else {// 存储第二个点positions.pop();positions.push(cartesian);this.addPoint(cartesian);this.addLine(positions);this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);};
2.面积测量
简单说一下原理:计算面积其实就是把一个面拆分成一个一个的三角曲面计算然后相加得到,下面贴出计算的面积的代码
//计算多边形面积getArea(points) {var degreesPerRadian = 180.0 / Math.PI; //弧度转化为角度/*角度*/function Angle(p1, p2, p3) {var bearing21 = Bearing(p2, p1);var bearing23 = Bearing(p2, p3);var angle = bearing21 - bearing23;if (angle < 0) {angle += 360;}return angle;}/*方向*/function Bearing(from, to) {from = Cesium.Cartographic.fromCartesian(from);to = Cesium.Cartographic.fromCartesian(to);var lat1 = from.latitude;var lon1 = from.longitude;var lat2 = to.latitude;var lon2 = to.longitude;var angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));if (angle < 0) {angle += Math.PI * 2.0;}angle = angle * degreesPerRadian; //角度return angle;}function distance(point1, point2) {var point1cartographic = Cesium.Cartographic.fromCartesian(point1);var point2cartographic = Cesium.Cartographic.fromCartesian(point2);/**根据经纬度计算出距离**/var geodesic = new Cesium.EllipsoidGeodesic();geodesic.setEndPoints(point1cartographic, point2cartographic);var s = geodesic.surfaceDistance;//console.log(Math.sqrt(Math.pow(distance, 2) + Math.pow(endheight, 2)));//返回两点之间的距离s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));return s;}var res = 0;//拆分三角曲面for (var i = 0; i < points.length - 2; i++) {var j = (i + 1) % points.length;var k = (i + 2) % points.length;var totalAngle = Angle(points[i], points[j], points[k]);var dis_temp1 = distance(points[j], points[0]);var dis_temp2 = distance(points[k], points[0]);res += dis_temp1 * dis_temp2 * Math.sin(totalAngle) / 2;// console.log(res);}if (res < 1000000) {res = Math.abs(res).toFixed(4) + " 平方米";} else {res = Math.abs((res / 1000000.0).toFixed(4)) + " 平方公里";}return res;};
然后用cesium的api画一个面
/*** 添加面* @param positions*/addPolyGon(positions) {var dynamicPositions = new Cesium.CallbackProperty(() => {return new Cesium.PolygonHierarchy(positions);}, false);this.entityCollection.push(this.viewer.entities.add(new Cesium.Entity({polygon: {hierarchy: dynamicPositions,material: Cesium.Color.RED.withAlpha(0.6),classificationType: Cesium.ClassificationType.BOTH // 贴地表和贴模型,如果设置了,这不能使用挤出高度}})));};
还是根据操作事件看一下代码
measurePolygon() {var positions = [];var clickStatus = false;var labelEntity = null;this.viewer.screenSpaceEventHandler.setInputAction((clickEvent) => {clickStatus = true;var cartesian = this.viewer.scene.globe.pick(this.viewer.camera.getPickRay(clickEvent.position), this.viewer.scene);if(!cartesian){return false}if (positions.length == 0) {positions.push(cartesian.clone()); //鼠标左击 添加第1个点this.addPoint(cartesian);this.viewer.screenSpaceEventHandler.setInputAction((moveEvent) => {var movePosition = this.viewer.scene.globe.pick(this.viewer.camera.getPickRay(moveEvent.endPosition), this.viewer.scene);if(!movePosition){return false;}if (positions.length == 1) {positions.push(movePosition);this.addLine(positions);} else {if (clickStatus) {positions.push(movePosition);} else {positions.pop();positions.push(movePosition);}}if (positions.length >= 3) {// 绘制labelif (labelEntity) {this.viewer.entities.remove(labelEntity);this.entityCollection.splice(this.entityCollection.indexOf(labelEntity), 1);}var text = "面积:" + this.getArea(positions);var centerPoint = this.getCenterOfGravityPoint(positions);labelEntity = this.addLabel(centerPoint, text);this.entityCollection.push(labelEntity);}clickStatus = false;}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);} else if (positions.length == 2) {if(!cartesian){return false}positions.pop();positions.push(cartesian.clone()); // 鼠标左击 添加第2个点this.addPoint(cartesian);this.addPolyGon(positions);// 右击结束this.viewer.screenSpaceEventHandler.setInputAction((clickEvent) => {var clickPosition = this.viewer.scene.globe.pick(this.viewer.camera.getPickRay(clickEvent.position), this.viewer.scene);if(!clickPosition){return false;}positions.pop();positions.push(clickPosition);positions.push(positions[0]); // 闭合this.addPoint(clickPosition);this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);if (callback) {callback()}}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);} else if (positions.length >= 3) {if(!cartesian){return false}positions.pop();positions.push(cartesian.clone()); // 鼠标左击 添加第3个点this.addPoint(cartesian);}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);};
3.直线,水平,垂直测量
直线,水平,垂直测量我们也叫高度的测量,大概原理就是空间两点垂直与地面画一个直角三角形,分别标出每条线的长度,(计算长度距离测量用到过这里就不说了)
直接上代码
measureHeight(callback) {var positions = [];var labelEntity_1 = null; // 标签实体var labelEntity_2 = null; // 标签实体var labelEntity_3 = null; // 标签实体// 注册鼠标左击事件this.viewer.screenSpaceEventHandler.setInputAction((clickEvent) => {var cartesian = this.viewer.scene.pickPosition(clickEvent.position); // 坐标// 存储第一个点if (positions.length == 0) {if(!cartesian){return false}positions.push(cartesian.clone());this.addPoint(cartesian);// 注册鼠标移动事件this.viewer.screenSpaceEventHandler.setInputAction((moveEvent) => {var movePosition = this.viewer.scene.pickPosition(moveEvent.endPosition); // 鼠标移动的点if(!movePosition){return false}if (positions.length >= 2) {positions.pop();positions.pop();positions.pop();var cartographic = Cesium.Cartographic.fromCartesian(movePosition);var height = Cesium.Cartographic.fromCartesian(positions[0]).height;var verticalPoint = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), height);positions.push(verticalPoint);positions.push(movePosition);positions.push(positions[0]);// 绘制labelif (labelEntity_1) {this.viewer.entities.remove(labelEntity_1);this.entityCollection.splice(this.entityCollection.indexOf(labelEntity_1), 1);this.viewer.entities.remove(labelEntity_2);this.entityCollection.splice(this.entityCollection.indexOf(labelEntity_2), 1);this.viewer.entities.remove(labelEntity_3);this.entityCollection.splice(this.entityCollection.indexOf(labelEntity_3), 1);}// 计算中点var centerPoint_1 = Cesium.Cartesian3.midpoint(positions[0], positions[1], new Cesium.Cartesian3());// 计算距离var lengthText_1 = "水平距离:" + this.getLengthText(positions[0], positions[1]);labelEntity_1 = this.addLabel(centerPoint_1, lengthText_1);this.entityCollection.push(labelEntity_1);// 计算中点var centerPoint_2 = Cesium.Cartesian3.midpoint(positions[1], positions[2], new Cesium.Cartesian3());// 计算距离var lengthText_2 = "垂直距离:" + this.getLengthText(positions[1], positions[2]);labelEntity_2 = this.addLabel(centerPoint_2, lengthText_2);this.entityCollection.push(labelEntity_2);// 计算中点var centerPoint_3 = Cesium.Cartesian3.midpoint(positions[2], positions[3], new Cesium.Cartesian3());// 计算距离var lengthText_3 = "直线距离:" + this.getLengthText(positions[2], positions[3]);labelEntity_3 = this.addLabel(centerPoint_3, lengthText_3);this.entityCollection.push(labelEntity_3);} else {var verticalPoint = new Cesium.Cartesian3(movePosition.x, movePosition.y, positions[0].z);positions.push(verticalPoint);positions.push(movePosition);positions.push(positions[0]);// 绘制线this.addLine(positions);}}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);} else {// 存储第二个点positions.pop();positions.pop();positions.pop();var cartographic = Cesium.Cartographic.fromCartesian(cartesian);var height = Cesium.Cartographic.fromCartesian(positions[0]).height;var verticalPoint = Cesium.Cartesian3.fromDegrees(Cesium.Math.toDegrees(cartographic.longitude), Cesium.Math.toDegrees(cartographic.latitude), height);positions.push(verticalPoint);positions.push(cartesian);positions.push(positions[0]);this.addPoint(cartesian);this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);this.viewer.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);if (callback) {callback()}}}, Cesium.ScreenSpaceEventType.LEFT_CLICK);};
完整代码
github:https://github.com/weshmily/cesiumPDG
作者: weshmily前端
官网: 百度搜索(weshmily前端)
CSDN博客:http://blog.csdn.net/qq_27118895
GitHub: https://github.com/weshmily
公众号:搜索"weshmilyqd"
cesium教程4-测量工具相关推荐
- Cesium教程 (1) 界面介绍-3dtiles加载-更改鼠标操作设置
Cesium教程 (1) 界面介绍-3dtiles加载-更改鼠标操作设置 目录 1. 界面介绍 (7-8互换位置) 2. 数据转3dtiles 3. 代码详解 4. 其他 1. 界面介绍 (7-8互换 ...
- Cesium教程(十六):动态数据三维可视化
Cesium教程(十六):动态数据三维可视化 1.Cesium时间系统 Cesium时间系统在动态数据可视化中发挥着重要作用. 2.动态数据格式CZML CZML是Cesium团队制定的一种用来描述动 ...
- Cesium教程(十四):简易三维模型的可视化
Cesium教程(十四):简易三维模型的可视化 效果预览 1.高效三维数据格式:3D Tiles 3D Tiles是Cesium提出的处理三维地理大数据的数据格式,目前已是OGC数据标准之一,并在We ...
- Cesium教程(十三):几何形体选取
Cesium教程(十三):几何形体选取 即使多个GeometryInstance被合并为单个Primitive,依然可以被独立地访问.可以为每一个GeometryInstance指定一个ID,并且可以 ...
- cesium入门示例-测量工具
作为cesium入门示例级别的最后一篇,参考cesium-长度测量和面积测量实现测量工具封装,修改了其中的距离测量函数,计算贴地距离,并对事件内部处理做了调整.包括贴地距离测量.面积测量.结果清除. ...
- (转)Cesium教程系列汇总
https://www.cnblogs.com/fuckgiser/p/5706842.html Cesium系列目录: 演示实例 ExamplesforCesium 最近老实有一些人问我,下载后在本 ...
- cesium教程-3(显示高度,海拔,经度,纬度)
老规矩先看效果 解析: 在Cesium里面,我们可以通过Cesium.ScreenSpaceEventHandler的实例化对象的setInputAction方法绑定鼠标事件: var handler ...
- cesium教程7-航迹模拟(无人机轨迹模拟飞行)
先看效果 航迹模拟-----模拟真实无人机飞行的轨迹和云台的拍摄方向,到达指定的拍摄点返回拍摄点的ID,用于显示对应拍摄点的照片或者视频 实现过程 创建一条轨迹和拍摄点 /*** @param {*} ...
- Cesium教程(八):绘制几何形体
目录 1.点要素 2.线要素 2.1 折线要素 2.2 轮廓线 3.面要素 4.体要素 三维几何形体所涉及的几何要素种类丰富,从类型上划分为点.线.面.体四大类.
最新文章
- 再见Python!Yann LeCun警告:深度学习需要新编程语言
- C#使用Xamarin开发可移植移动应用进阶篇(7.使用布局渲染器,修改默认布局),附源码...
- spring jdbcTemplate使用queryForList示例
- jsp 将页面中的值导入java中_JavaWeb - JSP:概述和语法,内置对象,JavaBean 组件,MVC 设计模式
- JS鼠标滚轮事件详解
- 字典树(Trie树)
- python 保存网页到印象笔记_如何将网页内容保存到印象笔记?
- What happens when passing an non-exist text object to API
- matlab 爬虫 例子,认识爬虫(示例代码)
- 8.4. su - root
- matlab通用程序,三次样条差值-matlab通用程序
- jspstudy oracle,SQL不走索引的几种常见情况
- Redis 集群原理
- 部分英文常用口语单词(30%转贴+70%原创)
- esxi - 加装vmware titan xp显卡配置
- qt 批量裁剪图片_照片变素描,不用下载App,好用的在线图片处理及图库
- Fluent多相流之VOF模型操作实例
- openwrt安装USB声卡播放音乐
- 用HTML+CSS做成的一个简单网页(小兔鲜儿)
- 中国雅虎和美国雅虎,你分的清吗?