我写的这个点线面绘制融入了增删改的功能。
其中可以通过手动点击地图进行动态绘制线面,也支持通过给定坐标数组来进行线面的增加。
绘制好的线面,可以点击进行修改;
以上介绍了我的大概的要给操作,下面以面的构建来进行代码解释;
cesium中想动态构建线面,离不开的一个属性就是CallbackProperty。
以下是部分核心代码:
1、构建面核心代码
此处面的postions用了callbackproperty,就可以进行动态绘制了,关于property的讲解可以参阅:https://www.jianshu.com/p/f0b47997224c
createPolygon: function(obj) {
var $this = this;
return this.viewer.entities.add({
polygon: {
hierarchy: new Cesium.CallbackProperty(function() {
return $this.positions
}, false),
clampToGround: obj.clampToGround || true,
show: true,
fill: obj.fill || true,
material: obj.material || Cesium.Color.WHITE,
width: obj.width || 3,
outlineColor: obj.outlineColor || Cesium.Color.BLACK,
outlineWidth: obj.outlineWidth || 1,
outline: false || obj.outline
}
});
},
2、操作逻辑核心代码
大致解释以下操作逻辑:
首先是绑定了鼠标左击,当鼠标在地图上点击时,会保存点击的坐标,用于构建面。鼠标移动时,会动态显示面;
鼠标右击时结束操作;
创建面的操作步骤:
startCreate: function(callBack) {
var $this = this;
this.handler.setInputAction(function(evt) { //单机开始绘制
var cartesian = $this.getCatesian3FromPX(evt.position, $this.viewer,[$this.polygon]);
if ($this.positions.length == 0) {
$this.positions.push(cartesian.clone());
}
$this.positions.push(cartesian);
var point = $this.createPoint(cartesian);
point.wz = $this.gonPointArr.length;
$this.gonPointArr.push(point);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(function(evt) { //移动时绘制面
if ($this.positions.length < 1) return;
var cartesian = $this.getCatesian3FromPX(evt.endPosition, $this.viewer,[$this.polygon]);
if ($this.positions.length == 2) {
if (!Cesium.defined($this.polygon)) {
$this.polygon = $this.createPolygon($this.style);
$this.polygon.objId = $this.objId;
}
}
if ($this.polygon) {
$this.positions.pop();
$this.positions.push(cartesian);
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction(function(evt) {
if (!$this.polygon) return;
var cartesian = $this.getCatesian3FromPX(evt.position, $this.viewer,[$this.polygon]);
$this.state = 1;
$this.handler.destroy();
if ($this.floatPoint) {
if ($this.floatPoint) $this.floatPoint.show = false;
$this.floatPoint = null;
}
$this.positions.pop();
$this.positions.push(cartesian);
var point = $this.createPoint(cartesian);
point.wz = $this.gonPointArr.length;
$this.gonPointArr.push(point);
callBack($this.polygon);
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
修改面:
startModify: function() {
if (this.state != 1 && this.state != 2) return; //表示还没绘制完成
if (!this.modifyHandler) this.modifyHandler = new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
var $this = this;
for (var i = 0; i < $this.gonPointArr.length; i++) {
var point = $this.gonPointArr[i];
if (point) point.show = true;
}
this.modifyHandler.setInputAction(function(evt) {
var pick = $this.viewer.scene.pick(evt.position);
if (Cesium.defined(pick) && pick.id) {
if (!pick.id.objId)
$this.modifyPoint = pick.id;
$this.forbidDrawWorld(true);
} else {
for (var i = 0; i < $this.gonPointArr.length; i++) {
var point = $this.gonPointArr[i];
if (point) point.show = false;
}
if ($this.modifyHandler) {
$this.modifyHandler.destroy();
$this.modifyHandler = null;
}
}
//$this.state = 2;
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
this.modifyHandler.setInputAction(function(evt) { //移动时绘制面
if ($this.positions.length < 1 || !$this.modifyPoint) return;
var cartesian = $this.getCatesian3FromPX(evt.endPosition, $this.viewer,[$this.polygon,$this.modifyPoint]);
if (cartesian) {
$this.modifyPoint.position.setValue(cartesian);
$this.positions[$this.modifyPoint.wz] = cartesian;
}
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.modifyHandler.setInputAction(function(evt) {
$this.forbidDrawWorld(false);
if (!$this.modifyPoint) return;
var cartesian = $this.getCatesian3FromPX(evt.position, $this.viewer,[$this.polygon,$this.modifyPoint]);
$this.modifyPoint.position.setValue(cartesian);
//$this.modifyPoint = null;
$this.positions[$this.modifyPoint.wz] = cartesian;
$this.modifyPoint = null;
$this.forbidDrawWorld(false);
}, Cesium.ScreenSpaceEventType.LEFT_UP);
}
getCatesian3FromPX方法是在模型或者地形上获取点的通用方法,此处兼容模型和地形上坐标的获取;
//通过屏幕坐标获取地形或者模型上的点 entity为需屏蔽的实体
getCatesian3FromPX:function(px, viewer, entitys) {
var pick = viewer.scene.pick(px);
var cartesian;
var drillPick = viewer.scene.drillPick(px);
var truePick = null;
if (entitys) {
for (var i = 0; i < drillPick.length; i++) {
if (drillPick[i].id._id != entitys[0].id && drillPick[i].id._id != entitys[1].id) {
truePick = drillPick[i].id;
break;
}
}
} else {
truePick = pick;
}
if (viewer.scene.pickPositionSupported && Cesium.defined(truePick)) {
cartesian = viewer.scene.pickPosition(px);
} else {
var ray = viewer.camera.getPickRay(px);
if (!ray) return;
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
}
return cartesian;
}
以上就是我整个动态绘制面的核心代码,动态绘制线类似。现在我将底层面的构建和业务逻辑分开了,下面放出全部js和html,有疑问可以给我留言或者联系我的qq951973194;感谢大家的关注。