在最基本的代码中,我们没有进行任何设置.移动鼠标就可以移动地图,滑动滚轮就可以实现缩放.
这些都是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)就可以了。