在最基本的代码中,我们没有进行任何设置.移动鼠标就可以移动地图,滑动滚轮就可以实现缩放.
这些都是Openlayer内置好的交互.
所有的交互都是基于监听的,如果前面的事件监听器返回false,那么后面的交互类就不会起作用。
建议不要轻易在MapBrowserEvent事件的监听器里面返回false。
一、Feature选取之选中样式
<div id="map" style="width: 100%"></div>
<script type="text/javascript">
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({
center: ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
// 在地图上添加一个圆
var circle = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'))
circle.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'red'
layer.getSource().addFeature(circle);
// 前面的代码我们已经看了很多遍了,关键是下面这段代码
// 添加一个用于选择Feature的交互方式
var selectSingleClick = new ol.interaction.Select({
// API文档里面有说明,可以设置style参数,用来设置选中后的样式,但是这个地方我们注释掉不用,因为就算不注释,也没作用,为什么?
// style: new ol.style.Style({
// image: new ol.style.Circle({
// radius: 10,
// fill: new ol.style.Fill({
// color: 'blue'
// })
// })
// })
map.addInteraction(selectSingleClick);
// 监听选中事件,然后在事件处理函数中改变被选中的`feature`的样式
selectSingleClick.on('select', function(event){
event.selected[0].setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'blue'
</script>
上面注释里面说到的,为什么style参数设置了没用? 因为我们的circle本身就设置了样式,而style参数设置的样式,其实是设置在内部新建的一个layer上的,而OpenLayers 3中,feature的样式优先级是大于layer的样式的优先级的。所以没生效,如果换成下面这种方式,就可以了:
<!Doctype html>
<html lang="ch" >
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
<meta content=always name=referrer>
<title>OpenLayers 地图示例</title>
<link href="ol.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="ol.js" charset="utf-8"></script>
</head>
<div id="map" style="width: 800px;height: 800px"></div>
<script type="text/javascript">
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({
center: ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
// 在地图上添加一个圆
var circle = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'))
circle.setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'red'
layer.getSource().addFeature(circle);
// 前面的代码我们已经看了很多遍了,关键是下面这段代码
// 添加一个用于选择Feature的交互方式
var selectSingleClick = new ol.interaction.Select({
// API文档里面有说明,可以设置style参数,用来设置选中后的样式,但是这个地方我们注释掉不用,因为就算不注释,也没作用,为什么?
// style: new ol.style.Style({
// image: new ol.style.Circle({
// radius: 10,
// fill: new ol.style.Fill({
// color: 'blue'
// })
// })
// })
map.addInteraction(selectSingleClick);
// 监听选中事件,然后在事件处理函数中改变被选中的`feature`的样式
selectSingleClick.on('select', function(event){
event.selected[0].setStyle(new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'blue'
</script>
</body>
</html>
二、Feature选取之条件过滤
之前我们是单击进行选择,而同样可以移动鼠标进行选择
<div id="map" style="width: 100%"></div>
<script type="text/javascript">
var layer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'red'
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
layer
target: 'map',
view: new ol.View({
center: ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
// 在地图上添加一个圆
var circle = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'))
layer.getSource().addFeature(circle);
// 添加一个用于选择Feature的交互方式
map.addInteraction(new ol.interaction.Select({
condition: ol.events.condition.pointerMove, // 唯一的不同之处,设置鼠标移到feature上就选取
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'blue'
</script>
我们甚至可以重写过滤函数:
ol.events.condition.singleClick = function(mapBrowserEvent) {
return mapBrowserEvent.type == ol.MapBrowserEvent.EventType.SINGLECLICK;
我们同样可以直接对feature进行过滤
选择圆形而不选择五角星
<div id="map2" style="width: 100%"></div>
<script type="text/javascript">
// 创建一个用于存放circle的layer
var circleLayer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'red'
// 创建一个用于存放star的layer
var starLayer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
image: new ol.style.RegularShape({
points: 5,
radius1: 20,
radius2: 10,
fill: new ol.style.Fill({
color: 'red'
var map2 = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
circleLayer, starLayer
target: 'map2',
view: new ol.View({
center: ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
// 在地图上添加一个圆
var circle1 = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'))
circleLayer.getSource().addFeature(circle1);
// 在地图上添加一个五星
var star = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(
[104.06, 30.05], 'EPSG:4326', 'EPSG:3857'))
starLayer.getSource().addFeature(star);
// 添加一个用于选择Feature的交互方式
map2.addInteraction(new ol.interaction.Select({
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'blue'
// 关键: 设置过了条件,可以用feature来写过滤,也可以用layer来写过滤
filter: function(feature, layer){
return layer === circleLayer;
</script>
前面的例子都只是一个feature的情况,在实际应用中,肯定是不止一个的,如果要能同时选择多个,只需要设置一下构造函数的参数multi: true,默认情况下,只能选取一个feature。 仿照上面的代码,可自行尝试。
三、通过HTML元素取消选择
<div id="map" style="width: 100%"></div>
<input type="button" value="取消选中" onclick="unselectFeature();"></input>
<script type="text/javascript">
var layer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'red'
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
layer
target: 'map',
view: new ol.View({
center: ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
// 在地图上添加一个圆
var circle = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'))
layer.getSource().addFeature(circle);
// 添加一个用于选择Feature的交互方式
var clickSelect = new ol.interaction.Select({
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
fill: new ol.style.Fill({
color: 'blue'
map.addInteraction(clickSelect);
// 取消选中
function unselectFeature() {
clickSelect.getFeatures().clear();
// 下面这样也是可以取消选中的,根据情况选择
// map.removeInteraction(clickSelect);
</script>
四、绘制一条线
我们可以用ol.interaction.Draw类绘制图片
普通绘制,双击取消:
<div id="map" style="width: 100%"></div>
<script type="text/javascript">
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
// 添加绘图的交互类
map.addInteraction(new ol.interaction.Draw({
type: 'LineString' // 设置绘制线
</script>
在地图上保存:
<div id="map2" style="width: 100%"></div>
<script type="text/javascript">
var map2 = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
target: 'map2',
view: new ol.View({
center: ol.proj.transform(
[104, 30], 'EPSG:4326', 'EPSG:3857'),
zoom: 10
// 添加一个绘制的线使用的layer
var lineLayer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
size: 1
map2.addLayer(lineLayer);
map2.addInteraction(new ol.interaction.Draw({
type: 'LineString',
source: lineLayer.getSource() // 注意设置source,这样绘制好的线,就会添加到这个source里
</script>
ol.interaction.Draw的构造参数type的值为’Point’,‘Polygon’,,‘MultiPoint’,‘MultiLineString’,‘MultiPolygon’ 或者 ‘Circle’
五、绘图其他设置
前面只是简单的绘制上了一条线,在实际业务中,可能还需要设置绘图时的样式,限制绘制的点的个数,获取绘制的图形的所有坐标等。 在上一节的基础上,以下面这个地图为例,再给大家介绍一下这些方面的更深入的应用。下面绘制这条线的点不能超过4个,在绘制时,样式会和前一节的样式不太一样,在地图上方,会显示当前绘制完的线的所有点的坐标。
<div style="background-color: #999;"><span>当前绘制线的坐标:</span><span id='points'></span></div>
<div id="map" style="width: 100%"></div>
<script type="text/javascript">
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
// 添加一个绘制的线使用的layer
var lineLayer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
size: 1
map.addLayer(lineLayer);
var lineDraw = new ol.interaction.Draw({
type: 'LineString',
source: lineLayer.getSource(), // 注意设置source,这样绘制好的线,就会添加到这个source里
style: new ol.style.Style({ // 设置绘制时的样式
stroke: new ol.style.Stroke({
color: '#009933',
size: 1
maxPoints: 4 // 限制不超过4个点
// 监听线绘制结束事件,获取坐标
lineDraw.on('drawend', function(event){
// event.feature 就是当前绘制完成的线的Feature
document.getElementById('points').innerHTML = JSON.stringify(event.feature.getGeometry().getCoordinates());
map.addInteraction(lineDraw);
</script>
如果我们想取消当前绘制,直接用map.removeInteraction(lineDraw)就可以了。