参考geojson.io网站用cesium实现自定义编辑多边形功能
绘制多边形
在cesium官方所给的实例中,Drawing on Terrain中可以做到自定义绘制多边形,但无法做到修改编辑,因此分享下实现编辑功能的思路。
在官方的实例中,绘制多边形的核心代码为:
handler.setInputAction(function (event) {
// We use `viewer.scene.pickPosition` here instead of `viewer.camera.pickEllipsoid` so that
// we get the correct point when mousing over terrain.
var earthPosition = viewer.scene.pickPosition(event.position);
// `earthPosition` will be undefined if our mouse is not over the globe.
if (Cesium.defined(earthPosition)) {
if (activeShapePoints.length === 0) {
floatingPoint = createPoint(earthPosition);
activeShapePoints.push(earthPosition);
var dynamicPositions = new Cesium.CallbackProperty(function () {
if (drawingMode === "polygon") {
return new Cesium.PolygonHierarchy(activeShapePoints);
}
return activeShapePoints;
}, false);
activeShape = drawShape(dynamicPositions);
}
activeShapePoints.push(earthPosition);
createPoint(earthPosition);
}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
handler.setInputAction(function (event) {
if (Cesium.defined(floatingPoint)) {
var newPosition = viewer.scene.pickPosition(event.endPosition);
if (Cesium.defined(newPosition)) {
floatingPoint.position.setValue(newPosition);
activeShapePoints.pop();
activeShapePoints.push(newPosition);
}
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
// Redraw the shape so it's not dynamic and remove the dynamic shape.
function terminateShape() {
activeShapePoints.pop();
drawShape(activeShapePoints);
viewer.entities.remove(floatingPoint);
viewer.entities.remove(activeShape);
floatingPoint = undefined;
activeShape = undefined;
activeShapePoints = [];
}
handler.setInputAction(function (event) {
terminateShape();
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
通过绑定左键的点击事件,实现左键点击获取多边形的顶点坐标,数组activeShapePoints保存绘制的多边形的顶点坐标,通过回调函数实现动态绘制。
var dynamicPositions = new Cesium.CallbackProperty(function () {
if (drawingMode === "polygon") {
return new Cesium.PolygonHierarchy(activeShapePoints);
}
return activeShapePoints;
}, false);
activeShape = drawShape(dynamicPositions);
而点击右键后去除activeShape 动态绘制的多边形,按照顶点坐标数组重新绘制静态的多边形。
// Redraw the shape so it's not dynamic and remove the dynamic shape.
function terminateShape() {
activeShapePoints.pop();
drawShape(activeShapePoints);
viewer.entities.remove(floatingPoint);
viewer.entities.remove(activeShape);
floatingPoint = undefined;
activeShape = undefined;
activeShapePoints = [];
}
handler.setInputAction(function (event) {
terminateShape();
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
编辑多边形
编辑多边形功能主要分为:
- 编辑现有多边形顶点;
- 增加多边形顶点;
为了实现这两个功能,首先我们需要在动态多边形上进行操作,因此需保留动态绘制的多边形activeShape。并且还需保存各顶点位置上添加的点实体。
1、编辑现有多边形顶点;
实现编辑现有多边形顶点主要通过viewer.scene.pick();
通过pick顶点的点实体将坐标点赋值给entity的position属性实现改变顶点的点实体位置,并将activeShapePoints数组中相应的坐标点数据进行更新。
2、增加多边形顶点
该功能主要思路是在绘制多边形后,两两顶点的中点位置需要添加可编辑点实体。
function draw_midpoint(){
var midposition:any;
for(let i=0;i<activeShapePoints.length;i++){
if(i+1 === activeShapePoints.length){
midposition = Cesium.Cartesian3.midpoint(activeShapePoints[i],activeShapePoints[0],new Cesium.Cartesian3());
}else{
midposition = Cesium.Cartesian3.midpoint(activeShapePoints[i],activeShapePoints[i+1],new Cesium.Cartesian3());
}
midpointArr[i]=viewer.entities.add({
position: midposition,
point: {
pixelSize: 5,
color: Cesium.Color.YELLOW.withAlpha(0.3),
outlineWidth: 2,
outlineColor: Cesium.Color.DARKRED.withAlpha(0.3),
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
disableDepthTestDistance: Number.POSITIVE_INFINITY
},
show: false,
description: i,
});
}
console.log(midpointArr);
}
这样在绘制完成后将会添加半透明的待编辑点实体,在编辑多边形时,点击待编辑点实体后,将其坐标插入到activeShapePoints数组的相应位置,且按照相同的思路添加新的待编辑点实体。注意的是,在后续添加及修改时需注意数组两端的数据位置。
最后先实现效果如下