Skip to content

与地图交互

控制器

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,则取消当前矢量的绘制,可以继续重新绘制矢量。

添加编辑矢量控制器

经过上一小节的教程,你一定可以在地图上绘制矢量了,万一用户操作失误,绘制了错误的矢量位置,那么就需要编辑矢量控制器来修改矢量的位置。

// 创建一个编辑矢量的控制器
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(); // 显示交互界面

添加选择矢量控制器

有了绘制和编辑,你已经可以完成绘制的功能了。在实际业务场景应用中,我们使用最多的应该就是查询功能,可以通过属性查询,也可以通过鼠标选择来查询。

在本小节中,将介绍如何使用选择矢量控制器,通过鼠标来查询矢量信息,而在实际业务场景中,矢量是代表真实世界具体事物的符号,那么该矢量信息一般都具有一些属性信息,我们通过鼠标选择矢量,来获取该矢量所具有的事物属性。

为了方便直观的展示选择矢量控制器,我们在选择矢量控制器中,将所选中的矢量调整都调整一下边线颜色,当然在实际应用中需要更符合逻辑的展示,比如弹出窗口展示详细的属性信息。

// 创建一个选择矢量的控制器
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(); // 显示交互界面

可以从图中看到,选择矢量之后,矢量线的颜色都变成了白色,但是这样产生了一个问题,我多次选择之后,所有的矢量边线都变成了白色,更进一步的,我只想让当前选中的矢量显示白色的边线,那么我们继续完善一下选择控制器,在选中事件中,我们只让当前选中的矢量边线变成白色,上一次选中的矢量让它恢复原来的颜色。

// 申明一个变量保存选中的矢量
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(); // 显示交互界面

用心去做高质量的内容网站,欢迎 star ⭐ 让更多人发现