与地图交互
控制器
SmartGloble使用控制器来处理用户与地图的交互,核心类分别是olview.MouseEventHandler(二维)和csview.MouseEventHander。二维控制器和三维控制器在使用方式上基本相同,有一些细微的差别会在后续的自定义控制器教程中介绍,本节教程主要介绍SmartGloble自带的控制器,以及如何使用现有的控制器与地图交互。
三维矢量控制器
添加绘制矢量控制器
我们还是以一个具体的示例来开始本教程,假设我现在需要在地图上绘制一些矢量符号,我需要绘制一些点来表示一些设备,然后在绘制一些线路来表示这些设备之间的联系,最后我还需要绘制一些面来表示这些设备覆盖的范围。
创建控制器代码如下:
// 创建矢量图层,并添加到视图
var csVectorLayer = csView.addLayer(new sg.csvector.VectorLayer());
// 创建一个绘制贴地点的控制器
var csDrawPoint = new sg.csvector.handler.DrawGroundPoint();
csDrawPoint.setVectorLayer(csVectorLayer); // 设置绘制的矢量属于哪个矢量图层
// 创建一个绘制贴地线的控制器
var csDrawPolyline = new sg.csvector.handler.DrawGroundPolyline();
csDrawPolyline.setVectorLayer(csVectorLayer);// 设置绘制的矢量属于哪个矢量图层
// 创建一个绘制贴地面的控制器
var csDrawPolygon = new sg.csvector.handler.DrawGroundPolygon();
csDrawPolygon.setVectorLayer(csVectorLayer);// 设置绘制的矢量属于哪个矢量图层
直接将所有的控制器添加到视图中,是会出现冲突的,因为地图在传递消息时,每个控制器对消息的处理逻辑是不同的。像我们这里,绘制点、线、面的逻辑是不一样的,同时响应三个控制器会出现绘制问题。实际使用中,用户也是需要在界面上分别选择进行哪个绘制操作。
界面上的交互逻辑,需要用户自己去根据业务功能的需要处理,在本示例中,我会使用dat.gui来处理简单的界面交互。注意引入dat.gui的库文件,SmartGloble很多示例里都用到了dat.gui库来显示简单的交互界面,请参考示例里的引入方式。
我们接着修改示例代码,在交互界面中选择当前视图中需要哪个控制器。
// 为了方便界面交互,我们将控制器按顺序存放到一个数组
var csHandlers = [csDrawPoint,csDrawPolyline,csDrawPolygon];
// 定义一个简单的交互界面
function Gui() {
this._csDrawType = -1;
///////////////////////////////////////////////////////////////////////// gui
this._gui = new dat.GUI({
autoPlace: false
});
this._gui.show();
this._gui.open();
this._drag = new sg.utils.DragContainer({
domElement: this._gui.domElement,
x: 800,
y: 0
});
this._gui.add(this, '_csDrawType', {
'绘制点': 0,
'绘制线': 1,
'绘制面': 2,
'取消绘制': -1
}).name('绘制矢量').onFinishChange(function(value) {
var index = parseInt(value);
if(index === -1) {
csView.removeHandlers(); //取消绘制,移除所有的控制器
} else {
csView.setHandlers(csHandlers[index]); // 根据选择的绘制内容,设置视图中的控制器
}
});
}
var gui = new Gui(); // 显示交互界面
默认的绘制线控制器和绘制面控制器,操作方式都是鼠标左键单击选择位置;鼠标左键双击结束当前矢量绘制,如果矢量顶点数量小于矢量最少顶点(线最少需要两个点,面最少需要三个点),则矢量不会绘制;鼠标右键单击会回退当前操作,如果回退到顶点数量为0,则取消当前矢量的绘制,可以继续重新绘制矢量。
![](/docs/images/cesium/665.png)
添加编辑矢量控制器
经过上一小节的教程,你一定可以在地图上绘制矢量了,万一用户操作失误,绘制了错误的矢量位置,那么就需要编辑矢量控制器来修改矢量的位置。
// 创建一个编辑矢量的控制器
var csModifyVector = new sg.csvector.handler.ModifyVector();
然后修改上面示例中交互界面的代码,增加编辑矢量的功能。
// 为了方便界面交互,我们将控制器按顺序存放到一个数组
var csHandlers = [csDrawPoint,csDrawPolyline,csDrawPolygon,csModifyVector];
// 定义一个简单的交互界面
function Gui() {
this._csDrawType = -1;
///////////////////////////////////////////////////////////////////////// gui
this._gui = new dat.GUI({
autoPlace: false
});
this._gui.show();
this._gui.open();
this._drag = new sg.utils.DragContainer({
domElement: this._gui.domElement,
x: 800,
y: 0
});
this._gui.add(this, '_csDrawType', {
'绘制点': 0,
'绘制线': 1,
'绘制面': 2,
'编辑矢量': 3,
'取消绘制': -1
}).name('绘制矢量').onFinishChange(function(value) {
var index = parseInt(value);
if(index === -1) {
csView.removeHandlers(); //取消绘制,移除所有的控制器
} else {
csView.setHandlers(csHandlers[index]); // 根据选择的绘制内容,设置视图中的控制器
}
});
}
var gui = new Gui(); // 显示交互界面
![](/docs/images/cesium/664.png)
添加选择矢量控制器
有了绘制和编辑,你已经可以完成绘制的功能了。在实际业务场景应用中,我们使用最多的应该就是查询功能,可以通过属性查询,也可以通过鼠标选择来查询。
在本小节中,将介绍如何使用选择矢量控制器,通过鼠标来查询矢量信息,而在实际业务场景中,矢量是代表真实世界具体事物的符号,那么该矢量信息一般都具有一些属性信息,我们通过鼠标选择矢量,来获取该矢量所具有的事物属性。
为了方便直观的展示选择矢量控制器,我们在选择矢量控制器中,将所选中的矢量调整都调整一下边线颜色,当然在实际应用中需要更符合逻辑的展示,比如弹出窗口展示详细的属性信息。
// 创建一个选择矢量的控制器
var csSelectVector = new sg.csvector.handler.SelectVector();
// 监听选择矢量控制器的选中事件
csSelectVector.on('Selected', function (event) {
if(event.vector) {
event.vector.setStrokeColor('white'); // 将选中的矢量边线颜色设置为白色
}
});
然后继续修改上面示例中交互界面的代码,增加选择矢量的功能。
// 为了方便界面交互,我们将控制器按顺序存放到一个数组
var csHandlers = [csDrawPoint,csDrawPolyline,csDrawPolygon,csModifyVector,csSelectVector];
// 定义一个简单的交互界面
function Gui() {
this._csDrawType = -1;
///////////////////////////////////////////////////////////////////////// gui
this._gui = new dat.GUI({
autoPlace: false
});
this._gui.show();
this._gui.open();
this._drag = new sg.utils.DragContainer({
domElement: this._gui.domElement,
x: 800,
y: 0
});
this._gui.add(this, '_csDrawType', {
'绘制点': 0,
'绘制线': 1,
'绘制面': 2,
'编辑矢量': 3,
'选择矢量': 4,
'取消绘制': -1
}).name('绘制矢量').onFinishChange(function(value) {
var index = parseInt(value);
if(index === -1) {
csView.removeHandlers(); //取消绘制,移除所有的控制器
} else {
csView.setHandlers(csHandlers[index]); // 根据选择的绘制内容,设置视图中的控制器
}
});
}
var gui = new Gui(); // 显示交互界面
![](/docs/images/cesium/666.png)
可以从图中看到,选择矢量之后,矢量线的颜色都变成了白色,但是这样产生了一个问题,我多次选择之后,所有的矢量边线都变成了白色,更进一步的,我只想让当前选中的矢量显示白色的边线,那么我们继续完善一下选择控制器,在选中事件中,我们只让当前选中的矢量边线变成白色,上一次选中的矢量让它恢复原来的颜色。
// 申明一个变量保存选中的矢量
var csSelectedVector = null;
// 申明一个变量保存选中的矢量原来的边线颜色
var csSelectedVectorOriginStrokeColor = null;
// 创建一个选择矢量的控制器
var csSelectVector = new sg.csvector.handler.SelectVector();
// 监听选择矢量控制器的选中事件
csSelectVector.on('Selected', function (event) {
if(event.vector) {
// 如果csSelectedVector跟当前选中的矢量不是同一个,那么改回原来的边线颜色,
// 然后保存当前选中的矢量和其边线颜色,改变当前选中的矢量的边线颜色,
if(csSelectedVector !== event.vector) {
if(csSelectedVector) {
csSelectedVector.setStrokeColor(csSelectedVectorOriginStrokeColor);
}
csSelectedVector = event.vector;
csSelectedVectorOriginStrokeColor = csSelectedVector.getStrokeColor();
csSelectedVector.setStrokeColor('white'); // 将选中的矢量边线颜色设置为白色
}
} else {
if(csSelectedVector) {
csSelectedVector.setStrokeColor(csSelectedVectorOriginStrokeColor);
csSelectedVector = null;
csSelectedVectorOriginStrokeColor = null;
}
}
});
完整代码
三维矢量控制器的完整代码如下:
// 创建矢量图层,并添加到视图
var csVectorLayer = csView.addLayer(new sg.csvector.VectorLayer());
// 创建一个绘制贴地点的控制器
var csDrawPoint = new sg.csvector.handler.DrawGroundPoint();
csDrawPoint.setVectorLayer(csVectorLayer); // 设置绘制的矢量属于哪个矢量图层
// 创建一个绘制贴地线的控制器
var csDrawPolyline = new sg.csvector.handler.DrawGroundPolyline();
csDrawPolyline.setVectorLayer(csVectorLayer);// 设置绘制的矢量属于哪个矢量图层
// 创建一个绘制贴地面的控制器
var csDrawPolygon = new sg.csvector.handler.DrawGroundPolygon();
csDrawPolygon.setVectorLayer(csVectorLayer);// 设置绘制的矢量属于哪个矢量图层
// 创建一个编辑矢量的控制器
var csModifyVector = new sg.csvector.handler.ModifyVector();
// 申明一个变量保存选中的矢量
var csSelectedVector = null;
// 申明一个变量保存选中的矢量原来的边线颜色
var csSelectedVectorOriginStrokeColor = null;
// 创建一个选择矢量的控制器
var csSelectVector = new sg.csvector.handler.SelectVector();
// 监听选择矢量控制器的选中事件
csSelectVector.on('Selected', function (event) {
if(event.vector) {
// 如果csSelectedVector跟当前选中的矢量不是同一个,那么改回原来的边线颜色,
// 然后保存当前选中的矢量和其边线颜色,改变当前选中的矢量的边线颜色,
if(csSelectedVector !== event.vector) {
if(csSelectedVector) {
csSelectedVector.setStrokeColor(csSelectedVectorOriginStrokeColor);
}
csSelectedVector = event.vector;
csSelectedVectorOriginStrokeColor = csSelectedVector.getStrokeColor();
csSelectedVector.setStrokeColor('white'); // 将选中的矢量边线颜色设置为白色
}
} else {
if(csSelectedVector) {
csSelectedVector.setStrokeColor(csSelectedVectorOriginStrokeColor);
csSelectedVector = null;
csSelectedVectorOriginStrokeColor = null;
}
}
});
// 为了方便界面交互,我们将控制器按顺序存放到一个数组
var csHandlers = [csDrawPoint,csDrawPolyline,csDrawPolygon,csModifyVector,csSelectVector];
// 定义一个简单的交互界面
function Gui() {
this._csDrawType = -1;
///////////////////////////////////////////////////////////////////////// gui
this._gui = new dat.GUI({
autoPlace: false
});
this._gui.show();
this._gui.open();
this._drag = new sg.utils.DragContainer({
domElement: this._gui.domElement,
x: 800,
y: 0
});
this._gui.add(this, '_csDrawType', {
'绘制点': 0,
'绘制线': 1,
'绘制面': 2,
'编辑矢量': 3,
'选择矢量': 4,
'取消绘制': -1
}).name('绘制矢量').onFinishChange(function(value) {
var index = parseInt(value);
if(index === -1) {
csView.removeHandlers(); //取消绘制,移除所有的控制器
} else {
csView.setHandlers(csHandlers[index]); // 根据选择的绘制内容,设置视图中的控制器
}
});
}
var gui = new Gui(); // 显示交互界面
二维矢量控制器
二维里的控制器和三维的控制器基本类似,这里不在分段详细介绍,直接展示完整的示例代码。
// 创建矢量图层,并添加到视图
var olVectorLayer = olView.addLayer(new sg.olvector.VectorLayer());
// 创建一个绘制点的控制器
var olDrawPoint = new sg.olvector.handler.DrawPoint();
olDrawPoint.setVectorLayer(olVectorLayer); // 设置绘制的矢量属于哪个矢量图层
// 创建一个绘制线的控制器
var olDrawPolyline = new sg.olvector.handler.DrawPolyline();
olDrawPolyline.setVectorLayer(olVectorLayer);// 设置绘制的矢量属于哪个矢量图层
// 创建一个绘制面的控制器
var olDrawPolygon = new sg.olvector.handler.DrawPolygon();
olDrawPolygon.setVectorLayer(olVectorLayer);// 设置绘制的矢量属于哪个矢量图层
// 创建一个编辑矢量的控制器
var olModifyVector = new sg.olvector.handler.ModifyVector();
// 申明一个变量保存选中的矢量
var olSelectedVector = null;
// 申明一个变量保存选中的矢量原来的边线颜色
var olSelectedVectorOriginStrokeColor = null;
// 创建一个选择矢量的控制器
var olSelectVector = new sg.olvector.handler.SelectVector();
// 监听选择矢量控制器的选中事件
olSelectVector.on('Selected', function (event) {
if(event.vector) {
// 如果olSelectedVector跟当前选中的矢量不是同一个,那么改回原来的边线颜色,
// 然后保存当前选中的矢量和其边线颜色,改变当前选中的矢量的边线颜色,
if(olSelectedVector !== event.vector) {
if(olSelectedVector) {
olSelectedVector.setStrokeColor(olSelectedVectorOriginStrokeColor);
}
olSelectedVector = event.vector;
olSelectedVectorOriginStrokeColor = olSelectedVector.getStrokeColor();
olSelectedVector.setStrokeColor('white'); // 将选中的矢量边线颜色设置为白色
}
} else {
if(olSelectedVector) {
olSelectedVector.setStrokeColor(olSelectedVectorOriginStrokeColor);
olSelectedVector = null;
olSelectedVectorOriginStrokeColor = null;
}
}
});
// 为了方便界面交互,我们将控制器按顺序存放到一个数组
var olHandlers = [olDrawPoint,olDrawPolyline,olDrawPolygon,olModifyVector,olSelectVector];
// 定义一个简单的交互界面
function Gui() {
this._olDrawType = -1;
///////////////////////////////////////////////////////////////////////// gui
this._gui = new dat.GUI({
autoPlace: false
});
this._gui.show();
this._gui.open();
this._drag = new sg.utils.DragContainer({
domElement: this._gui.domElement,
x: 800,
y: 0
});
this._gui.add(this, '_olDrawType', {
'绘制点': 0,
'绘制线': 1,
'绘制面': 2,
'编辑矢量': 3,
'选择矢量': 4,
'取消绘制': -1
}).name('绘制矢量').onFinishChange(function(value) {
var index = parseInt(value);
if(index === -1) {
olView.removeHandlers(); //取消绘制,移除所有的控制器
} else {
olView.setHandlers(olHandlers[index]); // 根据选择的绘制内容,设置视图中的控制器
}
});
}
var gui = new Gui(); // 显示交互界面
![](/docs/images/cesium/667.png)