cesium空间面积测量,取点比较准,数据不是很准,但是差不太多

参考了:
https://blog.csdn.net/qq_27532167/article/details/83346893
这个文章画多边形取点准确,但是我画出来的面积数据差太多,不知道是不是我的用法不对,面积差好几倍。
https://blog.csdn.net/qq_18144905/article/details/81947780
主要取的这篇文章的算法,这个获取的面积比较接近真实面积。

measureArea() {
				var viewer = this.viewer
				var tooltip = document.getElementById("ToolTip");
				var isDraw = false;
				var positions = [];
				var polygon = null;
				var tempPoints = [];
				var handler = viewer.screenSpaceEventHandler;
				handler.setInputAction(function (movement) {
					//新增部分
					var position1;
					var cartographic;
					var ray = viewer.scene.camera.getPickRay(movement.endPosition);
					if (ray)
						position1 = viewer.scene.globe.pick(ray, viewer.scene);
					if (position1)
						cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position1);
					if (cartographic) {
						//海拔
						var height = viewer.scene.globe.getHeight(cartographic);
						var point = Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180, height);
						if (isDraw) {
							tooltip.style.left = movement.endPosition.x + 10 + "px";
							tooltip.style.top = movement.endPosition.y + 20 + "px";
							tooltip.style.display = "block";

							if (positions.length < 2) {
								return;
							}
							if (!Cesium.defined(polygon)) {
								positions.push(point);
								polygon = new CreatePolygon(positions, Cesium);
							} else {
								polygon.path.pop();
								polygon.path.push(point);
							}
							if (positions.length >= 2) {
								tooltip.innerHTML = '<p>双击确定终点</p>';
							}
						}
					}

				}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
				handler.setInputAction(function (movement) {
					isDraw = true;
					//新增部分
					var position1;
					var cartographic;
					var ray = viewer.scene.camera.getPickRay(movement.position);
					if (ray)
						position1 = viewer.scene.globe.pick(ray, viewer.scene);
					if (position1)
						cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(position1);
					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});
					if (cartographic) {
						//海拔
						var height = viewer.scene.globe.getHeight(cartographic);
						var point = Cesium.Cartesian3.fromDegrees(cartographic.longitude / Math.PI * 180, cartographic.latitude / Math.PI * 180, height);
						if (isDraw) {
							positions.push(position1);
							var tmep = viewer.entities.add({
								position: point,
								point: {
									show: true,
									color: Cesium.Color.SKYBLUE,
									pixelSize: 3,
									outlineColor: Cesium.Color.YELLOW,
									outlineWidth: 1
								},
							});
						}
					}
				}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
				handler.setInputAction(function () {
					handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
					handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

					if (positions.length >= 2) {
						var label = getArea(tempPoints);
						// var label = String(countAreaInCartesian3(polygon.path));
						label = label.substr(0, label.indexOf(".", 0));
						var text;
						if (label.length < 6)
							text = label + "平方米";
						else {
							label = String(label / 1000000);
							label = label.substr(0, label.indexOf(".", 0) + 3);
							text = label + "平方公里"
						}
						var textArea = text;
						var lastpoint = viewer.entities.add({
							name: '多边形面积',
							position: polygon.path[polygon.path.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)
							}
						});
					}
					viewer.trackedEntity = undefined;
					isDraw = false;
					tooltip.style.display = 'none';

				}, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

				var CreatePolygon = (function () {
					function _(positions, cesium) {
						if (!Cesium.defined(positions)) {
							throw new Cesium.DeveloperError('positions is required!');
						}
						if (positions.length < 3) {
							throw new Cesium.DeveloperError('positions 的长度必须大于等于3');
						}

						this.options = {
							polygon: {
								hierarchy: undefined,
								outline: true,
								material: Cesium.Color.RED.withAlpha(0.4)
							}
						};
						this.path = positions;
						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);
						var oo = viewer.entities.add(this.options);
					};
					return _;
				})();

				//微元法求面积
				var countAreaInCartesian3 = function (ps) {
					var s = 0;
					for (var i = 0; i < ps.length; i++) {
						var p1 = ps[i];
						var p2;
						if (i < ps.length - 1)
							p2 = ps[i + 1];
						else
							p2 = ps[0];
						s += p1.x * p2.y - p2.x * p1.y;
					}
					return Math.abs(s);
				};
				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.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;
				}

			},
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值