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 doesnt take into account feature states #6569

Merged
merged 4 commits into from
May 3, 2018

Conversation

asheemmamoowala
Copy link
Contributor

Addresses #6536 .

When updating a feature's paint properties using Map.setFeatureState, each tile should refresh its queryPadding. Additionally, feature state needs to be present on the feature object when evaluating paint properties for the intersection test.

@@ -168,7 +168,7 @@ class SourceCache extends Evented {
this._source.prepare();
}

this._state.coalesceChanges(this._tiles);
this._state.coalesceChanges(this._tiles, this.map ? this.map.painter : null);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anandthakker, in #6236(comment), we discussed (and agreed upon) :

  • move the responsibility for calling Tile#updateFeatureState during prepare() directly into SourceFeatureState#coalesceChanges() (i.e., take a set of tiles as a parameter to coalesceChanges)?
  • Add a SourceFeatureState#initializeTileState(Tile) method and replace the other two cases of tile.updateFeatureState(this._state.state); with this._state.initializeTileState(tile)?

What do you think of moving back the tile-specific code from this._state.coalesceChanges into SourceCache, to reduce the painter spaghetti created here.
Not a burning issue though.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we should keep this as-is, because I expect this bit of 🍝 to be temporary: via #4875 and #4012, I'm hoping we'll end up in a place where each tile can easily hold on to a view of the style layers that were used to lay it out, and that will let us eliminate the need to thread painter through here.

@@ -24,6 +24,7 @@ export function queryRenderedFeatures(sourceCache: SourceCache,
wrappedTileID: tileIn.tileID.wrapped().key,
queryResults: tileIn.tile.queryRenderedFeatures(
styleLayers,
sourceCache.getFeatureState.bind(sourceCache),
Copy link
Contributor Author

@asheemmamoowala asheemmamoowala Apr 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SourceFeatureState maintains different states for each sourceLayer. Instead of passing state for the entire source, pass a function instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the advantage of passing this callback rather than a reference to the source's SourceFeatureState object?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SourceCache#getFeatureState has logic for handling GeoJSON sources where there is no sourceLayer in the query results. After considering that options, I decided that it would be better to pass the callback instead of duplicating that logic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm -- there are several other places in the code that already have awareness of _geojsonTileLayer... as such, I'd be inclined to say we should just dupe the logic, or else move it into SourceFeatureState.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@anandthakker What is the advantage of duplicating the logic over passing the bound function? This PR has already reduced the spred of _geojsonTileLayer by consolidating it in SourceCache.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It just seems clearer to me: I find a callback as a method of passing data to be harder to read and understand as compared to passing an object. Would moving the _geojsonTileLayer logic into SourceFeatureState give us the best of both worlds?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would moving the _geojsonTileLayer logic into SourceFeatureState give us the best of both worlds?

I don't think so. I could change the name of the callback from getState to queryState, but all of these changes seem minor and not that significant advantages to whats already here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @anandthakker that moving the logic into SourceFeatureState or duping the logic would be a bit clearer than passing the callback here

@@ -24,6 +24,7 @@ export function queryRenderedFeatures(sourceCache: SourceCache,
wrappedTileID: tileIn.tileID.wrapped().key,
queryResults: tileIn.tile.queryRenderedFeatures(
styleLayers,
sourceCache.getFeatureState.bind(sourceCache),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the advantage of passing this callback rather than a reference to the source's SourceFeatureState object?

@@ -418,7 +419,7 @@ class Tile {
}
}

setFeatureState(states: LayerFeatureStates) {
setFeatureState(states: LayerFeatureStates, painter: any) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could the second argument be the Style itself rather than painter, since it's only the style that we actually need?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used painter to maintain similarity with loadVectorData, but it doesn't have to be that way - for both these methods. The only advantage I see of passing painter as the argument is that it communicates that the render style is being used. This becomes important when considering the Immutable Styl/Render-classes split.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yeah that's odd that loadVectorData takes a painter rather than a style object. I lean slightly towards passing Style here, but since this will get refactored in the nearish future with the immutable style state changes, it's not a big deal either way.

The only advantage I see of passing painter as the argument is that it communicates that the render style is being used. This becomes important when considering the Immutable Styl/Render-classes split

I think the correct style to use here will be the one that the tile will already hold a reference to -- namely, the one that was used at layout time, since that's the one that will be consistent with the data in the buckets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this will get refactored in the nearish future with the immutable style state changes, it's not a big deal either way.

I'd prefer to keep it as-is in that case.

I think the correct style to use here will be the one that the tile will already hold a reference to

👍

Copy link
Contributor

@ansis ansis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. I agree with @anandthakker about that one callback tweak, but other than that it looks good

@@ -24,6 +24,7 @@ export function queryRenderedFeatures(sourceCache: SourceCache,
wrappedTileID: tileIn.tileID.wrapped().key,
queryResults: tileIn.tile.queryRenderedFeatures(
styleLayers,
sourceCache.getFeatureState.bind(sourceCache),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @anandthakker that moving the logic into SourceFeatureState or duping the logic would be a bit clearer than passing the callback here

@asheemmamoowala asheemmamoowala merged commit c9c4f61 into master May 3, 2018
@asheemmamoowala asheemmamoowala deleted the fix-query-padding branch May 3, 2018 23:11
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

Successfully merging this pull request may close these issues.

3 participants