styleFunction应用
很多时候,我们会忽略styleFunction
的存在,但很明显的,它可以让我们的图标或者标签应用更加灵活,比如根据层级放大缩小图标也可以用styleFunction
来实现:
代码如下:
<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({
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);
</script>
对比一下前面同样功能的代码,你会发现这样更加的简单, 同时在此基础上扩展开来的应用也会更加的多。 比如动态替换图标,或者让图标不显示等等,可自行来实现这两个需求,以掌握此方式的使用。
在上面这个例子中,我们是在feature
上应用了styleFunction
,通过官网API文档可以看到,其类型为ol.FeatureStyleFunction
,函数仅带有一个参数resolution
,在上面的代码中看到了,在函数体内this
指的是当前的feature
,根据文档说明,这个函数要范围一个style
数组。 这一点需要注意,虽然实际使用中,即使没有返回数组也不会出错,但还是希望大家能遵守官网API的说明来使用该接口。
我们知道,除了feature
可以设置样式之外,layer
也是可以设置样式的,同样地也支持styleFunction
,但是需要注意的是,其定义和feature
的不一样,类型为ol.style.StyleFunction
,该函数具有两个参数,第一个参数为feature
,第二个参数为resolution
,同样地,该函数需要返回style
数组。
styleFunction
在feature
上具有很好的灵活性,那么应用在layer
上,同样威力无穷,比如像下面这个:
在地图上可以看到中心位置有一个圆,一个点,一个五边形,但这次都没有直接在这些feature
上设置样式,具体的代码如下:
<div id="map2" style="width: 100%"></div>
<script type="text/javascript">
// 创建layer使用的style function,根据feature的自定义type,返回不同的样式
var layerStyleFunction = function(feature, resolution) {
var type = feature.get('type');
var style = null;
// 点
if (type === 'point') {
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 1,
fill: new ol.style.Fill({
color: 'red'
})
})
});
} else if ( type === 'circle') { // 圆形
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: 'red',
size: 1
})
})
});
} else { // 其他形状
style = new ol.style.Style({
image: new ol.style.RegularShape({
points: 5,
radius: 10,
fill: new ol.style.Fill({
color: 'blue'
})
})
});
}
// 返回 style 数组
return [style];
};
var layer2 = new ol.layer.Vector({
source: new ol.source.Vector(),
style: layerStyleFunction // 应用上面创建的 style function
});
var map2 = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
layer2
],
target: 'map2',
view: new ol.View({
projection: 'EPSG:4326',
center: [104, 30],
zoom: 10
})
});
// 添加三个feature,并设置自定义属性 type
var rect = new ol.Feature({
geometry: new ol.geom.Point([104, 30])
});
layer2.getSource().addFeature(rect);
var circle = new ol.Feature({
geometry: new ol.geom.Point([104, 30])
});
circle.set('type', 'circle');
layer2.getSource().addFeature(circle);
var point = new ol.Feature({
geometry: new ol.geom.Point([104, 30])
});
point.set('type', 'point');
layer2.getSource().addFeature(point);
</script>
这就是一个典型的根据feature
的属性进行不同渲染的例子,可以在业务上无限扩展,比如feature
的属性可以是速度,可以是大小,可以是时间,可以是权重等等。 由此可见,只要掌握了这个方法,前端按照条件渲染就不再困难。