使用方法新建一个文件measureArea.js将下面代码贴上去
// DrawPolygon
/*
绘制面(面积测量)*/class measureArea {constructor(arg) {this.objId = Number(new Date().getTime() + "" + Number(Math.random() * 1000).toFixed(0));this.viewer = arg.viewer;this.Cesium = arg.Cesium;this.callback = arg.callback;this._polygon = null; //活动面this._polygonLast = null; //最后一个面this._positions = []; //活动点this._entities_point = []; //脏数据this._entities_polygon = []; //脏数据this._polygonData = null; //用户构造面}//返回最后活动面get polygon() {return this._polygonLast;}//返回面数据用于加载面getData() {return this._polygonData;}//加载面loadPolygon(data) {var $this = this;return this.viewer.entities.add({polygon: {hierarchy: new $this.Cesium.PolygonHierarchy(data),clampToGround: true,show: true,fill: true,material: $this.Cesium.Color.RED.withAlpha(0.5),width: 3,outlineColor: $this.Cesium.Color.BLACK,outlineWidth: 1,outline: false,classificationType: Cesium.ClassificationType.BOTH // 支持类型: 地形、3DTile、或者在地面上}});}//开始绘制startCreate() {var $this = this;this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);this.handler.setInputAction(function(evt) {//单机开始绘制var cartesian = $this.getCatesian3FromPX(evt.position);if ($this._positions.length == 0) {$this._positions.push(cartesian.clone());}if (cartesian) {$this.createPoint(cartesian);$this._positions.push(cartesian);}}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);this.handler.setInputAction(function(evt) {//移动时绘制面if ($this._positions.length < 1) return;var cartesian = $this.getCatesian3FromPX(evt.endPosition);if ($this._positions.length == 3) {if (!$this.Cesium.defined($this._polygon)) {$this._polygon = $this.createPolygon();}}if (cartesian) {$this._positions.pop();$this._positions.push(cartesian);}}, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);this.handler.setInputAction(function(evt) {if (!$this._polygon) return;var cartesian = $this.getCatesian3FromPX(evt.position);$this._positions.pop();$this._positions.push(cartesian);$this.createPoint(cartesian);$this._polygonData = $this._positions.concat();$this.viewer.entities.remove($this._positions); //移除$this._positions = null;$this._positions = [];var Polygon = $this.loadPolygon($this._polygonData);$this._entities_polygon.push(Polygon);$this._polygonLast = Polygon;var textArea = $this.getArea($this._polygonData) + "平方米";$this.createPointLabel($this._polygonData[$this._polygonData.length - 1],textArea);$this.destroy();if (typeof $this.callback == "function") {$this.callback(cartesian);}}, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);}//创建面createPolygon() {var $this = this;var polygon = this.viewer.entities.add({polygon: {hierarchy: new $this.Cesium.CallbackProperty(function() {return new $this.Cesium.PolygonHierarchy($this._positions);}, false),clampToGround: true,show: true,fill: true,material: $this.Cesium.Color.RED.withAlpha(0.5),width: 3,outlineColor: $this.Cesium.Color.BLACK,outlineWidth: 1,outline: false}});$this._entities_polygon.push(polygon);return polygon;}//创建点createPoint(cartesian) {var $this = this;var point = this.viewer.entities.add({position: cartesian,point: {pixelSize: 10,color: $this.Cesium.Color.YELLOW,disableDepthTestDistance: Number.POSITIVE_INFINITY, //被遮罩classificationType: Cesium.ClassificationType.BOTTOM}});point.objId = this.objId;$this._entities_point.push(point);return point;}//创建点createPointLabel(cartesian, textArea) {var $this = this;var point = this.viewer.entities.add({position: cartesian,label: {text: textArea,font: "18px sans-serif",fillColor: $this.Cesium.Color.GOLD,style: $this.Cesium.LabelStyle.FILL_AND_OUTLINE,outlineWidth: 2,disableDepthTestDistance: Number.POSITIVE_INFINITY, //被遮罩classificationType: Cesium.ClassificationType.BOTTOM,verticalOrigin: $this.Cesium.VerticalOrigin.BOTTOM,pixelOffset: new $this.Cesium.Cartesian2(20, -40),heightReference: $this.Cesium.HeightReference.CLAMP_TO_GROUND}});point.objId = this.objId;$this._entities_point.push(point);return point;}//销毁事件destroy() {if (this.handler) {this.handler.destroy();this.handler = null;}}//清空实体对象clear() {for (var i = 0; i < this._entities_point.length; i++) {this.viewer.entities.remove(this._entities_point[i]);}for (var i = 0; i < this._entities_polygon.length; i++) {this.viewer.entities.remove(this._entities_polygon[i]);}this._polygon = null; //活动面this._polygonLast = null; //最后一个面this._positions = []; //活动点this._entities_point = []; //脏数据this._entities_polygon = []; //脏数据this._polygonData = null; //用户构造面}getCatesian3FromPX(px) {var cartesian;cartesian = this.viewer.scene.pickPosition(px);return cartesian;}//计算多边形面积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 = this.Angle(points[i], points[j], points[k]);var dis_temp1 = this.distance(points[i], points[j]);var dis_temp2 = this.distance(points[j], points[k]);res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle));}return res;}/*角度*/Angle(p1, p2, p3) {var bearing21 = this.Bearing(p2, p1);var bearing23 = this.Bearing(p2, p3);var angle = bearing21 - bearing23;if (angle < 0) {angle += 360;}return angle;}/*方向*/Bearing(from, to) {var radiansPerDegree = Math.PI / 180.0; //角度转化为弧度(rad)var degreesPerRadian = 180.0 / Math.PI; //弧度转化为角度var cartographic_from = this.Cesium.Cartographic.fromCartesian(from);var cartographic_to = this.Cesium.Cartographic.fromCartesian(to);var lon_from = this.Cesium.Math.toDegrees(cartographic_from.longitude);var lat_from = this.Cesium.Math.toDegrees(cartographic_from.latitude);var lon_to = this.Cesium.Math.toDegrees(cartographic_to.longitude);var lat_to = this.Cesium.Math.toDegrees(cartographic_to.latitude);var lat1 = lat_from * radiansPerDegree;var lon1 = lon_from * radiansPerDegree;var lat2 = lat_to * radiansPerDegree;var lon2 = lon_to * 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;}distance(point1, point2) {var point1cartographic = this.Cesium.Cartographic.fromCartesian(point1);var point2cartographic = this.Cesium.Cartographic.fromCartesian(point2);/**根据经纬度计算出距离**/var geodesic = new this.Cesium.EllipsoidGeodesic();geodesic.setEndPoints(point1cartographic, point2cartographic);var s = geodesic.surfaceDistance;//返回两点之间的距离s = Math.sqrt(Math.pow(s, 2) +Math.pow(point2cartographic.height - point1cartographic.height, 2));return s;}
}export default measureArea;
使用方法如下:
import measureArea from "@/assets/js/measureArea.js";
let measureAreas = new measureArea({viewer: window.viewer,Cesium: Cesium});measureAreas.startCreate();
效果图