三维场景中用户常需要自定义绘制点线面对象,实现像桌面中的矢量数据的编辑和修改,因此本片文章主要讲讲,如何对绘制好的面对象的形状进行修改,大家可以参考本片文章实现点线数据的修改
思路
利用屏幕交互事件中的LEFT_DOWN事件,拾取到面对象,并计算左键拾取到的点坐标离拾取的面对象中的哪个节点更近。拿到最近的节点坐标,再结合鼠标移动事件,实现鼠标拖动坐标点更改面形状
一、构造面对象
http://support.supermap.com.cn:8090/webgl/examples/editor.html#drawHandler
将以上链接的示例提取出绘制面的代码,将绘制出来的结果构造一个面实体对象,注意面实体的坐标参数要给一个Cesium.PolygonHierarchy()类。
var clampMode = 0;
var tooltip = createTooltip(document.body);
var handlerPolygon = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Line, clampMode);
handlerPolygon.activeEvt.addEventListener(function(isActive) {
if (isActive == true) {
viewer.enableCursorStyle = false;
viewer._element.style.cursor = '';
$('body').removeClass('drawCur').addClass('drawCur');
} else {
viewer.enableCursorStyle = true;
$('body').removeClass('drawCur');
}
});
handlerPolygon.movingEvt.addEventListener(function(windowPosition) {
if (handlerPolygon.isDrawing) {
tooltip.showAt(windowPosition, '<p>点击确定多边形中间点</p><p>右键单击结束绘制</p>');
} else {
tooltip.showAt(windowPosition, '<p>点击绘制第一个点</p>');
}
});
handlerPolygon.drawEvt.addEventListener(function(result) {
//构造实体面
var polygon = viewer.entities.add({
polygon: {
hierarchy: new Cesium.PolygonHierarchy(result.object.positions),
material: Cesium.Color.WHITE,
perPositionHeight: true
}
})
tooltip.setVisible(false);
});
二、获取最近节点,更改节点坐标
结合鼠标点下的事件,获取到对象
var handbegin = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
var handm = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handbegin.setInputAction(function(e) {
var pro = scene.pick(e.position)//获取点击拾取到的对象
if (Cesium.defined(pro) && Cesium.defined(pro.id)) {
selectedPlane = pro.id.polygon;
var pos = selectedPlane.hierarchy._value.positions;
var shiqu = scene.pickPosition(e.position);//获取在场景中拾取的坐标
//计算最近的节点坐标
var min, imin, dis;
for (var i = 0; i < pos.length; i++) {
var dis = Cesium.Cartesian3.distance(shiqu, pos[i]);
if (i == 0) {
min = dis;
imin = 0;
} else if (dis < min) {
min = dis;
imin = i;
}
}
//关闭场景的拖动功能
scene.screenSpaceCameraController.enableInputs = false;
//鼠标移动事件,更改节点坐标
handm.setInputAction(function(e) {
var shiqum = scene.pickPosition(e.endPosition)
pos[imin] = shiqum;
selectedPlane.hierarchy = new Cesium.PolygonHierarchy(pos);
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
}
}, Cesium.ScreenSpaceEventType.LEFT_DOWN)
三、结束更改
var handend = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
//关闭鼠标移动事件,并打开场景的拖动事件
handend.setInputAction(function() {
handem.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
scene.screenSpaceCameraController.enableInputs = true;
}, Cesium.ScreenSpaceEventType.LEFT_UP)
结言
这个方法实现主要是结合屏幕交互事件来是实现,对于一些鼠标交互功能,使用ScreenSpaceEventHandler是一个很好的方法。完整示例代码在如下链接中
链接:https://pan.baidu.com/s/1g0-BvTK5MfEqkAEFGn04rw&shfl=sharepset
提取码:tta0