剛剛分享了地形開挖膜楷,覺得可能大部分業(yè)務(wù)是自定義多邊形砾嫉,然后開挖抡砂,基于此大咱,分享自定義繪制多邊形函數(shù),引入即可使用
// 構(gòu)造唯一id
import { v4 as uuidv4 } from 'uuid';
// 坐標(biāo)轉(zhuǎn)化
const getLonLatFromCartesian = (cartesian3) => {
const { longitude, latitude, height } = Cesium.Cartographic.fromCartesian(cartesian3);
return {
lng: +Cesium.Math.toDegrees(longitude),
lat: +Cesium.Math.toDegrees(latitude),
height: +height
}
};
// 創(chuàng)建點(diǎn)
const createPoint = (viewer, Cartesian, options) => {
const { lng, lat, height } = getLonLatFromCartesian(Cartesian)
return viewer.entities.add({
position: new Cesium.Cartesian3.fromDegrees(lng, lat, height),
point: {
pixelSize: options.pixelSize,
color: options.pointColor
}
})
};
// 繪制多邊形
const DrawPolygon = (viewer, options = {}, callback) => {
if (!viewer) throw new Error("no viewer object!");
options = {
id: uuidv4(),
pointColor: Cesium.Color.fromCssColorString('#FFC107'),
pixelSize: 8,
outlineWidth: 5,
outlineColor: new Cesium.Color(0, 64 / 255, 133 / 255, 0.8),
color: Cesium.Color.fromCssColorString('rgba(0, 123, 255, 0.4)'),
...options
};
if (viewer.entities.getById(options.id)) {
throw new Error("the id is an unique value");
}
const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
let activeShapePoints = [];
let polygon = undefined;
let floatingPoint = undefined;
// 鼠標(biāo)左擊事件
handler.setInputAction((event) => {
let ray = viewer.camera.getPickRay(event.position);
let earthPosition = viewer.scene.globe.pick(ray, viewer.scene);
// 鼠標(biāo)開始點(diǎn)擊多邊形的第一個(gè)點(diǎn)
if (activeShapePoints.length === 0) {
floatingPoint = createPoint(viewer, earthPosition, options);
// 將第一個(gè)左擊的點(diǎn)添加到多邊形頂點(diǎn)集合中
activeShapePoints.push(earthPosition);
// 多邊形的坐標(biāo)采用回調(diào)的形式
// 多邊形邊界頂點(diǎn)
let polylinePoints = new Cesium.CallbackProperty(() => {
let vertexPoints = activeShapePoints.concat([activeShapePoints[0]]);
return vertexPoints;
}, false);
// 多邊形頂點(diǎn)
let dynamicPositions = new Cesium.CallbackProperty(() => {
return new Cesium.PolygonHierarchy(activeShapePoints);
}, false);
// 添加一個(gè)多邊形
polygon = viewer.entities.add({
name: "customPolygon",
id: options.id,
polyline: {
positions: polylinePoints,
width: options.outlineWidth,
material: options.outlineColor,
clampToGround: true,
},
polygon: {
hierarchy: dynamicPositions,
material: options.color,
heightReference: Cesium.HeightReference.NONE,
},
});
}
// 將鼠標(biāo)點(diǎn)擊的點(diǎn)添加到多邊形頂點(diǎn)集合中
activeShapePoints.push(earthPosition);
// 記錄多邊形邊界的點(diǎn)
polygon.outLinePoint = (polygon.outLinePoint ?? []).concat(createPoint(viewer, earthPosition, options));
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
// 鼠標(biāo)移動(dòng)事件
handler.setInputAction((movement) => {
// 獲取鼠標(biāo)所在的位置
const ray = viewer.camera.getPickRay(movement.endPosition);
const newPosition = viewer.scene.globe.pick(ray, viewer.scene);
// 已經(jīng)定義了polygon
if (Cesium.defined(polygon)) {
floatingPoint.position.setValue(newPosition);
// 刪除多邊形頂點(diǎn)中最新的一個(gè)點(diǎn)
activeShapePoints.pop();
// 將最新獲取到的點(diǎn)添加到多邊形頂點(diǎn)集合中
activeShapePoints.push(newPosition);
}
if (activeShapePoints.length === 3) {
polygon.polygon.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(() => {
// 刪除最后一個(gè)點(diǎn)(重復(fù)添加的點(diǎn))
activeShapePoints.pop();
polygon.pottingPoint = activeShapePoints;
viewer.entities.remove(floatingPoint);
floatingPoint = undefined;
// 銷毀右擊事件
handler.destroy();
if (typeof callback === "function") callback(polygon);
}, Cesium.ScreenSpaceEventType.RIGHT_DOWN);
};
export default DrawPolygon;
使用方法
DrawPolygon(this.viewer, {}, (polygon) => {
console.log(polygon)
})
效果圖