目录
标绘作为GIS最基本需求之一,想必大家在工作中肯定遇到了,标题中的这些标绘大家肯定都实现过,但是也许总是不太全面,在此,我把标绘的逻辑做了统一的封装处理,没准等你看完了点线面的处理逻辑后,你会说,只要你给我一个算法,我给你画出个牡丹花(本质上就是给你一堆点,看你能画出什么奇奇怪怪的东西了)
绘制逻辑说明:
constructor:这里采用ES6的新语法,用来构造每种标绘类型的构造函数(js没有类的概念,就是一个语法糖,谁不知道呢?)
getData:返回该标绘对象坐标数据,该数据可以存储到数据库,用于二次从数据库中直接读取加载该标绘(谁规定非要用鼠标交互绘制呢?)
loadXXX(data):将getData返回的数据传入该函数中,即可重新构造出该标绘(数据导入构建)
startCreate:注册鼠标交互事件,用于绘制该标绘(鼠标交互构建)
destroy:销毁鼠标交互
clear:清空临时实体对象
前言
说了这么多,相比你心里还有一些疑惑,下面就从代码由浅入深逐渐理解吧,如果你对
CallbackProperty机制不熟悉,最好还是先熟悉一下,这样你会更加容易理解后面发生的一切。
一、点
// DrawPoint
/*
绘制点
*/
class DrawPoint {
constructor(arg) {
this.viewer = arg.viewer;
this.Cesium = arg.Cesium;
this.callback=arg.callback;
this._point = null; //最后一个点
this._pointData = null;//点数据用于构造点
this._entities = []; //脏数据
}
//返回最后活动点
get point() {
return this._point;
}
//加载点
loadPoint(data) {
return this.createPoint(data);
}
//返回点数据用于加载点
getData() {
return this._pointData;
}
//开始绘制
startCreate() {
var $this = this;
this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction(function (evt) { //单机开始绘制
var cartesian = $this.getCatesian3FromPX(evt.position);
if (!cartesian) return;
var point = $this.createPoint(cartesian);
$this._pointData = cartesian;
$this._point = point;
if(typeof $this.callback=="function"){
$this.callback(point);
}
}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
}
//创建点
createPoint(cartesian) {
var $this = this;
var point = this.viewer.entities.add({
position: cartesian,
point: {
pixelSize: 10,
color: $this.Cesium.Color.YELLOW,
}
});
$this._entities.push(point); //加载脏数据
return point;
}
//销毁鼠标事件
destroy() {
if (this.handler) {
this.handler.destroy();
this.handler = null;
}
}
//清空实体对象
clear() {
for (var i = 0; i < this._entities.length; i++) {
this.viewer.entities.remove(this._entities[i]);
}
this._entities = [];
this._point = null;
}
getCatesian3FromPX(px) {
var cartesian;
var ray = this.viewer.camera.getPickRay(px);
if (!ray) return null;
cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
return cartesian;
}
}
export default DrawPoint;
二、折线
// DrawPolyline
/*
绘制线
*/
class DrawPolyline {
constructor(arg) {
this.viewer = arg.viewer;
this.Cesium = arg.Cesium;
this.callback=arg.callback;
this._polyline = null; //活动线
this._polylineLast = null; //最后一条线
this._positions = []; //活动点
this._entities_point = []; //脏数据
this._entities_line = []; //脏数据
this._polylineData = null; //用于构造线数据
}
//返回最后活动线
get line() {
return this._polylineLast;
}
//返回线数据用于加载线
getData() {
return this._polylineData;
}
//加载线
loadPolyline(data) {
var $this = this;
var polyline = this.viewer.entities.add({
polyline: {
positions: data,
show: true,
material: $this.Cesium.Color.RED,
width: 3,
clampToGround: true
}
});
return polyline;
}
//开始创建
startCreate() {
var $this = this;
this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
this.handler.setInputAction(function (evt) { //单机开始绘制
//屏幕坐标转地形上坐标
var cartesian = $this.getCatesian3FromPX(evt.position);
if ($this._positions.length == 0) {
$this._positions.push(cartesian.clone());
}
$this._positions.push(cartesian);
$this.createPoint(cartesian);// 绘制点
}, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
this.handler.setInputAction(function (evt) { //移动时绘制线
if ($this._positions.length < 1) return;
var cartesian = $this.getCatesian3FromPX(evt.endPosition);
if (!$this.Cesium.defined($this._polyline)) {
$this._polyline = $this.createPolyline();
}
if ($this._polyline) {
$this._positions.pop();
$this._positions.push(cartesian);
}
}, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
this.handler.setInputAction(function (evt) {
if (!$this._polyline) return;
var cartesian = $this.getCatesian3FromPX(evt.position);
$this._positions.pop();
$this._positions.push(cartesian);
$this.createPoint(cartesian);// 绘制点
$this._polylineData = $this._positions.concat();
$this.viewer.entities.remove($this._polyline); //移除
$this._polyline = null;
$this._positions = [];
var line = $this.loadPolyline($this._polylineData); //加载线
$this._entities_line.push(line);
$this._polylineLast=line;
if(typeof $this.callback=="function"){
$this.callback(line);
}
}, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
}
//创建点
createPoint(cartesian) {
var $this = this;
var point = this.viewer.entities.add({
position: cartesian,
point: {
pixelSize: 10,
color: $this.Cesium.Color.YELLOW,
}
});
$this._entities_point.push(point);
return point;
}
//创建线
createPolyline() {
var $this = this;
var polyline = this.viewer.entities.add({
polyline: {
//使用cesium的peoperty
positions: new $this.Cesium.CallbackProperty(function () {
return $this._positions
}, false),
show: true,
material: $this.Cesium.Color.RED,
width: 3,
clampToGround: true
}
});
$this._entities_line.push(polyline);
return polyline;
}
//销毁
destroy() {
if (this.handler) {
this.handler.destroy();
this.handler = null;
}
}
//清空实体对象
clear() {
for (var i = 0; i < this._entities_point.length; i++) {
this.viewer.entities.remove(this._entities_point[i]);
}
for (var i = 0; i < this._entities_line.length; i++) {
this.viewer.entities.remove(this._entities_line[i]);
}
this._polyline = null;
this._positions = [];
this._entities_point = []; //脏数据
this._entities_line = []; //脏数据
this._polylineData = null; //用于构造线数据
this._polylineLast=null;
}
getCatesian3FromPX(px) {
var cartesian;
var ray = this.viewer.camera.getPickRay(px);
if (!ray) return null;
cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
return cartesian;
}
}
export default DrawPolyline
三、曲线
// DrawCurve
/*
绘制曲线
*/
class DrawCurve {
constructor(arg) {
this.viewer = arg.viewer;
this.Cesium = arg.Cesium;
this.floatingPoint = null;//标识点
this._curveline = null; //活动曲线
this._curvelineLast = null; //最后一条曲线
this._positions = []; //活动点
this._entities_point = []; //脏数据
this._entities_line = []; //脏数据
this._curvelineData = null; //用于构造曲线数据
}</