7
votes

I am using Mapbox GL JS and I would like to allow users to change a map's background style from streets to satellite, while showing a polygon layer above the map background.

I have adapted the Mapbox example, but I can't work out how to stop map.setStyle from setting the new style above (and thus hiding) my polygon layer. I would like it to change without hiding the polygon layer.

Before switching layers:

enter image description here

After switching layers - polygon overlay missing, would like to carry on showing it:

enter image description here

This is my code in full:

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title></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.33.1/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.33.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 {
        position: absolute;
        background: #fff;
        padding: 10px;
        font-family: 'Open Sans', sans-serif;
    }
</style>
<div id='map'></div>
<div id='menu'>
    <input id='basic' type='radio' name='rtoggle' value='basic' checked='checked'>
    <label for='basic'>basic</label>
    <input id='satellite' type='radio' name='rtoggle' value='satellite'>
    <label for='satellite'>satellite</label>
</div>
<script>
mapboxgl.accessToken = 'pk.eyTOKEN';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/basic-v9',
    zoom: 5,
    center: [-3.0, 54.6]
});
map.on('load', function () {
    map.addSource('xxx', {
        type: 'vector',
        url: 'mapbox://xxx.xxx'
    });
    map.addLayer({
        'id': 'xxx',
        'source': 'xxx',
        'type': 'fill',
        'paint': {
            'fill-color': 'red'
        },
        'source-layer': mylayer
    }, 'road'); // Note that I'd like this to display above the OSM 'roads' layer
    var layerList = document.getElementById('menu');
    var inputs = layerList.getElementsByTagName('input');
    function switchLayer(layer) {
        var layerId = layer.target.id;
        map.setStyle('mapbox://styles/mapbox/' + layerId + '-v9');
    }
    for (var i = 0; i < inputs.length; i++) {
        inputs[i].onclick = switchLayer;
    }
});
</script>
</body>
</html>
1

1 Answers

4
votes

Mapbox GL JS does not have the concept of a "base layer" and "overlays." All layers of all maps are drawn with the same basic primitives.

If you need to persist one or more custom layers while switching between the provided Mapbox styles, you may choose to

  • fork the Mapbox style and add your custom layers in Studio
  • re-add your custom layers after switching styles
  • download the Mapbox style as JSON in the browser and add your custom layers to the style in the browser