使用方法新建一个文件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();
效果图