cesium-长度测量和面积测量
网上找的大神的实现方法有点问题,实现有一些bug,作为cesium新手一个,弃之不忍,只好硬着头皮修改了,不过还好问题不大,再次mark一下,下次就可以直接用了

import Cesium from "cesium/Cesium";
import widgets from "cesium/Widgets/widgets.css";
export default {
//测量空间直线距离
/******************************************* */
measureLineSpace(viewer, handler) {
// 取消双击事件-追踪该位置
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
var positions = [];
var poly = null;
// var tooltip = document.getElementById("toolTip");
var distance = 0;
var cartesian = null;
var floatingPoint;
// tooltip.style.display = "block";
handler.setInputAction(function (movement) {
// tooltip.style.left = movement.endPosition.x + 3 + "px";
// tooltip.style.top = movement.endPosition.y - 25 + "px";
// tooltip.innerHTML = '<p>单击开始,右击结束</p>';
// cartesian = viewer.scene.pickPosition(movement.endPosition);
let ray = viewer.camera.getPickRay(movement.endPosition);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
//cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
if (positions.length >= 2) {
if (!Cesium.defined(poly)) {
poly = new PolyLinePrimitive(positions);
} else {
positions.pop();
// cartesian.y += (1 + Math.random());
positions.push(cartesian);
}
distance = getSpaceDistance(positions);
// console.log("distance: " + distance);
// tooltip.innerHTML='<p>'+distance+'米</p>';
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(function (movement) {
// tooltip.style.display = "none";
// cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
// cartesian = viewer.scene.pickPosition(movement.position);
let ray = viewer.camera.getPickRay(movement.position);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
if (positions.length == 0) {
positions.push(cartesian.clone());
}
positions.push(cartesian);
//在三维场景中添加Label
// var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
var textDisance = distance + "米";
// console.log(textDisance + ",lng:" + cartographic.longitude/Math.PI*180.0);
floatingPoint = viewer.entities.add({
name: '空间直线距离',
// position: Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180,cartographic.height),
position: positions[positions.length - 1],
point: {
pixelSize: 5,
color: Cesium.Color.RED,
outlineColor: Cesium.Color.WHITE,
outlineWidth: 2,
},
label: {
text: textDisance,
font: '18px sans-serif',
fillColor: Cesium.Color.GOLD,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
pixelOffset: new Cesium.Cartesian2(20, -20),
}
});
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(function (movement) {
handler.destroy(); //关闭事件句柄
positions.pop(); //最后一个点无效
// viewer.entities.remove(floatingPoint);
// tooltip.style.display = "none";
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
var PolyLinePrimitive = (function () {
function _(positions) {
this.options = {
name: '直线',
polyline: {
show: true,
positions: [],
material: Cesium.Color.CHARTREUSE,
width: 10,
clampToGround: true
}
};
this.positions = positions;
this._init();
}
_.prototype._init = function () {
var _self = this;
var _update = function () {
return _self.positions;
};
//实时更新polyline.positions
this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
viewer.entities.add(this.options);
};
return _;
})();
//空间两点距离计算函数
function getSpaceDistance(positions) {
var distance = 0;
for (var i = 0; i < positions.length - 1; i++) {
var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
/**根据经纬度计算出距离**/
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));
distance = distance + s;
}
return distance.toFixed(2);
}
},
//****************************测量空间面积************************************************//
measureAreaSpace(viewer, handler){
// 取消双击事件-追踪该位置
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
// 鼠标事件
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
var positions = [];
var tempPoints = [];
var polygon = null;
// var tooltip = document.getElementById("toolTip");
var cartesian = null;
var floatingPoint;//浮动点
// tooltip.style.display = "block";
handler.setInputAction(function(movement){
// tooltip.style.left = movement.endPosition.x + 3 + "px";
// tooltip.style.top = movement.endPosition.y - 25 + "px";
// tooltip.innerHTML ='<p>单击开始,右击结束</p>';
// cartesian = viewer.scene.pickPosition(movement.endPosition);
let ray = viewer.camera.getPickRay(movement.endPosition);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
//cartesian = viewer.scene.camera.pickEllipsoid(movement.endPosition, viewer.scene.globe.ellipsoid);
if(positions.length >= 2){
if (!Cesium.defined(polygon)) {
polygon = new PolygonPrimitive(positions);
}else{
positions.pop();
// cartesian.y += (1 + Math.random());
positions.push(cartesian);
}
// tooltip.innerHTML='<p>'+distance+'米</p>';
}
},Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(function(movement){
// tooltip.style.display = "none";
// cartesian = viewer.scene.pickPosition(movement.position);
let ray = viewer.camera.getPickRay(movement.position);
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
// cartesian = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid);
if(positions.length == 0) {
positions.push(cartesian.clone());
}
//positions.pop();
positions.push(cartesian);
//在三维场景中添加点
var cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);
var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
var heightString = cartographic.height;
tempPoints.push({ lon: longitudeString, lat: latitudeString ,hei:heightString});
floatingPoint = viewer.entities.add({
name : '多边形面积',
position : positions[positions.length - 1],
point : {
pixelSize : 5,
color : Cesium.Color.RED,
outlineColor : Cesium.Color.WHITE,
outlineWidth : 2,
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND
}
});
},Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(function(movement){
handler.destroy();
positions.pop();
//tempPoints.pop();
// viewer.entities.remove(floatingPoint);
// tooltip.style.display = "none";
//在三维场景中添加点
// var cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);
// var longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
// var latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
// var heightString = cartographic.height;
// tempPoints.push({ lon: longitudeString, lat: latitudeString ,hei:heightString});
var textArea = getArea(tempPoints) + "平方公里";
viewer.entities.add({
name : '多边形面积',
position : positions[positions.length - 1],
// point : {
// pixelSize : 5,
// color : Cesium.Color.RED,
// outlineColor : Cesium.Color.WHITE,
// outlineWidth : 2,
// heightReference:Cesium.HeightReference.CLAMP_TO_GROUND
// },
label : {
text : textArea,
font : '18px sans-serif',
fillColor : Cesium.Color.GOLD,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineWidth : 2,
verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
pixelOffset : new Cesium.Cartesian2(20, -40),
heightReference:Cesium.HeightReference.CLAMP_TO_GROUND
}
});
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK );
var radiansPerDegree = Math.PI / 180.0;//角度转化为弧度(rad)
var degreesPerRadian = 180.0 / Math.PI;//弧度转化为角度
//计算多边形面积
function getArea(points) {
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(positions[i], positions[j]);
var dis_temp2 = distance(positions[j], positions[k]);
res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle)) ;
console.log(res);
}
return (res/1000000.0).toFixed(4);
}
/*角度*/
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) {
var lat1 = from.lat * radiansPerDegree;
var lon1 = from.lon * radiansPerDegree;
var lat2 = to.lat * radiansPerDegree;
var lon2 = to.lon * radiansPerDegree;
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;
}
var PolygonPrimitive = (function(){
function _(positions){
this.options = {
name:'多边形',
polygon : {
hierarchy : [],
// perPositionHeight : true,
material : Cesium.Color.GREEN.withAlpha(0.5),
// heightReference:20000
}
};
this.hierarchy = positions;
this._init();
}
_.prototype._init = function(){
var _self = this;
var _update = function(){
return _self.hierarchy;
};
//实时更新polygon.hierarchy
this.options.polygon.hierarchy = new Cesium.CallbackProperty(_update,false);
viewer.entities.add(this.options);
};
return _;
})();
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;
}
}
}
cesium-长度测量和面积测量的更多相关文章
- Cesium 绘制点、线、面和测距
本文基于ES6,采用React+Cesium的Webgis前端开发框架,目前threejs和cesium的结合正在研究中.此段代码采用原生javascript,可能过程中用到了es6的扁平化语法,如( ...
- cesium入门示例-测量工具
作为cesium入门示例级别的最后一篇,参考cesium-长度测量和面积测量实现测量工具封装,修改了其中的距离测量函数,计算贴地距离,并对事件内部处理做了调整.包括贴地距离测量.面积测量.结果清除. ...
- Cesium参考资源
Reference resources cesium官网 cesium 下载 cesium官方文档 APIs cesium-workshop github cesium 官方示例 cesium git ...
- cesium自定义气泡窗口infoWindow
一.自定义气泡窗口与cesium默认窗口效果对比: 1.cesium点击弹出气泡窗口显示的位置固定在地图的右上角,默认效果: 2.对于习惯arcgis或者openlayer气泡窗口样式的giser来说 ...
- cesium核心类Viewer简介
1.简单描述Viewer Viewer类是cesium的核心类,是地图可视化展示的主窗口,cesium程序应用的切入口,扮演必不可少的核心角色. 官网的英文解析如下: A base widget fo ...
- Cesium简介以及离线部署运行
Cesium简介 cesium是国外一个基于JavaScript编写的使用WebGL的地图引擎,一款开源3DGIS的js库.cesium支持3D,2D,2.5D形式的地图展示,可以自行绘制图形,高亮区 ...
- Cesium教程系列汇总
Cesium系列目录: 应用篇 入门 Cesium应用篇:1快速搭建 影像 Cesium应用篇:2影像服务(上) Cesium应用篇:2影像服务(下) 控件 Cesium应用篇:3控件(1)Clock ...
- Cesium原理篇:GroundPrimitive
今天来看看GroundPrimitive,选择GroundPrimitive有三个目的:1 了解GroundPrimitive和Primitive的区别和关系 2 createGeometry的特殊处 ...
- Cesium原理篇:Batch
通过之前的Material和Entity介绍,不知道你有没有发现,当我们需要添加一个rectangle时,有两种方式可供选择,我们可以直接添加到Scene的PrimitiveCollection,也可 ...
- Cesium原理篇:Material
Shader 首先,在本文开始前,我们先普及一下材质的概念,这里推荐材质,普及材质的内容都是截取自该网站,我觉得他写的已经够好了.在开始普及概念前,推荐一首我此刻想到的歌<光---陈粒>. ...
随机推荐
- IK的整个分词处理过程
首先,介绍一下IK的整个分词处理过程: 1. Lucene的分词基类是Analyzer,所以IK提供了Analyzer的一个实现类IKAnalyzer.首先,我们要实例化一个IKAnalyzer,它有 ...
- Unity实现Android端视频播放
本文只讲Android短的视频播放 实现方式 使用Handheld.PlayFullScreenMovie(),这个函数实现.具体如下: 1.创建StreamingAssets文件夹,此文件夹放入视频 ...
- DIV+CSS网页布局常用的一些基础知识
CSS命名规范 一.文件命名规范 全局样式:global.css:框架布局:layout.css:字体样式:font.css:链接样式:link.css:打印样式:print.css: 二.常用类/I ...
- JS事件 编程练习-自制计算器 使用JS完成一个简单的计算器功能。实现2个输入框中输入整数后,点击第三个输入框能给出2个整数的加减乘除。
编程练习 使用JS完成一个简单的计算器功能.实现2个输入框中输入整数后,点击第三个输入框能给出2个整数的加减乘除. 提示:获取元素的值设置和获取方法为:例:赋值:document.getElement ...
- js 本地预览图片和得到图片实际大小
//填充预览图片 function adpter(file, upfile) { var imgName = new Date().getTime() + file.name.substr(file. ...
- js 高级 原型与原型链
* 所有函数都有一个特别的属性: * `prototype` : 显式原型属性* 所有实例对象都有一个特别的属性: * `__proto__` : 隐式原型属性 1. 每个函数都有一个prototy ...
- COGS2353 【HZOI2015】有标号的DAG计数 I
题面 题目描述 给定一正整数n,对n个点有标号的有向无环图(可以不连通)进行计数,输出答案mod 10007的结果 输入格式 一个正整数n 输出格式 一个数,表示答案 样例输入 3 样例输出 25 提 ...
- 【JZOJ4905】【BZOJ4720】【luoguP1850】换教室
description 对于刚上大学的牛牛来说,他面临的第一个问题是如何根据实际情况申请合适的课程.在可以选择的课程中,有2n节课程安排在n个时间段上.在第i(1≤i≤n)个时间段上,两节内容相同的课 ...
- XML、JSON、ProtocolBuffer特点比较
XML JSON PB Lua 数据结构支持 复杂结构 简单结构 较复杂结构 复杂结构 数据保存方式 文本 文本 二进制 文本 数据保存大小 大 一般 小 一般 解析效率 慢 一般 快 稍快 语言支持 ...
- Python collection模块与深浅拷贝
collection模块是对Python的通用内置容器:字典.列表.元组和集合的扩展,它包含一些专业的容器数据类型: Counter(计数器):dict子类,用于计算可哈希性对象的个数. Ordere ...