当前位置: 移动技术网 > IT编程>开发语言>JavaScript > openLayers 3知识回顾

openLayers 3知识回顾

2018年12月25日  | 移动技术网IT编程  | 我要评论

陈慧琳合成图,点睛网,002578

openlayers 知识


前段时间帮助同事重构一个地图类的项目,然后就学习了openlayer3这个框架,但是官网上没有中文版,也没有详细的例子解释,我只能遇到看不懂的就翻译成中文来用,为了方便以后再用这个ol,能够更快的上手,就花了几天的时间总结了ol的知识,ol功能很丰富,api也很多,没有写太多,只是写了怎么用的,只要学会了根本,就可以很快的使用api去操作map。

另外,在总结知识的同时,还写了demo,加深自己的理解,大家觉得不错的话,给个star~ github

那么开始吧!

目录

var map = new ol.map({
    target:'map',
    layers:[],
    view:views,
    interactions:interactions,
    controls:controls,
})

map是openlayers的核心组件,所有的操作方法以及渲染都是挂载到map上面。创建的map对象需要传一个对象进去,最常见的就有以下几个属性,

* target --> 地图的挂载元素,就是在html元素里声明的id
* layers --> 层,是个数组,可以放很多层,如果未定义,则将呈现没有图层的地图,图层是按照提供的顺序渲染的,因此,如果您希望(例如)矢量图层显示在图块图层的顶部,则它必须位于图块图层之后。
* view  --> map的视图,
* interactions --> 交互,比如鼠标事件导致放大,缩小,旋转之类的,默认都是true
* controls --> 控件,类似与按钮,有放大,缩小,全屏等的按钮 

最简单的显示地图:

document.body.innerhtml = `<div id="map" style="height:400px;width:100%"></div>`;

var map = new ol.map({
    target:'map',
    layers:[new ol.layers.tile({
        source: new ol.source.osm()
    })],
    view: new ol.view({
        center:[0,0],
        projection: 'epsg:4326',
        zoom:10,
    }),
    interactions: ol.interaction.defaults({
        doubleclickzoom:false,
        altshiftdragrotate:false
    }),
    controls: ol.control.defaults({
        attribution: false,
    })
})

map

这个map不是里面的map,而是初始化后的map,map = new ol.map();在openlayers3 的api中,有很多方法,可以通过方法去操作layers,view,interactions,controls。
打印map,可以发现map里面有很多属性,可以简单知道map上有多少个层,target是谁,size是多少等等,也可以通过api方法去获取

var target = map.gettarget();    // 获取 target的值  -- map
var size = map.getsize();  // 获取可视区域的宽高。

同样的,也可以在map上设置

map.addcontrol(new ol.control.fullscreen()); // 添加全屏控件
map.addlayers( new ol.layer.vector({
    source:new ol.source.vector()
}))  // 添加一个矢量图层

*map里有一个函数方法,可以通过点击某个图层或某个点而获取到当前的层和信息。
foreachfeatureatpixel(pixel, callback, opt_options)
params: pixel:坐标
callback:回调函数,将使用两个参数调用回调,第一个是feature,第二个是layers
opt_options:可选

map.on('click',function(e){
    var feature = map.foreachfeatureatpixel(e.pixel,function(f){
        return f;
    })
    console.log(feature);   // ol.feature
})

view

视图.view对象表示地图的简单2d视图。这是用于更改地图的中心,分辨率和旋转的对象。
一个视图是由三种状态确定:center,resolution,zoom和rotation。每个状态具有相应的获取和设置。

  • center:初始坐标,比如:成都的位置 [104.06, 30.67],这样地图初始化会以成都为中心展开(projection:'epsg:4326')。
  • projection:一个视图有一个projection。投影确定中心的坐标系,其单位确定分辨率的单位(每像素的投影单位)。
    projection有两种值,默认投影是球形墨卡托(epsg:3857),是地图的xy坐标,另一种就是经纬度坐标,(epsg:4326)是wgs84的一种。
    通过一个方法可以进行epsg:3857与epsg:4326转化。
    经纬度转至xy(epsg:4326->epsg:3857)
    ol.proj.transform(coordinates,'epsg:4326','epsg:3857')
    xy转至经纬度(epsg:3857->epsg:4326)
    ol.proj.transform(coordinates,'epsf:3857','epsg:4326')
  • zoom:计算视图初始分辨率的缩放级别。至于resolution初始分辨率,在其未声明时,zoom起作用。对应的它也有maxzoom,minzoom。
  • rotation:初始旋转度,默认是0,(顺时针正向旋转,0表示北向),弧度制
var view = new ol.view({
    center:[104.06,30.67],
    projection:'epsg:4326',
    // center: ol.proj.transform([104.06,30,67],'epsg:4326','epsg:3857');    // 这个和上面的结合体。
    zoom:10,
    rotation:math.pi/10,
})

视图对应的也有get和set系列的方法,用于获取和设置zoom,center,rotation等等,除此之外,还有约束方法,constrainrotation(),约束旋转度,api上有详细解释。

map.getview()   // 就是当前视图,view
view.getzoom()  // 获取缩放级别;
view.getcenter() // 获取初始中心坐标
view.setcenter([20,30])  // 设置初始中心[20,30],也可以用ol.proj.transform
view.constrainrotation(2,5) // 获取此视图的约束旋转

layers

层,是一个对象数组,将那些与数据显示方式相关的属性组合在一起,形成一个层,openlayer就是由一个一个的层形成的,包括地图,瓦片地图,图片,图形都是由layer形成而呈现在map上的
简单的来说,layer可以是一个地图,也可以是一个图形,也可以是个图片,因为是个数组,可以互相叠加的,[map,image,shape],在相同位置的情况下,后者会覆盖前者。

layer

根据这个图片可知,layers有三种形式

  • ol.layer.tile 瓦片,瓦片地图源于一种大地图解决方案,针对一整块非常大的地图进行切片,分成很多相同大小的小块地图,在用户访问的时候,再一块一块小地图加载,拼接在一起,从而还原成一整块大的地图。这样做的优点在于,用户在同一时间,同一个可见视图内,只能看到地图的一部分,而不是全部。提高用户体验。通常用这个作为底图。
  • ol.layer.image 对应的是一整张图,而不像瓦片那样很多张图,从而无需切片,也可以加载一些地图,适用于一些小场景地图
  • ol.layer.vector 矢量,使用直线和曲线来描述图形,这些图形的元素是一些点、线、矩形、多边形、圆和弧线等等,它们都是通过数学公式计算获得的。由于矢量图形可通过公式计算获得,所以矢量图形文件体积一般较小。矢量图形最大的优点是无论放大、缩小或旋转等不会失真。

每个形式都需要一个source,数据源,所以每一个形式都对应一个数据源,source和layer是一对一的关系,有一个source,必然需要一个layer,然后把这个layer添加到map上,就可以显示出来了。

ol.layer.tile

对于瓦片数据源,也有很多属性,

  • opacity,改变透明度,默认是1
  • visible,可视,默认是true
  • zindex,图层渲染的z-index。在渲染时,将按照z-index然后按位置对图层进行排序
  • source 有很多形式,
  • 在线服务的source
    • ol.source.osm
    • ol.source.bingmaps
    • ol.source.tileimage
  • 支持协议标准的source,包括ol.source.tilearcgisrest,ol.source.tilewms,ol.source.wmts,ol.source.utfgrid,ol.source.tilejson。如果要使用它们,首先你得先学习对应的协议,之后必须找到支持这些协议的服务器来提供数据源,这些服务器可以是地图服务提供商提供的,也可以是自己搭建的服务器,关键是得支持这些协议。
  • ol.source.xyz,而且现在很多地图服务(在线的,或者自己搭建的服务器)都支持xyz方式的请求。国内在线的地图服务,高德,天地图等,都可以通过这种方式加载的
var osmtile = new ol.layer.tile({ 
    source:new ol.source.osm()  
})
var qqtile = new ol.layer.tile({
    source: new ol.source.xyz({
        url: 'http://map.geoq.cn/arcgis/rest/services/chinaonlinecommunity/mapserver/tile/{z}/{y}/{x}'
    }),
})
map.addlayer(osmtile);  // 添加open street map作为底图
map.addlayer(qqtile)  // 添加腾讯地图

map.addlayer()这个方法就相当于初始化中的layers的数组中添加一样,如下代码,这俩是等价的,只不过后者更灵活些。

var map = new ol.map({
    layers:[osmtile,qqtile]
})  // 等价于下面
map.addlayer(osmtile); 
map.addlayer(qqtile)

ps!当添加地图作为底图时,会发现腾讯底图覆盖率osm地图,是因为layer是一个数组,遵遁先来先渲染,后来居上的原则。
layer也有get/set方法,用来设置或获取属性,其实通过api就可以知道响应方法去操作。

ol.layer.image

关于静态图片层,运用的不多,一般作为写死的,不经常换的实例中。
同样,ol.layer.image也有数据源,一般就是ol.source.imagestatic,ol.source.imagecanvas等等。

var center = ol.proj.transform([104.06667, 30.66667], 'epsg:4326', 'epsg:3857');
// 计算静态图映射到地图上的范围,图片像素为 550*344,保持比例的情况下,把分辨率放大一些
var extent = [center[0]- 550*1000/2, center[1]-344*1000/2, center[0]+550*1000/2, center[1]+344*1000/2];
var imagestatic = new ol.layer.image({
    source: new ol.source.imagestatic({
        url: '../pandabase.jpg', // 静态图
        imageextent: extent     // 映射到地图的范围
    })
})
map.addlayer(imagestatic);
ol.layer.vector
矢量图层,是用来渲染矢量数据的图层类型,在openlayers里,它是可以定制的,可以控制它的透明度,颜色,以及加载在上面的要素形状等。常用于从数据库中请求数据,接受数据,并将接收的数据解析成图层上的信息。比如将鼠标移动到中国,相应的区域会以红色高亮显示出来,高亮便是矢量图层的行为

既然是个矢量图,可以改变大小,颜色,以及形状。包含source数据源类,style类设置样式,以及其他的zindex,opacity等等。
feature类是vector类用来在地图上展示几何对象,是vector图层类一个属性。这个属性是个*要素数组*。

source

对应的数据源ol.source.vector也是个对象。最常见属性的是featuresformat以及url。通常url和format一块,url按理传来的是geojson格式的矢量图,需要format格式化一下。最常用还是features。
ol.feature

  • feature 具有几何和其他属性属性的地理要素的矢量对象,类似于geojson等矢量文件格式中的要素。
  • geometry类是feature对象的基本组成部分,vector类采用geometry类来存储一个要素的几何信息.通过feature名.getgeometry()获取
  • feature类有两个部分,geometry对象和attributes属性,attributes包含要素相关的数据。比如:{type:'circle'},通过getproperties().attributes去获取。
    geometry
  • new ol.geom.point([x1,y1]) 点
  • new ol.geom.linestring([[x1,y1],[x2,y2]]) 线
  • new ol.geom.linearring()
  • new ol.geom.multilinestring([[[x1,y1],[x2,y2]],[[x3,y3],[x4,y4]],[...]]) 多条线
  • new ol.geom.multipoint([[x1,y1],[x2,y2],[...]]) 多个点
  • new ol.geom.polygon([[[x1,y1],[x2,y2],[x3,y3],[x4,y4],[...],[x1,y1]]]) 几何
    如果这些坐标是经纬度坐标的话,都需要坐标转换applytransform(ol.proj.gettransform('epsg:4326', 'epsg:3857')),(部分图形展示请看demo)
var polygon = new ol.geom.polygon([[[110, 39], [116, 39], [116, 33], [110, 33], [110, 39]]]);
polygon.applytransform(ol.proj.gettransform('epsg:4326', 'epsg:3857')); // 坐标转换
var square = new ol.feature({
    geometry:polygon
})
layer.getsource().addfeature(square)
style
一个style对象,包含style类,有7个属性:
  • geometry 返回要为此样式渲染的几何的要素属性或几何或函数
  • fill 填充样式。
  • image 图像样式
    • icon : new ol.style.icon()
      • anchor :[0.5,0.5]锚点,
      • color
      • src :图标源
      • ...
    • circle: new ol.style.circle()
      • fill :new ol.style.fill()
      • radius : 半径
      • stroke :new ol.style.stroke()
    • regularshape :new ol.style.regularshape()
      • fill :new ol.style.fill()
      • points : 点数,几个点
      • radius : 半径
      • radius1 : 外半径
      • radius2 : 内半径
      • angle 0 形状的角度以弧度表示。值为0将使其中一个形状的点朝上。
      • stroke :new ol.style.stroke()
      • rotation : 0 旋转度
      • ...
  • renderer 自定义渲染器。配置时fill,stroke和image将被忽略,并且将为每个几何体的每个渲染帧调用提供的函数。
  • stroke 边线样式
    • color 颜色
    • linecap :butt, round, square 线帽
    • linejoin :bevel, round, miter. 线条连接形状
    • width 宽度
  • text 文字样式
    • font :'10px sans-serif'
    • text
    • textalign left','right','center','end' start'
    • fill :new ol.style.fill()
    • stroke :new ol.style.stroke()
    • backgroundfill
    • padding
  • zindex 层级
    // set*()在重新呈现使用该样式的要素或图层之前,通过方法对样式或其子项所做的任何更改都不会生效
// 最简单的呈现方式,复杂的请参考demo
var layer = new ol.layer.vector({
    source: new ol.source.vector({
        features:[new ol.feature({
            geometry: new ol.geom.point(ol.proj.transform([104, 30], 'epsg:4326', 'epsg:3857')),
        })]
    }),
    style: new ol.style.style({
        image: new ol.style.circle({
            radius: 30,
            fill: new ol.style.fill({
                color: 'red'
            })
        })
    }),
    opacity:0.5
})
map.addlayer(layer)

一个层layer有一个featrue,也可以有多个feature,因为feature类是vector类用来在地图上展示几何对象,是vector图层类一个属性。这个属性是个*要素数组*。
对于style样式问题,feature的style的层级比layer.vector的层级要高,所以feature的style会覆盖layer的style。
ps:feature中的样式不能以属性名的形式写,因为feature类中没有style属性名,只有geometry,所以要以方法的形式去添加,setstyle()。

其实关于layer,vector,api上都有其方法,包括set/get,虽然类有很多子类,子类又有很多子子类,也无妨,只要抓住想要操作的是哪一个部分就行,是feature,还是layer,还是geometry等等。

stylefunction
feature中可以使用stylefunction来设置自己随心所欲的样式,通过官网api文档可以看到,其类型为ol.featurestylefunction,函数仅带有一个参数resolution,在函数体内this指的是当前的feature,根据文档说明,这个函数要返回一个style数组。
除了feature可以设置样式之外,layer也是可以设置样式的,同样地也支持stylefunction,但是需要注意的是,其定义和feature的不一样,类型为ol.style.stylefunction,该函数具有两个参数,第一个参数为feature,第二个参数为resolution,同样地,该函数需要返回style数组。

var layer = new ol.layer.vector({
    source: new ol.source.vector()
})
var map = new ol.map({
    layers: [
        new ol.layer.tile({
        source: new ol.source.osm()
        }), 
        layer
    ],
    target: 'map',
    view: new ol.view({
        projection: 'epsg:4326',
        center: [104, 30],
        zoom: 10
    })
});

var anchor = new ol.feature({
    geometry: new ol.geom.point([104, 30])
});
// 应用style function,动态的获取样式
anchor.setstyle(function(resolution){
    return [new ol.style.style({
        image: new ol.style.icon({
        src: '../img/anchor.png',
        scale: map.getview().getzoom() / 10
        })
    })];
});

layer.getsource().addfeature(anchor);

controls

地图控件,包括缩放按钮,标尺,版权说明,指北针等等,不会随着地图的放大而放大,缩小而缩小,就相当于position:fixed一样,固定在某个地方。 在实现上,并不是在画布上绘制的,而是使用传统的html元素来实现的,便于同地图分离,也便于界面实现。
在openlayers 3 中,默认情况下,在地图上是不会显示这么多地图控件的,只会应用ol.control.defaults()这个函数返回的地图控件,默认包含了ol.control.zoom,ol.control.rotate和ol.control.attribution这个控件。
openlayers 3目前内置的地图控件类都在包ol.control下面:

  • ol.control.attribution: 右下角的地图信息控件
  • ol.control.fullscreen: 全屏控件
  • ol.control.mouseposition: 鼠标位置控件
  • ol.control.overviewmap: 鸟瞰图控件
  • ol.control.rotate: 指北针控件
  • ol.control.scaleline: 比例尺控件
  • ol.control.zoom: 缩放按钮控件
  • ol.control.zoomslider: 缩放滚动条控件
  • ol.control.zoomtoextent: 放大到设定区域控件
var map = new ol.map({
    target:'map',
    layers:[new ol.layers.tile({
        source: new ol.source.osm()
    })],
    view: new ol.view({
        center:[0,0],
        projection: 'epsg:4326',
        zoom:10,
    })
    controls: ol.control.defaults({
        attribution: false, // 信息false
        rotate: false,    // 旋转false
        zoom: false      //   缩放false
    })
})

map.getcontrols()是获取控件的信息,
如果想要添加其他的控件,可以使用map中的一个方法,map.addcontrol()

map.addcontrol(ol.control.overviewmap)  // 添加鸟瞰图控件

控件不是在画布上绘制的,而是用html实现的,所以样式问题可以按照css+html的形式去修改。

interactions

交互,就是人与机之间的交互模式,比如用鼠标左键双击地图可以放大地图,按住鼠标左键拖动地图可以移动浏览地图,用滚动鼠标中间的滑轮可以放大缩小地图等等。这些都是openlayers内置的,其实也可以自己去interact。

内置的交互

内置的交互在map中都是默认的。

var map = new ol.map({
    interactions: ol.interaction.defaults().extends()
    // .... 其余代码
})

ol.interaction.defaults()默认包含以下交互:

  • 鼠标
    • 按住alt+shift键,用鼠标左键拖动地图,就能让地图旋转,对应的交互类为ol.interaction.dragrotate。
    • 用鼠标左键双击地图,就可以放大地图,对应的交互类为ol.interaction.doubleclickzoom。
    • 用鼠标左键,拖拽地图,就可以平移地图,对应的交互类为ol.interaction.dragpan。
    • 滚动鼠标中间的滑轮,就可以缩放地图,对应的交互类为ol.interaction.mousewheelzoom。
    • 按住shift键,同时用鼠标左键在地图上拖动,就可以放大地图,对应的交互类为ol.interaction.dragzoom。
  • 触摸屏
    • 在触摸屏上,用两个手指在触摸屏上旋转,就可以旋转地图,对应的交互类为ol.interaction.pinchrotate。
    • 在触摸屏上,用两个手指在触摸屏上缩放,就可以缩放地图,对应的交互类为ol.interaction.pinchzoom。
  • 键盘(注意:需要设置tabindex,才能使div获得键盘事件,就是在声明id的那个div中添加:tabindex="0")
    • 用键盘上的上下左右键,就可以平移地图,对应的交互类为ol.interaction.keyboardpan。
    • 用键盘上的+/-键,就可以缩放地图,对应的交互类为ol.interaction.keyboardzoom。

如果想要取消某个交互事件

var map = new ol.map({
    interactions: ol.interaction.defaults({
        mousewheelzoom: false, // 取消滚动鼠标中间的滑轮交互
        shiftdragzoom: false, // 取消shift+wheel左键拖动交互
    })
    // .... 其余代码
})

extend()为扩展

var map = new ol.map({
    interactions: ol.interaction.defaults().extend()
    // .... 其余代码
})

map.getinteraction()是获取控件的信息,
如果想要添加其他的交互,可以使用map中的一个方法,map.addinteraction()

map.addinteraction(new ol.interaction.mousewheelzoom); 

关于new interaction(),总共有7个子类,可以用在extend([])中,也可以用addinteraction()

  • doubleclickzoom interaction,双击放大交互功能;
  • draganddrop interaction,以“拖文件到地图中”的交互添加图层;
  • dragbox interaction,拉框,用于划定一个矩形范围,例子常用于放大地图;
  • dragpan interaction,拖拽平移地图;
  • dragrotateandzoom interaction,拖拽方式进行缩放和旋转地图;
  • dragrotate interaction,拖拽方式旋转地图;
  • dragzoom interaction,拖拽方式缩放地图;
  • draw interaction,绘制地理要素功能;
  • keyboardpan interaction,键盘方式平移地图;
  • keyboardzoom interaction,键盘方式缩放地图;
  • select interaction,选择要素功能;
  • modify interaction,更改要素;
  • mousewheelzoom interaction,鼠标滚轮缩放功能;
  • pinchrotate interaction,手指旋转地图,针对触摸屏;
  • pinchroom interaction,手指进行缩放,针对触摸屏;
  • pointer interaction,鼠标的用户自定义事件基类;
  • snap interaction,鼠标捕捉,当鼠标距离某个要素一定距离之内,自动吸附到要素。

这些子类都可以查api,有详细解释。这些子类中,有个常用的属性condition或方法handleevent(mapbrowserevent)

condition

代表的是事件名称,比如:click,doubleclick,主要是依据ol.events。主要有以下几种,默认是singleclick

  • altkeyonly 仅按下alt键则返回true
  • shiftkeyonly 仅按下shift键则返回true
  • altshiftkeysonly 仅按下alt键+shift则返回true
  • always
  • never
  • click,只要是点击,包括singleclick,doubleclick都返回true
  • doubleclick
  • singleclick
  • focus 如果地图具有焦点,则返回true。此条件需要具有tabindex属性的地图目标元素,例如
  • mouseonly 从鼠标设备发起为true
  • nomodifierkeys 没有组合键则返回true
  • pointermove 指针移动时返回true
  • targetnoteditable 如果目标元素不可编辑,则返回true,即不是input,select或textarea元素false。
  • platformmodifierkeyonly
  • primaryaction 从一个主指针在与表面接触或起源如果按下鼠标左键

handleevent(mapbrowserevent)

function (mapbrowserevent){
    return ol.events.condition.click(mapbrowserevent) && ol.events.condition.shiftkeyonly(mapbrowserevent);
}
select

是个选择图形的类,用于交互.
new ol.interaction.select(options)
options是个对象参数,包括:

  • style
  • layers 应从中选择要素的图层列表。或者,可以提供过滤功能。将为地图中的每个图层调用该函数,并应返回true您想要选择的图层。如果该选项不存在,则所有可见图层都将被视为可选择。
  • condition 类型为 ol.events.conditiontype,规定了什么情况下触发 select 操作,默认不需要特殊条件进行触发。
  • addcondition
  • removecondition
  • togglecondition 获取module:ol/mapbrowserevent-mapbrowserevent和返回布尔值的函数,以指示是否应该处理该事件。这是condition事件的补充。默认情况下, module:ol/events/condition-shiftkeyonly即按下shift以及condition事件,如果当前未选中,则将该功能添加到当前选择,如果是,则将其删除。见add而remove 如果你想使用的,而不是一个触发不同的事件。
  • multi 用于确定默认行为是否应仅在单击的地图位置选择单个feature或所有(重叠)feature。默认值false表示单选。
  • features
  • filter 过滤 见demo
  • wrapx 当地图水平显示多个相同位置时,是否显示多个勾绘任务,默认为 false
    select点击事件
selectsingleclick.on('select', function (event) {
    console.log(event)
})

该select也有set/get方法,用来获取或者设置属性,比如获取选中的features,获取所有属性名称和值的对象getproperties。

draw

是个绘制图形的类,默认支持绘制的图形类型包含 point(点)、linestring(线)、polygon(面)和circle(圆)。触发的事件包含 drawstart和drawend,分别在勾绘开始时候(单击鼠标)和结束时候触发(双击鼠标)。
new ol.interaction.draw(options)
options是个对象参数,包括:

  • type: 几何类型(加粗为默认)
    • point
    • linestring
    • linearring
    • polygon
    • multipoint
    • multilinestring
    • multipolygon
    • geometrycollection
    • circle
  • source 数据源,如果想要保存绘制的图形,需要有一个载体来存储绘制的图形,比如新建一个layer,这个layer的source就是该绘制的source。
    •   var drawlayer = new ol.layer.vector({
            source:new ol.source.vector()
        }) // 新建一个层
        map.addlayer(drawlayer)
        var draw = new ol.interaction.draw({
            source: drawlayer.getsource(), // 数据源就是新建层的数据源
            type: 'point',
        })
        map.addinteraction(draw);
  • style
  • stopclick
  • condition 类型为 ol.events.conditiontype,规定了什么情况下触发 draw 操作,默认不需要特殊条件进行触发。
  • clicktolerance: 数值类型,单位是像素,判断用户鼠标(pc)或者手指(移动设备)的行为是添加点,还是按住鼠标或者手指不松开进行拖拽地图,默认值是 6 像素,也就是说当按下鼠标和抬起鼠标左键之间的这段时间段内,如果地图被拖动没有超过 6 像素,那么默认为添加一个点,相反如果超过了 6 像素,那么不会添加点,只是平移一下地图。
  • snaptolerance 数值,像素为单位,默认值是 12 像素,当一定位置内最后一个点吸附到第一个点,对多边形时有用
  • features
  • maxpoints 表示绘制单个要素(面和线)最多的点数限制,默认没有限制
  • minpoints 表示绘制单个要素(面和线)需要的最少点数,面默认为 3,线默认为 2
  • geometryname 字符串类型,绘制的 geometry 的名称。
  • geometryfunction 因为默认type只有四种:point(点)、linestring(线)、polygon(面)和circle(圆),此方法就是可以用来绘制规则或者自己想要绘制的图形的方法,该函数有两个参数,一个是坐标集合、一个是勾绘的 geometry 类型,返回构造好的 geometry 对象,用来初始化要素。
    •   var draw = new ol.interaction.draw({ // 绘制矩形
            type: 'linestring',
            maxpoints: 2,
            geometryfunction: function(coordinates, geometry){
                if(!geometry){
                    geometry = new ol.geom.polygon(null);
                }
                var start = coordinates[0];
                var end = coordinates[1];
                geometry.setcoordinates([
                    [start, [start[0], end[1]], end, [end[0], start[1]], start]
                ]);
                return geometry;
            }
            // 其余代码块
        })
    • 上面的例子用linestring的形式去绘制矩形,这里的原理就是捕捉鼠标点击的点,然后获取限制的两个点的坐标,用来初始化一个矩形框。
  • wrapx 当地图水平显示多个相同位置时,是否显示多个勾绘任务,默认为 false
  • freehand 默认是false,是否以曲线的形式,不是规范化的,看demo-freehanddraw.html
  • freehandcondition 类型同condition,也是 ol.events.conditiontype,这个选项规定了什么情况下触发不用重复点击绘制模式,即拖拽鼠标就可以绘制图形的模式,默认情况下是按下 shift 按键,这种模式对于不容易绘制的曲线比较方便,而且释放 shift 情况下,如果没有完成绘制,可以继续使用点击绘制。(就是需要辅助键,例如shift,ctrl时,会以曲线形式绘画)--demo-seconddraw.html,按shift绘画可以发现。
    drawstart/drawend
// 绘制结束时进行回调
draw.addeventlistener('drawend', function (evt) {
    // 获取绘制图形的所有坐标点(终止点是起始点)
    var feature = evt.feature
    var geometry = feature.getgeometry()
    var coordinate = geometry.getcoordinates()
    // console.log(coordinate)
    var lent = coordinate[0].length // 坐标点个数
})
modify

用于修改要素几何的交互。要修改已添加到现有源的功能,请使用该source选项构建修改交互,如果要修改集合中的要素(例如,选择交互使用的集合),请使用该features选项构建交互。必须使用source或features构建交互
默认情况下,交互将允许在alt 按下键时删除顶点。要配置具有不同删除条件的交互,请使用该deletecondition选项。
new ol.interaction.modify(options)
options是一个参数对象,如下:

  • condition
  • style
  • source
  • features
  • wrapx
  • insertvertexcondition 一个函数,它接受module:ol/mapbrowsereventmapbrowserevent并返回一个布尔值,以指示是否可以将新顶点添加到草图要素中。默认是module:ol/events/condition-always。 同deletcondition
  • deletecondition 获取module:ol/mapbrowsereventmapbrowserevent和返回布尔值的函数,以指示是否应该处理该事件。默认情况下, module:ol/events/condition-singleclick与 module:ol/events/conditionaltkeyonly在顶点缺失的结果。看demo-modifydifficult.html(先选中后操作)
snap

在修改或绘制矢量要素时处理矢量要素的捕捉。这些功能可以来自一个module:ol/source/vector或module:ol/collection-collection 任何交互对象,允许用户使用鼠标与功能进行交互可以从捕捉中受益,只要它之前添加。

快照交互会修改地图浏览器事件coordinate和pixel 属性,以强制对其进行的任何交互进行快照。
new ol.interaction.snap(options) 看api
options:

  • features 应提供此选项或来源。
  • edge 抓住边缘。默认值时true
  • vertex 捕捉到顶点。默认值是true
  • source 捕捉此来源的功能。应提供此选项或功能

官方例子snap interaction

事件
简单例子
var map = new ol.map({
    layers: [
        new ol.layer.tile({
        source: new ol.source.osm()
        })
    ],
    target: 'map',
    view: new ol.view({
        center: ol.proj.transform(
            [104, 30], 'epsg:4326', 'epsg:3857'),
        zoom: 10
    })
});

// 监听singleclick事件
map.on('singleclick', function(event){
    // 通过geteventcoordinate方法获取地理位置,再转换为wgs84坐标,并弹出对话框显示
    alert(ol.proj.transform(map.geteventcoordinate(event), 'epsg:3857', 'epsg:4326'));
})

任意的事件应用,必然会有三个步骤:

  • 找准事件发送者,比如上面这个例子,map就是事件发送者。 如何找到它呢? 一般都是要交互的对象。
  • 找准事件名称,比如上面例子中的singleclick,切忌不要随便想象,或者按照惯例来写名称-condition,
  • 编写事件响应函数,在openlayers中,事件发送者都会有一个名字为on的函数,调用这个函数,就能监听指定的事件,响应函数listener具有一个参数event,这个event类就对应于api文档中事件名称后边括号里的类。
    foreachfeatureatpixel(pixel, callback, opt_options)

    注销事件
  •   // 创建事件监听器
      var singleclicklistener = function(event){
          alert('...');
          // 在响应一次后,注销掉该监听器
          map.un('singleclick', singleclicklistener);
      };
      map.on('singleclick', singleclicklistener);
  •   // 使用once函数,只会响应一次事件,之后自动注销事件监听
      map.once('singleclick', function(event){
          alert('...');
      })
    自定义事件

    要添加自定义事件,需要知道这样一个事实:ol.feature继承于ol.object,而ol.object具有派发事件(dispatchevent)和监听事件(on)的功能。

  • dispatchevent(event) 分发一个事件,并调用侦听此类事件的所有监听器,event参数可以是字符串,也可以是具有type属性的object
  • on(type, listener) 触发type类型的监听器。

// 为地图注册鼠标移动事件的监听
map.on('pointermove', function (event) {
    map.foreachfeatureatpixel(event.pixel, function (feature) {
        // 为移动到的feature发送自定义的mousemove消息
        feature.dispatchevent({ type: 'mousemove', event: event });
        // feature.dispatchevent('mousemove');
    });
});

// 为feature1(之前创建的一个feature)注册自定义事件mousemove的监听
feature1.on('mousemove', function (event) {
    // 修改feature的样式为半径100像素的园,用蓝色填充
    this.setstyle(new ol.style.style({
        image: new ol.style.circle({
            radius: 100,
            fill: new ol.style.fill({
                color: 'blue'
            })
        })
    }));
});
dispatchevent的参数具有type和event属性,必须这样构造吗?在回答这个问题之前,需要先看一下api文档,发现参数类型为goog.events.eventlike,说明它其实用的是google的closure库来实现的,通过closure库的源码我们知道,派发的事件如果是一个对象,那么必须包含type属性,用于表示事件类型。其他的属性可以自由定义,比如此处定义了event属性,并设置对应的值,为的是让鼠标事件传递给feature1的监听函数。dispatchevent的参数会被原封不动的传递给事件响应函数,对应代码`feature1.on('mousemove', function(event){}`里参数event,可以通过调试窗口看到此处的event和dispatchevent的参数是一样的。注意事件名称是可以自定义的,只要派发和监听使用的事件名称是一致的就可以。

除了可以通过dispatchevent({type: 'mousemove', event: event})这种形式派发一个事件之外,还可以通过dispatchevent('mousemove')这中形式直接发送mousemove事件。

总结

openlayers功能很多,有的地方自己因时间有限还没有深入了解,但是大部分是够用了,有大部分都是参考资料的,因为讲的很通透,所以就拿过来了。,对于openylayers3,一定多看看官方例子,例子有很多吸收的知识点,特别有用。有时间后会自己补上这一环节,大家如果有疑问或者我不对的地方请下方评论或私信。大家一起进步加油!

参考资料


如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网