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

sort_rank and highroad-style layering #72

Open
bdon opened this issue Jul 21, 2023 · 14 comments
Open

sort_rank and highroad-style layering #72

bdon opened this issue Jul 21, 2023 · 14 comments

Comments

@bdon
Copy link
Member

bdon commented Jul 21, 2023

In order to make correct casing ordering on complex overpasses, we may need to change Tilezen - Tangram relied on sort_rank with casings to overlay an arbitrary number of layers. For MapLibre GL we have sort_key in the style but that only works per-layer: casings needs to be drawn as separate layers.

In my experience the only solution is to have a fixed set of layers each with their own filter e.g. layers -2, -1, 0, 1, 2. @nvkelso

@nvkelso
Copy link
Collaborator

nvkelso commented Jul 27, 2023

My work around recommendation is to have -1, 0, 1, and a single new MapLibre style layer for "even higher bridges" (level = 2, 3, 4, 5, 6).

That way you avoid parsing the MVT in MapLibre "again, again, again" looking for features at those levels per style layer – when mostly no MVT data layer features are found to be eligible for the GL style layers.

Ideally the "inline" and "outline" are in the same GL style layer and could use the existing sort_key from Tilezen (which would need a port over to this repo). But the explosion of MapLibre style layers for each kind and the levels is already burdensome...

@bdon
Copy link
Member Author

bdon commented Aug 7, 2023

@nvkelso I don't think there is still any solve for what you described like tilezen sort_key because of intersections? maplibre/maplibre#164 (comment)

So we need have 4 levels, say 5 road classes, and casings/inner strokes, 4x5x2 = 40 layers...

Unless you think we can combine all road classes into a single layer with expressions

@wipfli
Copy link
Collaborator

wipfli commented Aug 7, 2023

Not so flexible alternative is this: https://github.com/wipfli/single-highway-layer

@bdon
Copy link
Member Author

bdon commented Aug 8, 2023

@wipfli what if styles weren't embedded in the properties, but you had a single layer for all classes, and the paint properties were a (very big) case statement? So a complete stack would be like

tunnels_casing
tunnels
ground_casing
ground
bridges_casing
bridges
bridges_2_casing
bridges_2

Instead of having motorway, primary, etc.

@wipfli
Copy link
Collaborator

wipfli commented Aug 9, 2023

Yes the case approach works. A limitation is that MapLibre GL JS currently does not support data-driven line-dash arrays and some other properties like line-caps. Maybe worth talking to @ZeLonewolf and others from the American map style. They run into the same problem.

@ZeLonewolf
Copy link

Agreed, it's capability gap in the current maplibre-gl-js and we've resorted to very inefficient techniques to resolve it in Americana.

@bdon
Copy link
Member Author

bdon commented Aug 9, 2023

So if we designed around the constraint that there are no variation in linecaps or dashes, we can get away with the total set of ~8 road layers I listed above - it would be cleaner in the number of layers, and have beastly match/case expressions - is this really better for performance than having 40 layers, or about the same?

@wipfli
Copy link
Collaborator

wipfli commented Aug 9, 2023

regarding performance cc @msbarry

@msbarry
Copy link
Contributor

msbarry commented Aug 9, 2023

Currently most of the processing time for each tile is evaluating each filter expression on each feature. I want to make a change that will make that more of a constant time for each feature regardless of how many layers there are. I need to set up new benchmarks in maplibre first though maplibre/maplibre-gl-js#982

bdon added a commit that referenced this issue Aug 13, 2023
bdon added a commit that referenced this issue Aug 14, 2023
* layers attr on roads is integer [#72]
@bdon
Copy link
Member Author

bdon commented Aug 14, 2023

Looking at tag info for stats: https://taginfo.openstreetmap.org/keys/layer#values

96.99% of layer tags are -1, 0 or 1.

We can try a hybrid approach of @wipfli 's for the other 3.01% where a casing feature is duplicated in the tileset - this should have minimal bloat

So the complete stack of "normal" road symbology for all kinds is

roads_tunnel_2_minus
roads_tunnel_1_casing
roads_tunnel_1
roads_0_casing
roads_0
roads_bridges_1_casing
roads_bridges_1
roads_bridges_2_plus

For a total of 8 road MapLibre GL layers supporting an arbitrary # of flyover levels and tunnels.

@bdon
Copy link
Member Author

bdon commented Aug 14, 2023

Screenshot 2023-08-14 at 12 15 56

A style can already support an arbitrary # of layers by using data-driven line-color to visually distinguish each layer. This looks a bit weird aesthetically, and using casings is better in the majority of cases...

"line-color":["rgb",["-",255,["*",20,["to-number",["get","layer"]]]],255,["-",255,["*",20,["to-number",["get","layer"]]]]],

@bdon
Copy link
Member Author

bdon commented Aug 14, 2023

proof of concept working:

Screenshot 2023-08-14 at 14 23 51

The main problem now is the lack of data-driven line endings, because using butt will show seams, and using Round will end up like this:

Screenshot 2023-08-14 at 14 25 02

@bdon
Copy link
Member Author

bdon commented Aug 14, 2023

Planet build proof of concept live: 5 road classes, unlimited stacking, 8 MapLibre layers:

Screenshot 2023-08-14 at 20 57 52

@bdon
Copy link
Member Author

bdon commented Aug 14, 2023

Relevant MapLibre issue: maplibre/maplibre-gl-js#2108

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

5 participants