ol.interaction.honeyselect存档位置 同一个位置有多个点时怎么处理

OpenLayers 之 地图交互功能(interaction)详解
时间: 10:59:08
&&&& 阅读:1803
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&&&&&&&地图交互功能和上一篇讲的地图控件有些混淆,它们都控制着用户与地图的交互,区别是地图控件的触发都是一些可见的 HTML 元素触发,如按钮、链接等;而交互功能都是一些设备行为触发,都是不可见的,如鼠标双击、滚轮滑动等,手机设备的手指缩放等。
&&&&&&地图的交互功能包含很多,如地图双击放大,鼠标滚轮缩放,矢量要素点选,地图上绘制图形等等。只要是涉及到与地图的交互,就会涉及到 intercation 类,它定义了用户与地图进行交互的基本要素和事件。下面我们就来看看用户与地图都有那些交互,怎么交互。
注: ‘自定义用户交互类型’,‘定制化交互’ 或者 ‘交互优化’ 都超出了本文范围。
有问题可以留言评论或者给我发邮件!
一、interaction 介绍
&&&&&&在 OpenLayers 3 中,表达交互功能的基类是 interaction,它是一个虚基类,不负责实例化,交互功能都继承该基类, OpenLayers 3 中可实例化的子类及其功能如下:
doubleclickzoom interaction,双击放大交互功能;
draganddrop interaction,以“拖文件到地图中”的交互添加图层;
dragbox interaction,拉框,用于划定一个矩形范围,常用于放大地图;
dragpan interaction,拖拽平移地图;
dragrotateandzoom interaction,拖拽方式进行缩放和旋转地图;
dragrotate interaction,拖拽方式旋转地图;
dragzoom interaction,拖拽方式缩放地图;
draw interaction,绘制地理要素功能;
interaction defaults ,规定了默认添加的交互功能;
keyboardpan interaction,键盘方式平移地图;
keyboardzoom interaction,键盘方式缩放地图;
select interaction,选择要素功能;
modify interaction,更改要素;
mousewheelzoom interaction,鼠标滚轮缩放功能;
pinchrotate interaction,手指旋转地图,针对触摸屏;
pinchzoom interaction,手指进行缩放,针对触摸屏;
pointer interaction,鼠标的用户自定义事件基类;
snap interaction,鼠标捕捉,当鼠标距离某个要素一定距离之内,自动吸附到要素。
二、交互功能的种类和使用方法
1. interaction defaults - 默认添加的交互功能
该类规定了默认包含在地图中的功能,主要是最为常用的功能,如缩放、平移和旋转地图等,具体功能有如下这些:
ol.interaction.DragRotate,鼠标拖拽旋转,一般配合一个键盘按键辅助;
ol.interaction.DragZoom,鼠标拖拽缩放,一般配合一个键盘按键辅助;
ol.interaction.DoubleClickZoom,鼠标或手指双击缩放地图;
ol.interaction.PinchRotate,两个手指旋转地图,针对触摸屏;
ol.interaction.PinchZoom,两个手指缩放地图,针对触摸屏;
ol.interaction.DragPan,鼠标或手指拖拽平移地图;
ol.interaction.KeyboardZoom,使用键盘 + 和 - 按键进行缩放;
ol.interaction.KeyboardPan,使用键盘方向键平移地图;
ol.interaction.MouseWheelZoom,鼠标滚轮缩放地图。
可以看出,很多都兼容移动设备的触摸屏,键盘,鼠标事件,这就是OpenLayers 3的改进,跨平台改进。这些功能都是默认添加的,如果要更改默认的选项,需要在相应的选项设置为 false。如果想去掉默认的 DoubleClickZoom 功能,配置如下:
interactions: ol.interaction.defaults([
doubleClickZoom: false
这样就去除了双击放大功能,去除其他的默认功能,是一样的。
2. draw interaction - 绘图功能
绘图交互允许绘制几何地理要素,可选参数为一个对象,包含参数如下:
* @typedef {{features: (ol.Collection.&ol.Feature&|undefined),
source: (ol.source.Vector|undefined),
snapTolerance: (number|undefined),
type: ol.geom.GeometryType,
minPointsPerRing: (number|undefined),
style: (ol.style.Style|Array.&ol.style.Style&|ol.style.StyleFunction|undefined),
geometryName: (string|undefined),
condition: (ol.events.ConditionType|undefined)}}
features,绘制的要素的目标集合;
source,绘制的要素的目标图层来源,即目标图层的 source属性 ;
snapTolerance,自动吸附完成点的像素距离,也就是说当鼠标位置距离闭合点小于该值设置的时候,会自动吸附到闭合点,默认值是 12;
type,绘制的地理要素类型,ol.geom.GeometryType类型,包含 Point、 LineString、 Polygon、MultiPoint、MultiLineString 或者 MultiPolygon;
minPointsPerRing,绘制一个多边形需要的点数最小值,数值类型,默认是 3;
style,要素素描的样式,是 ol.style.Style对象之一;
geometryName,绘制的地理要素的名称,string类型;
condition,一个函数,接受一个ol.MapBrowserEvent类型的参数,返回一个布尔值表示是否应该调用事件处理函数。默认情况下,增加一个顶点,类型为 ol.events.ConditionType。
给地图添加该交互功能,首先需要实例化一个ol.interaction.Draw,必须指定 source和type属性:
var draw = new ol.interaction.Draw({
source: source,
type: "Polygon"
然后将该功能添加到地图中map.addInteraction(draw)。
这里我们在页面中添加一个 HTML
select 元素,通过选择要素类型,绘制相应的要素类型:
&select id="type"&
&option value="None"&None&/option&
&option value="LineString"&LineString&/option&
&option value="Polygon"&Polygon&/option&
定义一个函数用于添加该交互功能:
var typeSelect = document.getElementById(‘type‘);
function addInteraction() {
var value = typeSelect.value;
if (value !== ‘None‘) {
draw = new ol.interaction.Draw({
source: source,
type: value
map.addInteraction(draw);
绑定select值变化触发的事件:
typeSelect.onchange = function(e) {
map.removeInteraction(draw);
addInteraction();
最后首先执行绑定函数addInteraction();,然后点击鼠标进行绘制:
绘制LineString
绘制Polygon
这里只是使用 LineString 和 Ploygon 做了例子,还有 Point 和 Circle 可以使用。对该类稍微定制,就可以定制绘制的图形,如箭头,这个就可以用于动态标绘系统,使用WFS协议和服务器建立通讯。
3. dragrotateandzoom interaction - 鼠标拖拽进行缩放和旋转地图
拖拽实现旋转和缩放地图的功能。首先定义该交互对象:
var interactions = ol.interaction.defaults().extend([
new ol.interaction.DragRotateAndZoom()
然后在 map 中加入交互对象:
&&&&&&这个功能的使用方法是首先按住键盘的 shift 按钮,然后使用鼠标点住地图一点,然后拖拽鼠标围绕地图中心旋转,地图就会选择相应的角度;如果拖拽鼠标远离地图中心,就会实现地图的放大,靠近地图中心,地图就会缩小。
&&&&&&该功能是两个单独功能的合体: dragzoom 和 dragrotate,一个负责拖拽缩放,一个负责拖拽旋转,和以上的功能一样,就不再赘述了。
4. dragbox interaction - 拉框交互
&&&&&&在地图上拉出一个矩形框,一般配合使用一个辅助按键,如Shift,常用于放大功能。该功能是默认添加在地图中的,默认情况下,按下Shift,然后拖动鼠标拉框,然后地图就会将框内内容放大。
5. draganddrop interaction - 拖拽文件到地图
&&&&&&将空间数据使用鼠标或者手指拖拽到地图中,解析成一个图层添加到地图中。目前只支持矢量数据,未来可能支持更多的空间数据格式。目前,支持的格式包括 GeoJSON, GML,
KML, GPX, OSMXML, TopoJSON 和 IGC。首先实例化一个 draganddrop interaction:
var dragAndDropInteraction = new ol.interaction.DragAndDrop({
formatConstructors: [
ol.format.GeoJSON,
ol.format.KML
formatConstructors 表示想要支持的格式,这里我选择了支持两种常见的格式:GeoJSON 和 KML,然后将该交互添加到地图中:
var interactions = ol.interaction.defaults().extend([
new ol.interaction.DragRotateAndZoom(),
dragAndDropInteraction
&&&&&&如果想在添加数据的时候定义一些额外行为,比如缩放到添加到数据的范围,需要注册 interaction 的事件-dragAndDropInteraction.on(‘addfeatures‘, function(event) {});, 以下为拖拽一个KML文件到地图中:
6. keyboard interaction - 键盘交互功能
&&&&&&包含 ol.interaction.KeyboardZoom 和 ol.interaction.KeyboardPan,分别是键盘缩放和键盘平移。默认添加到地图中,但是只有当焦点在包含地图的 HTML 元素上,才可用。可以通过修改 ol.Map 的 keyboardEventTarget 属性,修改键盘事件的关联 HTML 元素。
&&ol.interaction.KeyboardZoom,使用键盘+ 和 - 进行地图缩放;ol.interaction.KeyboardPan,使用方向键平移地图。
7. modify 和 select interaction
&&&&&&select 就像名字暗示的一样,是用来选中要素的;而 modify 是修改要素的,主要是通过拖拽方式修改点的坐标。
选中后的原图
拖拽几个点后效果
模拟选中并修改要素的交互功能需要添加如下代码:
var select = new ol.interaction.Select();
var moddify = new ol.interaction.Modify({
features:select.getFeatures()
features:select.getFeatures()目的为修改选中的要素。 然后将两个交互功能添加到 map 中就可以使用其功能了。
8. pinchrotate ,pinchzoom interaction - 两个手指缩放和旋转地图
这两个功能针对触摸屏,两个手指按住地图,增减距离来实现缩放,旋转手指,地图跟着旋转。默认添加到地图中。
9. pointer interaction - 自定义鼠标事件
&&&&&&针对鼠标的行为按下(Down)、移动(Move)和抬起(Up),自定义事件。这三个事件发生有先后顺序,首先是触发按下,之后是移动事件,最后是抬起事件。只要配置相关的属性,包含handleDownEvent,handleDragEvent,handleMoveEvent,handleUpEvent分别对应鼠标的 down、drag、move和up四种事件。例如配置鼠标的按下左键事件,当按下鼠标左键时候,就会触发 functionName函数 :
.interaction.Pointer({
handleDownEvent: functionName
10. snap interaction - 鼠标捕捉
当修改和绘制矢量要素时,鼠标距离某个要素一定距离之内,自动吸附到要素。
再靠近就会吸附到黄色的点
可以配置的选项有 具有捕捉吸附功能的要素集 或者 矢量图层,发生捕捉的最大距离(像素为单位),使用方法如下:
new ol.interaction.Snap({
features: 要素集(ol.Collection),
pixelTolerance: 捕捉发生的距离,像素数,默认为10,
source: 具有捕捉功能的图层(ol.source.Vector)
&&&&&&交互功能比较多,主要涉及用户与地图交互需要的基本功能:缩放、平移拖拽、旋转,为了提高兼容性,除了针对鼠标和键盘的交互,还有针对触摸屏的缩放、旋转和平移拖拽。
&&&&&&比较有用的有勾绘draw、选择要素select、modify、捕捉吸附snap 和 鼠标自定义事件pointer。这些交互功能可以共同构建一个动态标绘系统,在客户端增加或者修改空间数据,提交给服务器,更新数据。
OK,写完了。
有问题可以留言评论或者给我发邮件!
标签:&&&&&&&&&&&&&&&
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!概述:本节主要讲述OL3的交互操作interaction,重点介绍draw,select以及modify。接口说明:OL3的interaction继承自ol.interaction.defaults,下面实现了以下几中交互操作:创建方式为:var interaction = new ol.interaction.InteractionType({options});添加和移除方式为:map.addInteraction(draw);map.removeInteraction(draw);1、draw.Drawnew ol.interaction.Draw(options)NameTypeDescriptionoptionsOptions.NameTypeDescriptionFires:&() - Triggered upon feature draw end&() - Triggered upon feature draw startExtendsMethodson(type, listener,&opt_this){goog.events.Key}&NameTypeDescriptiontypestring&|&Array.&string&The event type or array of event types.listenerfunctionThe listener function.thisObjectThe object to use as&this&in&listener.2、select.Selectnew ol.interaction.Select(opt_options)NameTypeDescriptionoptionsOptions.NameTypeDescriptionExtendsMethodsgetFeatures(){.&&}3、modify.Modifynew ol.interaction.Modify(options)NameTypeDescriptionoptionsOptions.NameTypeDescriptionExtendsMethodson(type, listener,&opt_this){goog.events.Key}&NameTypeDescriptiontypestring&|&Array.&string&The event type or array of event types.listenerfunctionThe listener function.thisObjectThe object to use as&this&in&listener.实现实例:1、draw&html xmlns=&http://www.w3.org/1999/xhtml&&
&meta http-equiv=&Content-Type& content=&text/ charset=utf-8& /&
&title&Ol3 draw&/title&
&link rel=&stylesheet& type=&text/css& href=&http://localhost/ol3/css/ol.css&/&
&style type=&text/css&&
body, #map {
padding: 0
width: 100%;
height: 100%;
font-size: 13
.form-inline{
z-index: 99;
&script type=&text/javascript& src=&http://localhost/ol3/build/ol.js&&&/script&
&script type=&text/javascript& src=&http://localhost/jquery/jquery-1.8.3.js&&&/script&
&script type=&text/javascript&&
function init(){
var format = 'image/png';
var bounds = [73.3, 18.7,
134., 53.6];
var untiled = new ol.layer.Image({
source: new ol.source.ImageWMS({
url: 'http://localhost:8081/geoserver/lzugis/wms',
params: {'FORMAT': format,
'VERSION': '1.1.1',
LAYERS: 'lzugis:province',
STYLES: ''
var projection = new ol.proj.Projection({
code: 'EPSG:4326',
units: 'degrees'
var map = new ol.Map({
controls: ol.control.defaults({
attribution: false
target: 'map',
view: new ol.View({
projection: projection
map.getView().fitExtent(bounds, map.getSize());
var source = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: source,
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 0, 0, 0.2)'
stroke: new ol.style.Stroke({
color: '#ffcc33',
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
map.addLayer(vector);
var typeSelect = document.getElementById('type');
// global so we can remove it later
function addInteraction() {
var value = typeSelect.
if (value !== 'None') {
draw = new ol.interaction.Draw({
source: source,
type: /** @type {ol.geom.GeometryType} */ (value)
map.addInteraction(draw);
* Let user change the geometry type.
* @param {Event} e Change event.
typeSelect.onchange = function(e) {
map.removeInteraction(draw);
addInteraction();
addInteraction();
&body onLoad=&init()&&
&div id=&map&&
&form class=&form-inline&&
&label&选择绘制类型:&/label&
&select id=&type&&
&option value=&None&&None&/option&
&option value=&Point&&点&/option&
&option value=&LineString&&线&/option&
&option value=&Polygon&&多边形&/option&
&/html&2、select&html xmlns=&http://www.w3.org/1999/xhtml&&
&meta http-equiv=&Content-Type& content=&text/ charset=utf-8& /&
&title&Ol3 select&/title&
&link rel=&stylesheet& type=&text/css& href=&http://localhost/ol3/css/ol.css&/&
&style type=&text/css&&
body, #map {
padding: 0
width: 100%;
height: 100%;
font-size: 13
.form-inline{
z-index: 99;
&script type=&text/javascript& src=&http://localhost/ol3/build/ol.js&&&/script&
&script type=&text/javascript& src=&http://localhost/jquery/jquery-1.8.3.js&&&/script&
&script type=&text/javascript&&
var point = &POINT(103. 36.)&;
var line = &MULTILINESTRING((106. 36.,108. 36.3))&;
var polygon = &MULTIPOLYGON(((106. 29.6,108. 34.7,113. 23.9)))&;
var wkts = [point, line, polygon];
var wktformat = new ol.format.WKT();
function init(){
var format = 'image/png';
var bounds = [73.3, 18.7,
134., 53.6];
var untiled = new ol.layer.Image({
source: new ol.source.ImageWMS({
url: 'http://localhost:8081/geoserver/lzugis/wms',
params: {'FORMAT': format,
'VERSION': '1.1.1',
LAYERS: 'lzugis:province',
STYLES: ''
var projection = new ol.proj.Projection({
code: 'EPSG:4326',
units: 'degrees'
var features = new Array();
for(var i=0;i&wkts.i++){
var feature = wktformat.readFeature(wkts[i]);
feature.getGeometry().transform('EPSG:4326', 'EPSG:4326');
features.push(feature);
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
features: features
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 0, 0, 0.2)'
stroke: new ol.style.Stroke({
color: '#ffcc33',
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
var map = new ol.Map({
controls: ol.control.defaults({
attribution: false
target: 'map',
untiled, vector
view: new ol.View({
projection: projection
map.getView().fitExtent(bounds, map.getSize());
//选择对象
var select =
// ref to currently selected interaction
// select interaction working on &singleclick&
var selectSingleClick = new ol.interaction.Select();
// select interaction working on &click&
var selectClick = new ol.interaction.Select({
condition: ol.events.condition.click
// select interaction working on &mousemove&
var selectMouseMove = new ol.interaction.Select({
condition: ol.events.condition.mouseMove
var selectElement = document.getElementById('selecttype');
var changeInteraction = function() {
if (select !== null) {
map.removeInteraction(select);
var value = selectElement.
if (value == 'singleclick') {
select = selectSingleC
} else if (value == 'click') {
select = selectC
} else if (value == 'mousemove') {
select = selectMouseM
if (select !== null) {
map.addInteraction(select);
* onchange callback on the select element.
selectElement.onchange = changeI
changeInteraction();
&body onLoad=&init()&&
&div id=&map&&
&form class=&form-inline&&
&label&选择高亮方式:&/label&
&select id=&selecttype&&
&option value=&none& selected&None&/option&
&option value=&singleclick&&单击&/option&
&option value=&click&&点击&/option&
&option value=&mousemove&&鼠标经过&/option&
&/html&3、modify&html xmlns=&http://www.w3.org/1999/xhtml&&
&meta http-equiv=&Content-Type& content=&text/ charset=utf-8& /&
&title&Ol3 modify&/title&
&link rel=&stylesheet& type=&text/css& href=&http://localhost/ol3/css/ol.css&/&
&style type=&text/css&&
body, #map {
padding: 0
width: 100%;
height: 100%;
font-size: 13
&script type=&text/javascript& src=&http://localhost/ol3/build/ol.js&&&/script&
&script type=&text/javascript& src=&http://localhost/jquery/jquery-1.8.3.js&&&/script&
&script type=&text/javascript&&
var point = &POINT(103. 36.)&;
var line = &MULTILINESTRING((106. 36.,108. 36.3))&;
var polygon = &MULTIPOLYGON(((106. 29.6,108. 34.7,113. 23.9)))&;
var wkts = [point, line, polygon];
var wktformat = new ol.format.WKT();
function init(){
var format = 'image/png';
var bounds = [73.3, 18.7,
134., 53.6];
var untiled = new ol.layer.Image({
source: new ol.source.ImageWMS({
url: 'http://localhost:8081/geoserver/lzugis/wms',
params: {'FORMAT': format,
'VERSION': '1.1.1',
LAYERS: 'lzugis:province',
STYLES: ''
var projection = new ol.proj.Projection({
code: 'EPSG:4326',
units: 'degrees'
var features = new Array();
for(var i=0;i&wkts.i++){
var feature = wktformat.readFeature(wkts[i]);
feature.getGeometry().transform('EPSG:4326', 'EPSG:4326');
features.push(feature);
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
features: features
style: new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(255, 0, 0, 0.2)'
stroke: new ol.style.Stroke({
color: '#ffcc33',
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
var select = new ol.interaction.Select();
var modify = new ol.interaction.Modify({
features: select.getFeatures()
vector.on(&afterfeaturemodified&,function(evt){
console.log(evt);
var map = new ol.Map({
interactions: ol.interaction.defaults().extend([select, modify]),
controls: ol.control.defaults({
attribution: false
target: 'map',
untiled, vector
view: new ol.View({
projection: projection
map.getView().fitExtent(bounds, map.getSize());
&body onLoad=&init()&&
&div id=&map&&
&/html&相关文章:
本文已收录于以下专栏:
相关文章推荐
地图交互功能和上一篇讲的地图控件有些混淆,它们都控制着用户与地图的交互,区别是地图控件的触发都是一些可见的 HTML 元素触发,如按钮、链接等;而交互功能都是一些设备行为触发,都是不可见的,如鼠标双击...
/forum.php?mod=viewthread&tid=171
解压后有如下内容;
把img, theme...
Linux老难题解决了!
Linux工程师很多,甚至有很多有多年工作经验,但是对一些关键概念的理解非常模糊,比如不理解CPU、内存资源等的真正分布,具体的工作机制,这使得他们对很多问题的分析都摸不到方向。比如进程的调度延时是多少?linux能否硬实时?多核下多线程如何执行?
openlayers入门经典例子
本文讲述的是Ol3中的control的介绍和应用。
本节主要讲述OL3的交互操作interaction,重点介绍draw,select以及modify。
第二十章 访问数据库
程序运行的时候,数据都是在内存中的。当程序终止的时候,通常都需要将数据保存到磁盘上,无论是保存到本地磁盘,还是通过网络保存到服务器上,最终都会将数据写入磁盘文件。
而如何定义...
OpenLayers 3对OpenLayers网络地图库进行了根本的重新设计。版本2虽然被广泛使用,但从JavaScript开发的早期发展阶段开始,已日益现实出它的落后。 OL3已运用现代的设计模式从...
他的最新文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)openlayers with google maps 教程 - 简书
openlayers with google maps 教程
what is openlayer
openlayers是一个高性能、功能全面的地图库。有以下特性:
支持各种格式的tiled layers数据
使用canvas的高性能vector layer
细粒度丰富的交互操作
支持commanjs风格
why use it
一般来说google map api就满足需求了,但是当需要在地图上绘制大量节点时,使用svg来显示部件就会出现很严重的性能问题,一般情况下google maps等的编辑操作也不够流畅。而openlayers使用canvas作为矢量层,大量的点线面信息对于canvas的影响是较小的,而且canvas的交互也更加流畅。
why write this article
与高德地图、google maps、百度地图等国内常用地图没有很方便的接口
大版本更新后官方文档不全面而且不够清晰,没有guild
而且网上简明详细的教程很少
针对以上几点,觉得自己的小经验会对大家有所帮助,可以少走些弯路,也是对自己这几天工作的一个总结。
a simple example(step by step)
下面通过一个简单地小例子介绍openlayers的一些基本用法,以及我觉得重要的地方。
需要使用google map或者高德地图作为底图,在地图上绘制一个矩形,实现矩形的编辑并且能够得到矩形被修改之后的回调函数。大概会涉及到这些技术点:
如何与google map等地图组合使用
知道坐标数组或者某格式的geo数据,如何在地图上添加feature
完成feature的修改
得到feature修改后的回调方法
附上简单截图
初始化地图
我们希望openlayer能和google map等组合使用,但是由于google等地图厂商不愿意向openlayer“妥协”,因此现在无法直接使用Tiled Layers,但我们可以将openlayer与地图api组合起来使用。
只使用地图的底图,在底图上覆盖一层 openlayer 的 canvas 层来显示数据并拦截与底图之间的交互,通过地图的 api 来重设状态。此方案还有以下优点:
解决了页面节点过多之后的性能问题
底图可以被抽象出去,能够在不影响交互逻辑的基础上更换底图。
代码如下:
&!DOCTYPE html&
&title&Snap interaction example&/title&
&script src="/jquery-1.11.2.min.js"&&/script&
&link rel="stylesheet" href="/bootstrap/3.3.4/css/bootstrap.min.css"&
&script src="/bootstrap/3.3.4/js/bootstrap.min.js"&&/script&
&link rel="stylesheet" href="/ajax/libs/ol3/3.6.0/ol.css" type="text/css"&
&script src="/ajax/libs/ol3/3.6.0/ol.js"&&/script&
&script src="/maps/api/js"&&/script&
&style type="text/css"&
div.fill {
width: 100%;
height: 100%;
width: 800
height: 400
&div class="container-fluid"&
&div class="row-fluid"&
&div class="span12"&
&div id="map" class="map"&
&!-- gmap用于加载google maps, olmap用于加载openlayer canvas。
目标是加载完毕之后olmap覆盖与gmap之上并且拦截交互操作。
开始时放在同一层的好处是都能根据父节点来设置长宽。也可以在js中动态生成div,渲染后插入 --&
&div id="gmap" class="fill"&&/div&
&div id="olmap" class="fill"&&/div&
&script type="application/javascript"&
// 加载google map并禁用地图的交互操作
var gmap = new google.maps.Map(document.getElementById('gmap'), {
disableDefaultUI: true,
keyboardShortcuts: false,
draggable: false,
disableDoubleClickZoom: true,
scrollwheel: false,
streetViewControl: false
// ol.View 是openlayers用于控制地图的 坐标系标准 zoom center rotate等操作的对象,在实例化map时候需要使用
var view = new ol.View({
// make sure the view doesn't go beyond the 22 zoom levels of Google Maps
maxZoom: 21,
projection: 'EPSG:4326' // 设置为标准经纬度的坐标标准,十分重要! 默认是'EPSG:3857'
// view 拖动时触发事件,根据当前的坐标转化为经纬度,调用谷歌地图setCenter方法同步地图位置
view.on('change:center', function () {
var center = view.getCenter();
gmap.setCenter(new google.maps.LatLng(center[1], center[0])); // 注意顺序
// 同上,更改焦距时触发的时间
view.on('change:resolution', function () {
gmap.setZoom(view.getZoom());
// ol.source.Vector 作为 ol.layer.Vector的数据集,增删改feature的方法由source提供
var vectorSource = new ol.source.Vector();
var vector = new ol.layer.Vector({
source: vectorSource
var olMapDiv = document.getElementById('olmap');
var map = new ol.Map({
layers: [vector], // 所使用的图层
// 禁用掉默认的拖动、旋转等交互
interactions: ol.interaction.defaults({
altShiftDragRotate: false,
dragPan: false,
rotate: false
}).extend([new ol.interaction.DragPan({kinetic: null})]),
target: olMapDiv,
view: view
// 这里可以使用 new ol.View({options}) 但是在这里需要通过手动设置来触发google maps调节到正确地zoom与center
view.setCenter([10., -25.]); // 如果未设置view的坐标标准,这里千万要注意不要直接写经纬度
view.setZoom(6);
// 设置缩放等级
// 将openlayers容器放置到google地图容器中
olMapDiv.parentNode.removeChild(olMapDiv);
gmap.controls[google.maps.ControlPosition.TOP_LEFT].push(olMapDiv);
有了这段代码应该就有了一个可以拖动缩放的地图了。
添加feature
当然光有一个地图是不行的,如果需要往地图上面添加feature怎么办呢?大致有以下两种场景:
提供整个地图的信息描述数据,比如geoJson,WKT或者自定义的数据结构等,需要解析整个数据并批量显示在地图上。
拿到某个feature的坐标数据,需要添加到地图上,并实现特异化的控制。
批量添加数据
* 将geoJson字符串解析后添加到地图中
* @param vectorSource {ol.source.Vector} 需要添加feature的矢量层数据对象
* @param data {string} geoJson字符串
function addFeatures(vectorSource, data){
vectorSource.addFeatures(ol.format.GeoJSON.readFeatures(data, {
// 数据的坐标code
dataProjection: 'EPSG:3857',
// 地图view使用的坐标code
featureProjection: 'EPSG:4326'
ol.format下有很多种数据类型,选择匹配的数据格式。比如WKT使用ol.format.WKT.readFeature
readFeature返回的是ol.Feature的数组,可以通过遍历其来获得feature对象,从而按需求修改或者挂载监听事件。
添加单个feature
如果现有的数据是geoJson等标准格式的数据,可以通过ol.format中的类进行转换。如果有需求则使用ol.proj.transform进行坐标系转换。
// 返回单个feature对象
var feature = ol.format.GeoJSON.readFeature(data)
// 添加到source
vectorSource.addFeature(feature);
如果拿到的是经纬度信息,添加一个polygon
// data 是一个coordinates的二维数组 需要注意
var feature = new ol.feature(new ol.geom.Polygon(data));
修改feature
介绍如何修改feature以及挂载监听事件。
初始化修改添加、修改交互
// 声明选择交互
var select = new ol.interaction.Select({
// 根据 feature editable 选项来判断是否可以选中
filter: function(feature) {
if (_this._featureMap[feature.getId()].editable) {
// 得到被选中元件的对象
var selected = select.getFeatures();
// 声明修改交互,可以修改被选中的feature
var modify = new ol.interaction.Modify({
features: selected
// 当新元件被选中时触发
selected.on('add', event =& {
var feature = event.element
// 当元件被取消选中时触发,一般把元件的修改回调放在这
selected.on('remove', evt =& {
var feature = evt.
var fid = feature.getId();
// 判断元件是否被修改还是需要feature的change事件
console.log(fid);
// 在interactions中添加
this._map = new ol.Map({
layers: [vector],
interactions: ol.interaction.defaults({
altShiftDragRotate: false,
dragPan: false,
rotate: false
}).extend([new ol.interaction.DragPan({kinetic: null}), select, modify]),
target: $olMapDiv,
view: this._view
一般来说如果需要后续对feature进行操作,可以使用getId方法拿到feature的id,可以通过setId来设置自己想要的id,否则会自动生成。 将id存在常驻的对象中供以后使用。
假设拿到ol.Feature对象 feature
feature.on('change:geometry', function(e){
var feature = e.
// do what you want
比如标记元件已被修改
需要注意的是这个onChange事件在修改的过程中会不断地触发,如果需要的是修改完成之后的回调,需要使用select的remove事件。
select.getFeatures().on('remove', function(e){})
修改feature对象
feature.setId(id)
得到geometry对象
var geometry = feature.getGeometry();
// 通过调用geometry类的方法修改元件坐标
feature to string
var format = new ol.format.GeoJSON();
format.writeFeature(feature);
需要注意的地方
openlayers默认的坐标系是'EPSG:3857',标准经纬度坐标系是'EPSG:4326'
看openlayer文档最重要的技巧是注意类型
geometry接受的coordinates其实是一个三维数组,一定要注意
坐标系转换
根据当前坐标系与目标坐标系进行转换。
ol.proj.transform(coordinate, source, destination)coordinate 在文档中得类型是 Coordinate其实就是一个有横纵坐标组成的数组,因此一定要注意官方文档中得数据类型。source 当前坐标编码
string类型destination 目标坐标编码 string类型
从经纬度转化到指定坐标系
ol.proj.fromLonLat(coordinate, opt_projection)opt_projection 目标坐标编码 string类型
从某坐标转经纬度
ol.proj.toLonLat(coordinate, opt_projection)
数据格式化
来自二次元的前端工程师}

我要回帖

更多关于 interaction.select 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信