2
votes

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?

3

3 Answers

1
votes

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
votes

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.

0
votes

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!