Mapbox – Use Geocoding Result to Query Rendered Features on Polygon Layer

geocodingmapboxmapbox-gl-js

I've been quite stumped on this and while I have seen it used in other online examples I can't find anything on stack or in the documentation.

Right now, I am trying to use the search bar result (a point) to identify which polygon from my existing layers added through paint it lies within.

Right now, the code below functions, but it always returns the wrong polygon within the fed_searched variable. In tests it is often within a short distance, but not reliably correct. I also found that without the moveend function, if the point is close to the edge of the polygon layer it doesn't find anything for the fed_searched variable. I am wondering if this is because my source layer for the polygons is an .mbtiles source.

[This example from mapbox][1] is what I pulled a lot of my logic from, though it is based off of a clicked point.

I am struggling because I have been able to run this same time of process with click points without any issues in selecting the correct polygon. See below:

    map.on('click', function (e) {
        // query which fed has been clicked
        var fed_clicked = map.queryRenderedFeatures(e.point, {
            layers: ['fed_click_fill']
        });

        console.log(fed_clicked);
    });

See my current code below:

    // geocoder/searchbar
    var geocoder = new MapboxGeocoder({ // Initialize the geocoder
        accessToken: mapbox_token, // Set the access token
        mapboxgl: mapboxgl, // Set the mapbox-gl instance
        marker: false,
        flyTo: {
            zoom: 10,
            speed: 1, // make the flying slow
            curve: 1, // change the speed at which it zooms out
            easing: function (t) { return t; }
        },
        countries: 'ca'
    });

    // Add the geocoder to the map
    map.addControl(geocoder);

    // Add the source(empty) and point layer for geocoding results to the map
    map.addSource('search', {
        type: 'geojson',
        data: {
            type: 'FeatureCollection',
            features: []
        }
    });

    map.addLayer({
        id: 'search_point',
        source: 'search',
        type: 'circle',
        paint: {
            'circle-radius': 3,
            'circle-color': '#448ee4'
        }
    });

    geocoder.on('result', function (e) {
        map.once('moveend', function () {
  // add the result as a point in the 'search_point' layer to show up as marker
            var geocoder_result = e.result.geometry;

            console.log(geocoder_result);

            map.getSource('search').setData(geocoder_result);


            var coordinates = e.result.geometry.coordinates;

            var fed_searched = map.queryRenderedFeatures(coordinates, {
                layers: ['fed_click_fill']
            });

            console.log(fed_searched);
// should be polygon feature containing the searched point

        });
    });


  [1]: https://docs.mapbox.com/mapbox-gl-js/example/queryrenderedfeatures-around-point/

Best Answer

I was able to solve this. A key piece that I was missing was switching the coordinates of the point to pixel xy cooordinates, so using the center property of the search result instead of geometry.

I used this thread to help find my solution: https://stackoverflow.com/questions/44595633/mapboxgl-querying-rendered-features-after-multiple-geocodes

Below is the updated geocoder result part of the code. The fed_searched variable can now be used to draw feature properties etc.

geocoder.on('result', function (e) {
// wait until the map has finished flying to the searched point
    map.once('moveend', function () {
        // add the result as a point in the 'search_point' layer to show up as marker
        var geocoder_result = e.result.geometry;
        map.getSource('search').setData(geocoder_result);

        //project to use (pixel xy coordinates instead of lat/lon for WebGL)
        var geocoder_point = map.project([e.result.center[0], e.result.center[1]]);

        var fed_searched = map.queryRenderedFeatures(geocoder_point, {
            layers: ['fed_click_fill']
        });

    });
});
Related Question