MapBox API独有的图层切换器

时间:2014-02-17 22:17:17

标签: javascript jquery mapbox

我已经彻底搜索了MapBox支持和Stack Overflow,以获得有关如何使用最新MapBox API(1.6.1截至目前)创建独占层切换器的答案。在这种情况下,独占意味着一次只能看到/激活一层。出于设计原因,我不想使用Leaflet Layers Control。

在一点帮助下,我想出了这个几乎可行的例子:

http://bl.ocks.org/sarahkhank/0e5d81998d2d0876856c

出于某种原因,添加和删除gridControl会中断循环。如果你使用这个结构来添加/删除没有gridLayer或gridControl的tileLayer,它可以正常工作。但是当你添加网格元素时,数组中的最后一个元素不会显示出来并且会影响循环的其余部分。 (在这种情况下'远'。)

有谁知道为什么会这样?这种类型的层切换器经常被问及MapBox的支持,所以我相信很多人都会很高兴看到这种情况变得生动。谢谢你的帮助!!

在我的bl.ocks链接断开的情况下,在底部发布完整代码。

<html>  
<head>
<title>DC Zoning Map</title>
    <script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
    <script src='http://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.js'></script>
    <link href='http://api.tiles.mapbox.com/mapbox.js/v1.6.1/mapbox.css' rel='stylesheet' />
</head>
  <body>
  <style>
#zoning-map-container {
    position:relative;
    float: right;
    display: inline;
}

#map_zoning {
    position: relative;
    float: left;
    clear: both;
    width:45%;
    min-width: 500px;
    height: 500px;
    right:20px;
    margin-top: 10px;
    margin-right: 10px;
    border: 1px solid #bbb;
  }

#map-ui-zoning {
  position:relative;
  float: left;
  list-style:none;
  margin:0;padding:0;
  left: -20px;
  }

#map-ui-zoning a {
  font-family:  'Carrois Gothic', sans-serif;
  font-size: 12px;
  font-weight: 400;
  background:#FFF;
  color:#5698D0;
  float: left;
  margin:0;
  border:1px solid #BBB;
  border-width: 1px 1px 1px 0;
  max-width:100px;
  padding:8px;
  text-decoration:none;
  }

#map-ui-zoning li {
    display: inline;
  }

#map-ui-zoning a:hover { background:#ECF5FA; }

#map-ui-zoning li:last-child a {
  border-bottom-width:1px;
  -webkit-border-radius:0 3px 3px 0;
          border-radius:0 3px 3px 0;
  }

#map-ui-zoning li:first-child a {
border-left-width: 1px;
  -webkit-border-radius:3px 0 0 3px;
          border-radius:3px 0 0 3px;
        }

#map-ui-zoning a.active {
  background:#5698D0;
  border-color:#5698D0;
  border-top-color:#BBB;
  color:#FFF;
  }
  .map-tooltip .zone {
    font-size: 10px;
    line-height: 13px;
    font-weight: bold;
    }
   .map-tooltip .desc {
    font-size: 10px;
    line-height: 13px;
    padding-bottom: 3px;
    } 
   .map-tooltip .focus {
    font-size: 13px;
    line-height: 16px;
    font-weight: bold;
    }  
   .map-tooltip .info {
    font-size: 11px;
    line-height: 16px;
    } 

</style>
<div id='zoning-map-container'>
        <ul id='map-ui-zoning'>
          <li><a href="#" data-name="stories" class="active">Maximum Stories</a></li>
          <li><a href="#" data-name="height">Maximum Height</a></li>
          <li><a href="#" data-name="far">Maximum FAR</a></li>
        </ul>
        <div id='map_zoning'></div>
  </div>
<script type='text/javascript'>
    var map = L.mapbox.map('map_zoning');

    var stamenLayer = L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.png', {
      attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>.'
    }).addTo(map);
    map.setView([38.908, -77.029], 11);

    var ui = document.getElementById('map-ui-zoning');

    var stories = L.mapbox.tileLayer('sarah.28n6ogvi');
        var storiesGrid = L.mapbox.gridLayer('sarah.28n6ogvi');
        var storiesGridControl = L.mapbox.gridControl(storiesGrid, {follow: false});

    var height = L.mapbox.tileLayer('sarah.ofjsv2t9');
        var heightGrid = L.mapbox.gridLayer('sarah.ofjsv2t9');
        var heightGridControl = L.mapbox.gridControl(heightGrid, {follow: false});

    var far = L.mapbox.tileLayer('sarah.2w9x80k9');
        var farGrid = L.mapbox.gridLayer('sarah.2w9x80k9');
        var farGridControl = L.mapbox.gridControl(farGrid, {follow: false});

    var layers = [{
        'name': 'stories',
        'layer': stories,
    'gridLayer': storiesGrid,
    'gridControl': storiesGridControl
      },
      {
        'name': 'height',
        'layer': height,
    'gridLayer': heightGrid,
    'gridControl': heightGridControl
      },
      {
        'name': 'far',
        'layer': far,
    'gridLayer': farGrid,
    'gridControl': farGridControl
      }
    ];

    $(document).ready(function(layer){
    map.addLayer(stories);
          map.addLayer(storiesGrid);
          map.addControl(storiesGridControl);
    });

    $('#map-ui-zoning li a').on('click', function() {
      $('#map-ui-zoning li a').removeClass('active');
      var $el = $(this);
      layers.forEach(function(layer) {
        if ($el.data('name') !== layer['name']){
          map.removeLayer(layer['layer']);
          map.removeLayer(layer['gridLayer']);
          map.removeControl(layer['gridControl']);
        }
        else {
          map.addLayer(layer['layer']);
          map.addLayer(layer['gridLayer']);
          map.addControl(layer['gridControl']);
          $el.addClass('active');
        }
      });
    });
</script>

1 个答案:

答案 0 :(得分:0)

我认为当你调用map.removeControl(layer ['gridControl'])或更常见的map.removeLayer时你不测试图层是否已经添加到地图中,否则mapboxjs会尝试删除一个元素不存在,这是你的代码被破坏的地方。

        if ($el.data('name') !== layer['name'])

需要成为

    if ($el.data('name') !== layer['name'] && map.hasLayer(layer))

当然你需要相应地改变你的其他声明。

这是您运行的示例 http://bl.ocks.org/radproject/31c48b1a7610e353d495