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 result sort #6266

Closed
tzvc opened this issue Mar 2, 2018 · 5 comments
Closed

queryRenderedFeatures result sort #6266

tzvc opened this issue Mar 2, 2018 · 5 comments

Comments

@tzvc
Copy link

tzvc commented Mar 2, 2018

mapbox-gl@0.44.0:

I'm experimenting with queryRenderedFeatures to select the feature currently prominent in view. I noticed that the resulting features correspond well to what is in the bounding box but are not sorted by prominence and wondered if this is normal behaviour.

Steps to Trigger Behavior

  1. call queryRenderedFeatures with a bounding box

(here i'm using a bounding box from the center of the map)

        const cpoint = this.map.project(this.map.getCenter());
        const bbox = [
          [cpoint.x - 50, cpoint.y - 50],
          [cpoint.x + 50, cpoint.y + 50]
        ];
  1. Apply queryRenderedFeature with this bounding box on a layer sourced from GEOjson data that highlight cities (in darker pink in my example).
        const features = this.map.queryRenderedFeatures(bbox, {
          layers: ["localities-highlight"]
        });
  1. Select the first elements return by the function (features[0]) to show what is selected

(here the bounding box is represented by the gray square and the selected feature is the one with dotted borders)
screen shot 2018-03-02 at 10 13 28

Expected Behavior

The first feature in the result array is the one prominent in the bounding box

Actual Behavior

The first feature in the result array is not the one prominent in the bounding box

@pathmapper
Copy link
Contributor

From the docs for queryRenderedFeatures how features are sorted in the returned array:

The topmost rendered feature appears first in the returned array, and subsequent features are sorted by descending z-order.

Regarding "topmost rendered feature" see also #6184 (comment) :

it looks like the sorting is based on the order in which items are inserted into the FeatureIndex by *Bucket.populate... which is closely related to the draw/z-order but not strictly the same

@tzvc
Copy link
Author

tzvc commented Mar 2, 2018

@pathmapper Thanks for the clarification !

So if the order depend only on the initial rendering order of features, is there a way using the API to get the prominent feature in that feature array ?

@pathmapper
Copy link
Contributor

is there a way using the API to get the prominent feature in that feature array?

@theochampion I'm very sure this isn't possible.

The "prominent feature" is also dependent on how you are defining prominent, because the term itself is not distinct. E.g for a polygon it could be the area or the length of the boundary or something else.

I don't know your specific data and use case, but maybe you are able to calculate your "prominent value" beforehand (e.g. calculate the area of the polygons) and include it in the feature properties to be able to sort (with JavaScript) the array returned by queryRenderedFeatures according to this value.

Or you could calculate such a value at runtime with Turf.js for the features in your returned array.

@tzvc
Copy link
Author

tzvc commented Mar 2, 2018

@pathmapper By prominent I mean prominent by area in the bounding box an the use case is to get which city the user is probably looking at even if it isn't perfectly hovering it.

I will look at TurfJs and make a few benchmark for the solution I come up with as this need to be fast (onMove handler) ;)

@anandthakker
Copy link
Contributor

Hi @theochampion, thanks for using Mapbox!

As @pathmapper indicated, there's already a specific sort order for queryRenderedFeatures, and since different applications will have different definitions of "prominence," we think sorting by prominence is something best handled at the application level rather than in Mapbox GL JS.

Using Turf for finding the area of a polygon should be pretty fast, but it will depend on the number of sides in the polygon. If it proves to be too slow, you could try either simplifying your polygons, or else precomputing the area and attaching it as a property to each feature.

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