简体   繁体   中英

Toggle Layers with Mapbox GL JS

I'd like to toggle between layers in Mapbox GL JS. I've created some radio buttons that partly work in that you can switch from one layer to the other but not back or forth.

Below is my code for toggling the layers so far:

    var layerList = document.getElementById('toggle');
    var inputs = layerList.getElementsByTagName('input');

    function switchLayer(layer) {
        var layerId = layer.target.id;
        map.setLayoutProperty(layerId, 'visibility');
    }

    for (var i = 0; i < inputs.length; i++) {
    inputs[i].onclick = switchLayer;
    }

Here's the rest of the code (simplified) and a link to jsbin https://jsbin.com/cigekutiho/edit?html,output

   <!DOCTYPE html>
   <html>
   <head>
   <meta charset=utf-8 />
   <title>Test</title>
   <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
   <link rel="stylesheet" type="text/css" href="css/style.css" />
   <script src='https://api.mapbox.com/mapbox.js/v3.1.1/mapbox.js'> 
   </script>
   <link href='https://api.mapbox.com/mapbox.js/v3.1.1/mapbox.css' rel='stylesheet' />
   <script src='https://api.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'></script>
   <link href='https://api.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css' rel='stylesheet'/>
   <script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.2.0/mapbox-gl-geocoder.min.js'></script>
   <link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-geocoder/v2.2.0/mapbox-gl-geocoder.css' type='text/css' />
   <link href='https://www.mapbox.com/base/latest/base.css' rel='stylesheet'/>
   <style>
   body { 
      margin: 0; 
      padding: 0;
   }

   #map { 
      position: absolute; 
      top: 0; 
      bottom: 0; 
      width: 100%; 
   }

   #toggle {
   position: absolute;
   padding: 10px;
   background: #dddddd;
   font-family: Helvetica;
  }

  .rounded-toggle {
  position: absolute;
  border: 1px solid rgba(0,0,0,0.4);
  font-family: Helvetica;
  width: 200px;
  height: 47px;
  text-align: center;
  margin-left: 550px;
  top: 10px;
  cursor: pointer;
  }
  </style>
  </head>

  <body>

  <div id='map'></div>
  <div class='rounded-toggle inline' id='toggle'>
     <input id='Test_A' type='radio' name='rtoggle' value='Test_A' checked='checked'>
     <label for='Test_A'>Test A</label>
     <input id='Test_B' type='radio' name='rtoggle' value='Test_B'>
     <label for='Test_B'>Test B</label>
  </div>

  <script>
mapboxgl.accessToken = 'pk.eyJ1IjoibGlhbWJvbHRvbnVrIiwiYSI6IjJyeWxEMzgifQ.OROtY7TDOwNOmAOfCZeo4w';

var map_zoom = L.mapbox.map('map');
map_zoom.removeControl(map_zoom.zoomControl);

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/liamboltonuk/cjfykyscf6i272snyorquvam6',
    attributionControl: false,
    minZoom: 13,
    center: [-0.042582, 51.518039]
});

map.on('load', function () {
map.addSource('Test_A', {
        type: 'vector',
        url: 'mapbox://liamboltonuk.bv937ecm'
    });
map.addLayer({
        'id': 'Test_A',
        'type': 'circle',
        'source': 'Test_A',
        'layout': 
        {
        'visibility': 'visible'
        },
        'paint': {
            'circle-radius': 4,
            'circle-color': {
            property: 'conct',
            type: 'interval',
            stops: [
                [1, '#00477a'],
                [700, '#00477a']
            ]
            },
        'circle-opacity': {
            stops: [
                [12, 1],
                [13, 0.75]
            ] 
        },
    },
        'source-layer': 'LAEI_2013_N0x-5pzq5d'
});
});

map.on('load', function () {
map.addSource('Test_B', {
        type: 'vector',
        url: 'mapbox://liamboltonuk.bv937ecm'
    });
map.addLayer({
        'id': 'Test_B',
        'type': 'circle',
        'source': 'Test_B',
        'layout': 
        {
        'visibility': 'none'
        },
        'paint': {
            'circle-radius': 4,
            'circle-color': {
            property: 'conct',
            type: 'interval',
            stops: [
                [1, '#66e8ff'],
                [700, '#66e8ff']
            ]
            },
        'circle-opacity': {
            stops: [
                [12, 1],
                [13, 0.75]
            ] 
        },
    },
        'source-layer': 'LAEI_2013_N0x-5pzq5d'
});
});

    var layerList = document.getElementById('toggle');
    var inputs = layerList.getElementsByTagName('input');

    function switchLayer(layer) {
      var layerId = layer.target.id;
      map.setLayoutProperty(layerId, 'visibility');
    }

    for (var i = 0; i < inputs.length; i++) {
      inputs[i].onclick = switchLayer;
    }

    </script>
    </body>
    </html>

Map.setLayoutProperty takes 3 arguments (layer, name, value) . So to make the layer invisible use:

map.setLayoutProperty('my-layer', 'visibility', 'none');

then to make it visible again use:

map.setLayoutProperty('my-layer', 'visibility', 'visible');

Mapbox has some very nice starter code for doing this. See the docs or play with the actual code here

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>Show and hide layers</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.1/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.1/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
    </style>
</head>
<body>

<style>
    #menu {
        background: #fff;
        position: absolute;
        z-index: 1;
        top: 10px;
        right: 10px;
        border-radius: 3px;
        width: 120px;
        border: 1px solid rgba(0,0,0,0.4);
        font-family: 'Open Sans', sans-serif;
    }

    #menu a {
        font-size: 13px;
        color: #404040;
        display: block;
        margin: 0;
        padding: 0;
        padding: 10px;
        text-decoration: none;
        border-bottom: 1px solid rgba(0,0,0,0.25);
        text-align: center;
    }

    #menu a:last-child {
        border: none;
    }

    #menu a:hover {
        background-color: #f8f8f8;
        color: #404040;
    }

    #menu a.active {
        background-color: #3887be;
        color: #ffffff;
    }

    #menu a.active:hover {
        background: #3074a4;
    }
</style>

<nav id="menu"></nav>
<div id="map"></div>

<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiYWFnb3N0aW5pLXBlb3JpYWdvdiIsImEiOiJjanRnMzdjYnkwcDAxM3ltcDNjaXkyNWgzIn0.NhV8nl5x6256q8F_-gVCtQ';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v11',
    zoom: 15,
    center: [-71.97722138410576, -13.517379300798098]
});

map.on('load', function () {
    map.addSource('museums', {
        type: 'vector',
        url: 'mapbox://mapbox.2opop9hr'
    });
    map.addLayer({
        'id': 'museums',
        'type': 'circle',
        'source': 'museums',
        'layout': {
            'visibility': 'visible'
        },
        'paint': {
            'circle-radius': 8,
            'circle-color': 'rgba(55,148,179,1)'
        },
        'source-layer': 'museum-cusco'
    });

    map.addSource('contours', {
        type: 'vector',
        url: 'mapbox://mapbox.mapbox-terrain-v2'
    });
    map.addLayer({
        'id': 'contours',
        'type': 'line',
        'source': 'contours',
        'source-layer': 'contour',
        'layout': {
            'visibility': 'visible',
            'line-join': 'round',
            'line-cap': 'round'
        },
        'paint': {
            'line-color': '#877b59',
            'line-width': 1
        }
    });
});

var toggleableLayerIds = [ 'contours', 'museums' ];

for (var i = 0; i < toggleableLayerIds.length; i++) {
    var id = toggleableLayerIds[i];

    var link = document.createElement('a');
    link.href = '#';
    link.className = 'active';
    link.textContent = id;

    link.onclick = function (e) {
        var clickedLayer = this.textContent;
        e.preventDefault();
        e.stopPropagation();

        var visibility = map.getLayoutProperty(clickedLayer, 'visibility');

        if (visibility === 'visible') {
            map.setLayoutProperty(clickedLayer, 'visibility', 'none');
            this.className = '';
        } else {
            this.className = 'active';
            map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
        }
    };

    var layers = document.getElementById('menu');
    layers.appendChild(link);
}

</script>

</body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM