Javascript MapBox API专用层切换器

Javascript MapBox API专用层切换器,javascript,jquery,mapbox,Javascript,Jquery,Mapbox,我已经彻底搜索了MapBox支持和Stack Overflow,以获得关于如何使用最新版本(目前为1.6.1)创建独占层切换器的答案。在这种情况下,独占意味着一次只能看到/激活一个层。出于设计原因,我不想使用传单层控件 在一点帮助下,我想出了一个几乎可以奏效的例子: 出于某种原因,添加和删除gridControl会中断循环。如果使用此结构仅添加/删除tileLayer,而不使用gridLayer或gridControl,则效果良好。但是,当您添加网格元素时,数组中的最后一个元素不会显示,并会将

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

在一点帮助下,我想出了一个几乎可以奏效的例子:

出于某种原因,添加和删除gridControl会中断循环。如果使用此结构仅添加/删除tileLayer,而不使用gridLayer或gridControl,则效果良好。但是,当您添加网格元素时,数组中的最后一个元素不会显示,并会将循环的其余部分弄乱。(在本例中为“远”。)

有人知道为什么会这样吗?这种类型的层切换器经常在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>

区议会分区图
#分区地图容器{
位置:相对位置;
浮动:对;
显示:内联;
}
#地图分区{
位置:相对位置;
浮动:左;
明确:两者皆有;
宽度:45%;
最小宽度:500px;
高度:500px;
右:20px;
边缘顶部:10px;
右边距:10px;
边框:1px实心#bbb;
}
#地图用户界面分区{
位置:相对位置;
浮动:左;
列表样式:无;
边距:0;填充:0;
左:-20px;
}
#地图用户界面分区a{
字体系列:“卡鲁瓦哥特式”,无衬线;
字体大小:12px;
字体大小:400;
背景:#FFF;
颜色:#5698D0;
浮动:左;
保证金:0;
边框:1px实心#BBB;
边框宽度:1px 1px 1px 0;
最大宽度:100px;
填充:8px;
文字装饰:无;
}
#地图用户界面{
显示:内联;
}
#地图用户界面分区a:悬停{背景:#ECF5FA;}
#地图ui分区li:最后一个子a{
边框底宽:1px;
-webkit边界半径:0 3px 3px 0;
边界半径:0 3px 3px 0;
}
#地图用户界面分区li:第一个孩子a{
左边框宽度:1px;
-webkit边界半径:3px 0 3px;
边界半径:3px 0 3px;
}
#地图用户界面分区a.active{
背景#5698D0;
边框颜色:#5698D0;
边框顶部颜色:#BBB;
颜色:#FFF;
}
.map工具提示.zone{
字体大小:10px;
线高:13px;
字体大小:粗体;
}
.map工具提示.desc{
字体大小:10px;
线高:13px;
垫底:3件;
} 
.map工具提示。焦点{
字体大小:13px;
线高:16px;
字体大小:粗体;
}  
.map工具提示.info{
字体大小:11px;
线高:16px;
} 
var map=L.mapbox.map('map_zoning'); var staminlayer=L.tileLayer('https://stamen-tiles-{s} .a.ssl.fastly.net/toner lite/{z}/{x}/{y}.png'{ 属性:“地图平铺依据,在下方。数据依据,在下方。” }).addTo(地图); 地图集视图([38.908,-77.029],11); var ui=document.getElementById('map-ui-zoning'); var stories=L.mapbox.tillelayer('sarah.28n6ogvi'); var storiesGrid=L.mapbox.gridLayer('sarah.28n6ogvi'); var storiesGridControl=L.mapbox.gridControl(storiesGrid,{follow:false}); var height=L.mapbox.tillelayer('sarah.ofjsv2t9'); var heightGrid=L.mapbox.gridLayer('sarah.ofjsv2t9'); var heightGridControl=L.mapbox.gridControl(heightGrid,{follow:false}); var far=L.mapbox.tillelayer('sarah.2w9x80k9'); var farGrid=L.mapbox.gridLayer('sarah.2w9x80k9'); var farGridControl=L.mapbox.gridControl(farGrid,{follow:false}); 变量层=[{ “名称”:“故事”, “层”:故事, “gridLayer”:storiesGrid, “gridControl”:storiesGridControl }, { “名称”:“高度”, “层”:高度, “网格层”:高度网格, “gridControl”:heightGridControl }, { 'name':'far', “层”:远, “网格层”:farGrid, “gridControl”:farGridControl } ]; $(文档).ready(功能(层){ map.addLayer(故事); map.addLayer(storiesGrid); map.addControl(storiesGridControl); }); $(“#映射ui分区li a”)。在('click',function()上{ $(“#映射ui分区li a”).removeClass('active'); var$el=$(本); 层。forEach(函数(层){ 如果($el.data('name')!==图层['name']){ map.removeLayer(层['layer']); removeLayer(图层['gridLayer']); removeControl(图层['gridControl']); } 否则{ addLayer(layer['layer']); addLayer(layer['gridLayer']); addControl(图层['gridControl']); $el.addClass(“活动”); } }); });

我认为当您调用map.removeControl(layer['gridControl'])或更一般的map.removeLayer时,您不会测试该层是否已添加到映射中,因为否则它会尝试删除不存在的元素,这就是代码被破坏的地方

        if ($el.data('name') !== layer['name'])
需要成为

    if ($el.data('name') !== layer['name'] && map.hasLayer(layer))
当然,您需要相应地更改else语句

下面是您的运行示例