Search code examples
mapboxgeojsonmapbox-gl-jsmapbox-glmapbox-marker

How can I enable clicking on default Mapbox POI markers?


Is it possible to make default POI markers on Mapbox actionable/clickable?

Not custom POI markers included as layers, but the default POI markers included in each map?

In the screenshot below you can see the default POI markers in blue and brown:

Central Station, Campbria Hotel, Homewood Suites, Minute Maid Park, etc.

These POI markers reveal on zoom, and were not added as a separate layer. I'd like to make them actionable.

Ideal behavior would be a map popup with related OSM POI information like Google Maps. But even linking directly to the OSM place would be acceptable.

For example, is it possible to redirect a user to the associated OSM place if a user clicks the Minute Maid Park POI icon below? (https://www.openstreetmap.org/way/129025430)

I can do this with custom markers via GeoJSON sources/layers, but I'd like to access all of the default POI markers rather than a small set of custom markers.

Default MapBox POI


Solution

  • Yes, you can! It all depends what are the layers of the style used you are interested in. For instance, mapbox://styles/mapbox/streets-v11 has 111 layers to represent the data.

    enter image description here

    Each click on any city point on a map with this style returns from 1 to 20 features across all these layers. It seems you know how to do it, but just for clarity of the explanation, you can access all of them on click like these:

            map.on('style.load', function() {
    
              map.on('click', function(e) {
                let l = map.getStyle().layers; // here you can get all the layers of the style
    
                var features = map.queryRenderedFeatures(e.point, {
                  layers: ['poi-label', 'transit-label', 'landuse', 'national-park']
                }); // this filters the features in these 4 layers
                new mapboxgl.Popup()
                  .setLngLat(e.lngLat)
                  .setHTML('you clicked here: <br/>' + features[0].properties.name)
                  .addTo(map);
              });
            });
    

    So just creating a filter for the layers or type of layers you are interested in... (I recommend you to start from any type symbol layer or with the ids landuse, poi-label, national-park, transit-label...)

    Here is a quick fiddle I have created with a sample on how to locate POIs on default layers. I just added 4 layers, you can probably create easily a better filter adjusted to your needs.

    enter image description here