Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

queryRenderedFeatures requires setTimeout after calling setFilter #5019

Closed
sthomp opened this issue Jul 21, 2017 · 3 comments
Closed

queryRenderedFeatures requires setTimeout after calling setFilter #5019

sthomp opened this issue Jul 21, 2017 · 3 comments

Comments

@sthomp
Copy link

sthomp commented Jul 21, 2017

Im setting a filter on my map: map.setFilter(ALL_POINTS_LAYER_NAME, ['==', 'll', val]);.

After setting the filter I then call map.queryRenderedFeatures({ layers: [ALL_POINTS_LAYER_NAME] }) which will return all the features from before setFilter was called. The only way I could work around this is by doing:

      map.setFilter(ALL_POINTS_LAYER_NAME, ['==', 'll', val]);
      setTimeout(() => {
        map.queryRenderedFeatures({ layers: [ALL_POINTS_LAYER_NAME] })
      }, 500);

I also tried listening to the data event but this seems to fire several times after setFilter is called.

Is there a better way to do this?

@peterqliu
Copy link
Contributor

This is a different approach, but you can queryRenderedFeatures and filter the results by your ll property, all before calling .setFilter() on the map object.

@anandthakker
Copy link
Contributor

Looks like @peterqliu 's suggestion might work in this particular use case. Alternatively:

Updates to the map that affect which features are drawn -- e.g., map.setFilter(layerId, [...]), or map.getSource(geojsonSourceId).setData(...) -- occur asynchronously. The best way to "know" when such an update is complete is to listen to the sourcedata event, inspecting the isSourceLoaded property of the event payload.

For example:

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v9',
    center: [-73.13734351262877, 45.837451890638886],
    zoom: 5
});
  
var position = [-73.13734351262877, 45.837451890638886];

map.on('load', function () {
    map.addLayer({
        'id': 'dot',
        'type': 'circle',
        'source': {
            'type': 'geojson',
            'data': {
                'type': 'Feature',
                'geometry': {
                    'type': 'Point',
                    'coordinates': position
                }
            }
        },
        'layout': {},
        'paint': {
            'circle-radius': 20,
            'circle-color': 'red'
        }
    });    
  
    animate();
});
 
count = 1000;
function animate() {
  if(--count < 0) return;
  position[0] -= 0.01;
  position[1] -= 0.01;
    
  // listener for sourcedata event.
  function onSourceData (e) {
    if (e.isSourceLoaded) {
      // the update is complete: unsubscribe this listener and
      // move on with whatever we need to do next (in this case,
      // schedule the next step in the animation)
      map.off('sourcedata', onSourceData);
      requestAnimationFrame(animate);
    }
  }
  map.on('sourcedata', onSourceData);
  
  
  map.getSource('dot').setData({
      'type': 'Feature',
      'geometry': {
          'type': 'Point',
          'coordinates': position
      }
  })
}

@sthomp
Copy link
Author

sthomp commented Jul 21, 2017

Just a nit: Instead of doing map.on followed by map.off you can do map.once.

edit: take that back. you have to check e.isSourceLoaded

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants