需要安装
在页面中引入
AreaUse() {
const viewer = QJViewer;
const _this = this;
var positions = [];
var height = undefined;
var polygonEntity = undefined;
var mesureResultEntity = undefined;
var tempPositions = [];
// 测量功能激活
var isMeasure = true;
_this.$message({
message: "开始计算面积,右键结束计算",
type: "success",
customClass: "message",
});
unRegisterEvents();
//创建面对象
function createPolygonEntity() {
polygonEntity = viewer.entities.add({
polygon: {
hierarchy: new Cesium.CallbackProperty((event) => {
return new Cesium.PolygonHierarchy(tempPositions);
//使用最新1.72的时候 必须返回PolygonHierarchy类型 Cannot read property 'length' of undefined
//低版本好像都可以
}, false),
material: Cesium.Color.RED.withAlpha(0.4),
perPositionHeight: true, //
},
polyline: {
positions: new Cesium.CallbackProperty((event) => {
return tempPositions.concat(tempPositions[0]);
}, false),
width: 1,
material: new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.YELLOW,
}),
depthFailMaterial: new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.YELLOW,
}),
},
});
_this.AreaEntities.push(polygonEntity);
}
// 创建起点
function createStartEntity() {
let vertexEntity = viewer.entities.add({
position: positions[0],
type: "MeasureDistanceVertex",
point: {
color: Cesium.Color.FUCHSIA,
pixelSize: 6,
},
});
_this.AreaEntities.push(vertexEntity);
}
// 创建节点
function createVertex() {
let vertexEntity = viewer.entities.add({
position: positions[positions.length - 1],
type: "MeasureAreaVertex",
point: {
color: Cesium.Color.FUCHSIA,
pixelSize: 8,
disableDepthTestDistance: 500,
},
});
_this.AreaEntities.push(vertexEntity);
}
//统一节点的高度
function unifiedHeight(positions, height) {
if (!height) height = getPositionHeight(positions[0]); //如果没有指定高度 就用第一个的高度
let point3d;
for (let i = 0; i < positions.length; i++) {
const element = positions[i];
point3d = cartesian3ToPoint3D(element);
positions[i] = Cesium.Cartesian3.fromDegrees(
point3d.x,
point3d.y,
height
);
}
return height;
}
//获取某个点的高度
function getPositionHeight(position) {
const cartographic = Cesium.Cartographic.fromCartesian(position);
return cartographic.height;
}
// 将 Cesium 的 Cartesian3 类型的位置坐标转换为一个更易于理解和处理的经纬度坐标对象
function cartesian3ToPoint3D(position) {
const cartographic = Cesium.Cartographic.fromCartesian(position);
const lon = Cesium.Math.toDegrees(cartographic.longitude);
const lat = Cesium.Math.toDegrees(cartographic.latitude);
return { x: lon, y: lat, z: cartographic.height };
}
// 计算面积
function computeArea(positions) {
let s = 0;
let p1 = 0;
let p2 = 0;
for (let i = 0; i < positions.length; ++i) {
p1 = positions[i];
let j = (i + 1) % positions.length;
p2 = positions[j];
s += p1.x * p2.y;
s -= p2.x * p1.y;
}
return Math.abs(s / 2 / 1000000.0).toFixed(6);
}
//测量结果标签
function createResultLabel() {
mesureResultEntity = viewer.entities.add({
position: new Cesium.CallbackProperty((event) => {
return getCenterPosition();
}, false),
type: "MeasureAreaResult",
label: {
text: new Cesium.CallbackProperty((event) => {
return "面积" + computeArea(tempPositions) + "km²";
}, false),
scale: 0.5,
font: "normal 28px MicroSoft YaHei",
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 5000),
scaleByDistance: new Cesium.NearFarScalar(1000, 1, 3000, 1),
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
// pixelOffset: new Cesium.Cartesian2(0, -30),
outlineWidth: 9,
outlineColor: Cesium.Color.YELLOW,
},
});
_this.AreaEntities.push(mesureResultEntity);
}
//获取节点的中心点
function getCenterPosition() {
let points = [];
if (tempPositions.length < 3) return tempPositions[0];
tempPositions.forEach((position) => {
const point3d = cartesian3ToPoint3D(position);
points.push([point3d.x, point3d.y]);
});
// 构建turf.js lineString
let geo = turf.lineString(points);
let bbox = turf.bbox(geo);
let bboxPolygon = turf.bboxPolygon(bbox);
let pointOnFeature = turf.center(bboxPolygon);
let lonLat = pointOnFeature.geometry.coordinates;
console.log(444);
return Cesium.Cartesian3.fromDegrees(
lonLat[0],
lonLat[1],
height + 0.3
);
}
//禁用
function deactivate() {
if (!isMeasure) return;
unRegisterEvents();
viewer._element.style.cursor = "pointer";
viewer.enableCursorStyle = true;
isMeasure = false;
tempPositions = [];
positions = [];
height = undefined;
}
// 清除
function clear() {
//清除线对象
viewer.entities.remove(polygonEntity);
polygonEntity = undefined;
//清除节点
_this.AreaEntities.forEach((item) => {
viewer.entities.remove(item);
});
_this.AreaEntities = [];
viewer.entities.remove(mesureResultEntity);
mesureResultEntity = undefined;
height = undefined;
}
// 解除鼠标事件
function unRegisterEvents() {
viewer.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.LEFT_CLICK
);
viewer.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.RIGHT_CLICK
);
viewer.screenSpaceEventHandler.removeInputAction(
Cesium.ScreenSpaceEventType.MOUSE_MOVE
);
}
//左键点击事件
viewer.screenSpaceEventHandler.setInputAction(function (event) {
viewer._element.style.cursor = "crosshair";
// 获取鼠标点击位置的屏幕坐标
var ray = viewer.camera.getPickRay(event.position);
if (!ray) return null;
var earthPosition = viewer.scene.globe.pick(ray, viewer.scene);
if (Cesium.defined(earthPosition)) {
const ellipsoid = viewer.scene.globe.ellipsoid;
earthPosition = viewer.scene.camera.pickEllipsoid(
event.position,
ellipsoid
);
}
if (!earthPosition) return;
positions.push(earthPosition);
height = unifiedHeight(positions, height);
if (positions.length == 1) {
//首次点击
createPolygonEntity();
createStartEntity();
}
createVertex();
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// 鼠标移动事件
viewer.screenSpaceEventHandler.setInputAction(function (event) {
if (!isMeasure) return;
viewer._element.style.cursor = "crosshair";
// 获取鼠标点击位置的屏幕坐标
var ray = viewer.camera.getPickRay(event.endPosition);
if (!ray) return null;
var earthPosition = viewer.scene.globe.pick(ray, viewer.scene);
if (earthPosition) {
earthPosition = viewer.scene.camera.pickEllipsoid(
event.startPosition,
viewer.scene.globe.ellipsoid
);
}
if (!earthPosition) return;
if (positions.length < 1) return;
height = unifiedHeight(positions, height);
tempPositions = positions.concat(earthPosition);
if (tempPositions.length >= 3 && !mesureResultEntity) {
createResultLabel();
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// 鼠标右键事件
viewer.screenSpaceEventHandler.setInputAction(function (event) {
// console.log(event);
if (!isMeasure || positions.length < 3) {
deactivate();
clear();
} else {
tempPositions = [...positions];
polygonEntity.polyline = {
positions: positions.concat(positions[0]),
width: 2,
material: Cesium.Color.YELLOW,
depthFailMaterial: new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.YELLOW,
}),
};
polygonEntity.polygon.hierarchy = new Cesium.PolygonHierarchy(
tempPositions
);
mesureResultEntity.position = getCenterPosition();
mesureResultEntity.label.text =
"总面积" + computeArea(positions) + "km²";
deactivate();
}
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
},