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

Style spec: Add ability to sort features #4361

Closed
kkaefer opened this issue Mar 3, 2017 · 10 comments
Closed

Style spec: Add ability to sort features #4361

kkaefer opened this issue Mar 3, 2017 · 10 comments
Labels
cross-platform 📺 Requires coordination with Mapbox GL Native (style specification, rendering tests, etc.)

Comments

@kkaefer
Copy link
Contributor

kkaefer commented Mar 3, 2017

With data driven styling, we can render more features in a single layer. However, this means that the order of the features in the source dictates the rendering order. It'd be useful to add a capability to sort/group features before they are parsed into a bucket.

The sorting step would come after the filter step and before the features are transformed into actual buffers. Here's a style syntax suggestion:

{
  "id": "place-city-lg-s",
  "type": "symbol",
  "source": "composite",
  "source-layer": "place_label",
  "filter": [
    "all",
    ["<=", "scalerank", 2],
    ["in", "type", "city"],
    ["in", "ldir", "S", "SE", "SW", "E"]
  ],
  "sort": [
    ["localrank", ">"]
  ]
}
{
  "id": "landcover",
  "type": "fill",
  "source": "composite",
  "source-layer": "landcover",
  "filter": [
    "all",
    ["in", "class", "crop", "grass", "scrub", "wood", "snow"]
  ],
  "sort": [
    ["class", ["crop", "grass", "scrub", "wood", "snow"]],
    ["area", "<"]
  ]
}

Sort rules are applied in order, so if items have an identical class , we're going to sort them by area in descending order. In the array, we're first supplying the sort field, then the sort order. We can either specify < for descending, > for ascending, and an array with explicitly listed items for discrete value ordering (all items that do not match a discrete value are going last and will have subsequent sort rules applied).

See #1349 for a similar discussion.

@kkaefer kkaefer added the cross-platform 📺 Requires coordination with Mapbox GL Native (style specification, rendering tests, etc.) label Mar 3, 2017
@stevage
Copy link
Contributor

stevage commented Mar 3, 2017

Small point, I'd suggest using a string like "asc" rather than subverting comparison operators (">"). They look like the filter attributes (which are comparisons) but the behaviour is unrelated.

It might even be better to use a different term which makes clearer the relationship between the sort order and the display order. I don't necessarily know whether an "ascending" order means that ID 5 is drawn above or below ID 3. I don't know what that term would be though :)

@1ec5
Copy link
Contributor

1ec5 commented Mar 3, 2017

In the iOS and macOS SDKs, it may be desirable to expose this sort option to the runtime styling API as a sortDescriptors property on MGLVectorSourceLayer that holds an array of NSSortDescriptors, for consistency with how we’re already representing filters as NSPredicates.

@nextstopsun
Copy link
Contributor

Waiting very much for this one to land. Can't really guarantee features get properly serialised to MVT keeping postgres sorting, so it's really important to have control for feature rendering order on client. Along with data-driven functions, this adds possibilities to reduce number of layers, "bigly".

@mollymerp
Copy link
Contributor

tagging in @mapbox/gl 🎉

@nickidlugash
Copy link

@kkaefer do you have a sense of the lift involved in implementing this feature?

@kkaefer
Copy link
Contributor Author

kkaefer commented Sep 11, 2017

To be able to sort features, we'd have to generate a sort key for every feature (likely an expression) in a layer. If we supported sorting by multiple keys (in case of equality), we'd want subsequent keys to be generated lazily. Either way, this relies on the ability to know all features within a layer as they are processed. When combined with custom sources, this assumption may no longer be true if they are streaming in some way. However, in the worst case, we could disallow sorting on custom sources (since the generating code is supposed to generate features in the right order).

@harry-wilson
Copy link

I've used the sort property to style road features based on 'layer' attribute of OSM data as follow, but the map renders all layes in the same z-order. What's the problem?

{
  "version": 8,
  "name": "Test MVT",
  "sources": {
    "sample-vectorTile": {
      "type": "vector",
       "url":"test://test-roads-v2
      "max-zoom":14,
    }
  },
  "sprite": "mapbox://sprites/lukaspaczos/cjnkdt02b0b2p2ss40skwpvs1",
  "glyphs": "mapbox://fonts/lukaspaczos/{fontstack}/{range}.pbf",

  "layers": [

    {
      "id": "background",
      "type": "background",
      "paint": {
        "background-color": "#BAD4E4"
      }
    },
    {
      "id": "road_footway",
      "type": "line",
      "source":"sample-vectorTile",
      "source-layer":"roads",
      "sort":[["to-number", ["get","layer"]],"<"],
      "paint": {
        "line-color": "#FEFB32",
        "line-width": {
          "base":1,
          "stops":[
            [5,0.75],
            [18,2],
            [22,15]
          ]
        }
      }
    }
  ]
}

@kkaefer
Copy link
Contributor Author

kkaefer commented Dec 17, 2018

@harry-wilson the syntax described in the original post is a proposal. It is not implemented.

@asheemmamoowala
Copy link
Contributor

@kkaefer The symbl-sort-key and other <layer-type>-sort-key properties partially address the proposal in this ticket. Do you think it can be closed?

@kkaefer
Copy link
Contributor Author

kkaefer commented Sep 2, 2019

Yeah, let's create a new issue if we discover missing functionality.

@kkaefer kkaefer closed this as completed Sep 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cross-platform 📺 Requires coordination with Mapbox GL Native (style specification, rendering tests, etc.)
Projects
None yet
Development

No branches or pull requests

8 participants