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数组。

styleFunctionfeature上具有很好的灵活性,那么应用在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的属性可以是速度,可以是大小,可以是时间,可以是权重等等。 由此可见,只要掌握了这个方法,前端按照条件渲染就不再困难。