Skip to content

queryRenderedFeatures doesnt take into account feature states - #6569

Merged
asheemmamoowala merged 4 commits into
masterfrom
fix-query-padding
May 3, 2018
Merged

asheemmamoowala merged 4 commits into
masterfrom
fix-query-padding

Conversation

@asheemmamoowala

Copy link
Copy Markdown
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.

}

this._state.coalesceChanges(this._tiles);
this._state.coalesceChanges(this._tiles, this.map ? this.map.painter : null);

Copy link
Copy Markdown
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
Copy Markdown
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.

Comment thread src/source/query_features.js Outdated
wrappedTileID: tileIn.tileID.wrapped().key,
queryResults: tileIn.tile.queryRenderedFeatures(
styleLayers,
sourceCache.getFeatureState.bind(sourceCache),

@asheemmamoowala asheemmamoowala Apr 26, 2018 •

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

Comment thread src/source/query_features.js Outdated
wrappedTileID: tileIn.tileID.wrapped().key,
queryResults: tileIn.tile.queryRenderedFeatures(
styleLayers,
sourceCache.getFeatureState.bind(sourceCache),

Copy link
Copy Markdown
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?

Comment thread src/source/tile.js
}

setFeatureState(states: LayerFeatureStates) {
setFeatureState(states: LayerFeatureStates, painter: any) {

Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

👍

@ansis ansis left a comment

Copy link
Copy Markdown
Contributor

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

Comment thread src/source/query_features.js Outdated
wrappedTileID: tileIn.tileID.wrapped().key,
queryResults: tileIn.tile.queryRenderedFeatures(
styleLayers,
sourceCache.getFeatureState.bind(sourceCache),

Copy link
Copy Markdown
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.

4 participants