图层叠加及管理

分层管理是GIS渲染引擎及其他图形系统常用的策略,为业务的应用提高了较大的适用性。比如更换地图底图,不能影响在上地图上添加的一些标注。如果把地图底图和标注分开,放在不同的图层上,就很容易解决这个问题。

有了图层的概念,自然需要对图层进行控制,比如增删改查等,图层之间的顺序,图层可见度等等。这些都是大家经常会遇到的问题。下面先来看一下三个图层叠加的情况:

显示/隐藏: 底图
图层顺序: 底图最上 圆最上 点最上

上面这个地图示范了显示和隐藏的控制,以及图层顺序的控制。可以勾选上面的复选框和单选框试试。具体实现,参见下面的代码:

<div id="map" style="width: 100%"></div>
<div> 显示/隐藏:
    <input type="checkbox" checked="checked" onclick="checkOsm(this);" />底图
    <input type="checkbox" checked="checked" onclick="checkCircle(this);"/><input type="checkbox" checked="checked" onclick="checkPoint(this);"/></div>
<div>
    图层顺序:
    <input name="seq" type="radio" value="" onclick="upOsm(this);" />底图最上
    <input name="seq" type="radio" value="" checked="checked" onclick="upCircle(this);"/>圆最上
    <input name="seq" type="radio" value="" onclick="upPoint(this);"/>点最上
</div>

<script>

    // 创建3个图层
    var osmLayer = new ol.layer.Tile({
        source: new ol.source.OSM()
    });
    var pointLayer = new ol.layer.Vector({
        source: new ol.source.Vector()
    });
    var circleLayer = new ol.layer.Vector({
        source: new ol.source.Vector()
    });

  new ol.Map({
      // 在地图上添加上面创建的三个图层,图层顺序自下而上,依次是osm,point,circle
        layers: [osmLayer, pointLayer, circleLayer],
        view: new ol.View({
            center: [0, 0],
            zoom: 2
        }),
        target: 'map'
  });

  // 添加点
  var point = new ol.Feature({
      geometry: new ol.geom.Point([0, 0])
  });
  point.setStyle(new ol.style.Style({
      image: new ol.style.Circle({
          radius: 1,
          fill: new ol.style.Fill({
              color: 'red'
          }),
          stroke: new ol.style.Stroke({
              color: 'red',
              size: 1
          })
      })
  }));
  pointLayer.getSource().addFeature(point);


  // 添加圆
  var circle = new ol.Feature({
      geometry: new ol.geom.Point([0, 0])
  });
  circle.setStyle(new ol.style.Style({
      image: new ol.style.Circle({
          radius: 10,
          stroke: new ol.style.Stroke({
              color: 'blue',
              size: 1
          })
      })
  }));
  circleLayer.getSource().addFeature(circle);

  // 隐藏显示osm图层
  function checkOsm(elem) {
      osmLayer.setVisible(elem.checked);
  }

    // 隐藏显示point图层
  function checkPoint(elem) {
      pointLayer.setVisible(elem.checked);
  }

  // 隐藏显示circle图层
  function checkCircle(elem) {
      circleLayer.setVisible(elem.checked);
  }

  // 置顶osm图层到最上面
  function upOsm (elem) {
      if (elem.checked) {
          osmLayer.setZIndex(3);
          circleLayer.setZIndex(circleLayer.getZIndex()-1);
          pointLayer.setZIndex(pointLayer.getZIndex()-1);
      }
  }

  // 置顶circle图层到最上面
  function upCircle (elem) {
      if (elem.checked) {
          circleLayer.setZIndex(3);
          osmLayer.setZIndex(osmLayer.getZIndex()-1);
          pointLayer.setZIndex(pointLayer.getZIndex()-1);
      }
  }

  // 置顶point图层到最上面
  function upPoint(elem) {
      if (elem.checked) {
          pointLayer.setZIndex(3);
          osmLayer.setZIndex(osmLayer.getZIndex()-1);
          circleLayer.setZIndex(circleLayer.getZIndex()-1);
      }
  }

</script>

简而言之,就是可以利用方法setVisiblesetZIndex来控制图层,满足80%的这种需求。 除此之外,大家也可以使用很早之前使用的一种方式来实现管理,即删除/添加图层,参见最简单的加载在线地图