2

Does somebody know how you can re-add an icon (symbol) after changing the map style?

The situation is as follows: I created a map with two views: a street view and satellite view. On the street view I also added an icon (symbol) that show the place where someone lives. When I switch between the two views the icon disappears and doesn't come back again. How can I reload the icon again?

Basically I want to combine the following two examples:

Change a map's style
https://docs.mapbox.com/mapbox-gl-js/example/setstyle/

and

Display a popup on click
https://docs.mapbox.com/mapbox-gl-js/example/popup-on-click/


How can it be done?

Steve Bennett
  • 114,604
  • 39
  • 168
  • 219

3 Answers3

2

Thank you very much for your answer!!

I looked at your code and compared it with my code and the only thing that I had to change was map.on('load', ...) to map.on('style.load', ... ) and that did the trick!

Here is the complete code:

HTML

<div id='openstreetmap' style='height: 420px'>
<div id="mapbox-menu">
    <input id="streets-v11" type="radio" name="rtoggle" value="streets" checked="checked" />
    <label for="streets">Kaart</label>
    <input id="satellite-v9" type="radio" name="rtoggle" value="satellite" />
    <label for="satellite">Satelliet</label>
</div>
</div>

JavaScript

        // Set an access token.
            mapboxgl.accessToken = '';

            // Create a map object.
            var map = new mapboxgl.Map({
                container: 'openstreetmap',
                style: 'mapbox://styles/mapbox/streets-v11',
                center: [5.880299, 51.834706],
                zoom: 15
            });
// Set the controls.
            map.addControl(new mapboxgl.NavigationControl({showCompass: false}), 'top-right');

            // Create and add a list of places.
            map.on('style.load', function() {

                map.addSource('places', {
                    'type': 'geojson',
                    'data': {
                        'type': 'FeatureCollection',
                        'features': [
                            {
                                'type': 'Feature',
                                'properties': {
                                    'description':
                                        '<strong>Header</strong><p>text</p>',
                                    'icon': 'music'
                                },
                                'geometry': {
                                    'type': 'Point',
                                    'coordinates': [5.880299, 51.834706]
                                }
                            }
                        ]
                    }
                });

                // Add a layer showing the places.
                map.addLayer({
                    'id': 'places',
                    'type': 'symbol',
                    'source': 'places',
                    'layout': {
                        'icon-image': '{icon}-15',
                        'icon-size': 1.25,
                        'icon-allow-overlap': true
                    }
                });

                // Show a popup.
                map.on('click', 'places', function(e) {

                    var coordinates = e.features[0].geometry.coordinates.slice();
                    var description = e.features[0].properties.description;

                    while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
                        coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
                    }

                    new mapboxgl.Popup()
                        .setLngLat(coordinates)
                        .setHTML(description)
                        .addTo(map);

                });

                // Change the cursor to a pointer.
                map.on('mouseenter', 'places', function() {
                    map.getCanvas().style.cursor = 'pointer';
                });

                // Reset the cursor.
                map.on('mouseleave', 'places', function() {
                    map.getCanvas().style.cursor = '';
                });
            });


            // Switch between street view and satellite view.
            var layerList = document.getElementById('mapbox-menu');
            var inputs = layerList.getElementsByTagName('input');

            function switchLayer(layer) {
                var layerId = layer.target.id;
                map.setStyle('mapbox://styles/mapbox/' + layerId);
            }

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

        </script>

The only (small) problem is that the close button doesn't work anymore. Have an idea about that?

0

Mapbox-GL-JS doesn't distinguish between layers that are part of the basemap, and layers that you added. So if you want to "retain" additional layers, you really just have to add them again.

Write a function to add your additional layers. Then, whenever you change basemap, just call that function again.

Steve Bennett
  • 114,604
  • 39
  • 168
  • 219
  • See also https://stackoverflow.com/questions/36168658/mapbox-gl-setstyle-removes-layers?rq=1 – Steve Bennett Feb 24 '20 at 22:15
  • Thank you very much for you answer! I looked at your code and compared it with my code and the only thing that I had to change was map.on('load', ...) to map.on('style.load', ... ) and that did the trick! You can find my code below. – Scott Trakker Feb 25 '20 at 22:51
0

Thanks again!!

I moved the following three block out of the function map.on('style.load', ...):

map.on('click', 'places', ...)
map.on('mouseenter', 'places', ...)
map.on('mouseleave', 'places', ...)

And that was it! Thank you for helping me!