Feature选取之选中样式

OpenLayers 3除了在地图浏览方面提供内置的交互方式之外,还提供了地图上Feature选取的交互类: ol.interaction.Select。 这是一个经常会用到的类,应用范围非常的广。 我们可以先简单操作一下下面地图中的圆,点击一下,颜色就变了:

自定义事件及应用中,我们用了方法map.forEachFeatureAtPixel来获取当前选择的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>

官网其实有例子select-features,但是这里面还是有一些需要注意的地方,比如上面注释里面说到的,为什么style参数设置了没用? 因为我们的circle本身就设置了样式,而style参数设置的样式,其实是设置在内部新建的一个layer上的,而OpenLayers 3中,feature的样式优先级是大于layer的样式的优先级的。所以没生效,如果换成下面这种方式,就可以了:

代码变成这样了:

<div id="map2" style="width: 100%"></div>
<script type="text/javascript">
    var layer2 = new ol.layer.Vector({
        source: new ol.source.Vector(),
        // 注意:把feature上的style,直接移到layer上,避免直接在feature上设置style
        style: new ol.style.Style({
            image: new ol.style.Circle({
                radius: 10,
                fill: new ol.style.Fill({
                    color: 'red'
                })
            })
        })
    });
    var map2 = new ol.Map({
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          }), 
          layer2
        ],
        target: 'map2',
        view: new ol.View({
          center: ol.proj.transform(
              [104, 30], 'EPSG:4326', 'EPSG:3857'),
          zoom: 10
        })
    });

    // 在地图上添加一个圆
    var circle2 = new ol.Feature({
        geometry: new ol.geom.Point(ol.proj.transform(
              [104, 30], 'EPSG:4326', 'EPSG:3857'))
    })
    // 此处不再为feature设置style
    layer2.getSource().addFeature(circle2);

    // 添加一个用于选择Feature的交互方式
    map2.addInteraction(new ol.interaction.Select({
        // 设置选中后的style
        style: new ol.style.Style({
            image: new ol.style.Circle({
                radius: 10,
                fill: new ol.style.Fill({
                    color: 'blue'
                })
            })
        })
    }));
</script>

代码改成上面这样就可以了。在使用过程中,请千万留意这个问题。