-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Conversation
85683b3
to
a180b4f
Compare
@@ -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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
src/source/query_features.js
Outdated
@@ -24,6 +24,7 @@ export function queryRenderedFeatures(sourceCache: SourceCache, | |||
wrappedTileID: tileIn.tileID.wrapped().key, | |||
queryResults: tileIn.tile.queryRenderedFeatures( | |||
styleLayers, | |||
sourceCache.getFeatureState.bind(sourceCache), |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
a180b4f
to
facfb57
Compare
src/source/query_features.js
Outdated
@@ -24,6 +24,7 @@ export function queryRenderedFeatures(sourceCache: SourceCache, | |||
wrappedTileID: tileIn.tileID.wrapped().key, | |||
queryResults: tileIn.tile.queryRenderedFeatures( | |||
styleLayers, | |||
sourceCache.getFeatureState.bind(sourceCache), |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
👍
facfb57
to
3b3e273
Compare
There was a problem hiding this 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
src/source/query_features.js
Outdated
@@ -24,6 +24,7 @@ export function queryRenderedFeatures(sourceCache: SourceCache, | |||
wrappedTileID: tileIn.tileID.wrapped().key, | |||
queryResults: tileIn.tile.queryRenderedFeatures( | |||
styleLayers, | |||
sourceCache.getFeatureState.bind(sourceCache), |
There was a problem hiding this comment.
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
Addresses #6536 .
When updating a feature's paint properties using
Map.setFeatureState
, each tile should refresh itsqueryPadding.
Additionally, feature state needs to be present on thefeature
object when evaluating paint properties for the intersection test.