tangram icon indicating copy to clipboard operation
tangram copied to clipboard

Allow draw groups to `freeze` parameter values through sub-layers

Open bcamper opened this issue 6 years ago • 6 comments
trafficstars

OK a couple years later I'm returning to this override issue #576. Here's my latest attempt...

This introduces a freeze keyword to draw groups. When a draw group contains the value freeze: true, any values in that group (only those values defined "locally" in the same immediate block as the freeze keyword) will be "frozen", meaning they will be unaffected by other draw group values, either from child/descendants in the same layer tree, or from parallel/sibling layer trees.

The simplest way to think of this is that it will create a draw group with infinite layer depth, and that is how it is implemented: after all draw groups are merged across both "across" (parallel layer trees) and "down" (layer -> sub-layers) with existing logic, any frozen groups are then additionally applied, as if they were in the next sub-layer down.

On balance, I think this is a helpful solution, but still has potential issues and is just a tricky problem to solve... suggestions welcome! The implementation footprint is small, it's more a matter of getting the logic right (in a way that keeps the implementation simple/performant :)

Basemap override

Returning to one of the common cases where you want to "globally" override one or more values, here is an example that re-colors all roads in an imported Refill:

import:
    - https://www.nextzen.org/carto/refill-style/12/refill-style.zip
    - https://www.nextzen.org/carto/refill-style/12/themes/label-10.zip

layers:
    roads:
        override-colors:
            draw:
                lines:
                    freeze: true
                    color: red
                    outline:
                        color: darkred

No matter what other draw groups are defined, at the end of the draw group merge process, an additional draw group that looks like this will be applied:

draw:
  lines:
    color: red
    outline:
      color: darkred

This yields the following: tangram-1556902003464

Priority

These draw groups are applied with the same priority/specificity as any other layer, so if you have two or more conflicting "frozen" groups...

override-colors2 will win over override-colors, because it has a higher priority due to last-alphabetical-layer-name-wins logic:

layers:
    roads:
        override-colors:
            draw:
                lines:
                    freeze: true
                    color: red
                    outline:
                        color: darkred

        override-colors2:
            draw:
                lines:
                    freeze: true
                    color: blue
                    outline:
                        color: darkblue

override-colors will win over override-colors2, because it has a higher explicit priority defined:

layers:
    roads:
        override-colors:
            priority: 1
            draw:
                lines:
                    freeze: true
                    color: red
                    outline:
                        color: darkred

        override-colors2:
            priority: 2
            draw:
                lines:
                    freeze: true
                    color: blue
                    outline:
                        color: darkblue

Similarly, if a layer marked exclusive matches, it will take precedence.

Freeze at multiple levels

A child layer won't modify values of its frozen ancestor, e.g. in this case, the child layer won't change the color, which will remain frozen as red:

layers:
    roads:
        override-colors:
            draw:
                lines:
                    freeze: true
                    color: red
                    outline:
                        color: darkred

            child:
                draw:
                    lines:
                        color: yellow # has no effect because ancestor layer is frozen

If multiple levels of the tree contain freeze: true, they are merged, but with inverse priority from the normal deepest-level-wins logic: instead, the higher-up/ancestor groups will win (does this make sense, or is it backwards...? I'm trying to think through the use cases). Also as a result, marking a descendant draw group as freeze: false has no effect (though I suppose this could be useful, as a way to say "you definitely cannot override this value"?).

Imports

There's a potential gotcha with imports (which would be likely to be mixed with this feature due to its nature), in that if you are importing an existing draw group and then applying freeze to it, you're also going to freeze the whole draw group, including any properties that were imported -- because import merges happen at the beginning of scene parsing, long before layers are parsed and merged (and it's likely not really practical to change that).

That's why in the example above, a top-level draw group with no filter and adjacent to others was created, called override-colors, rather than just applying freeze to the existing top-level draw group under the roads layer.

bcamper avatar May 03 '19 16:05 bcamper

Call for comments... @matteblair @nvkelso @meetar @burritojustice

bcamper avatar May 03 '19 16:05 bcamper

Seems useful, though I find the name freeze confusing. Is there a more common term for this?

nvkelso avatar May 03 '19 17:05 nvkelso

Ha, yeah I've always struggled with naming this. Freeze was just the closest conceptual match I could find to what's happening. In CSS there is important, but that is... worse IMO. Happy for alternatives.

bcamper avatar May 03 '19 17:05 bcamper

From my understanding of the feature maybe final: true is a good name? Maybe too OOP-ish though. Still trying to grok all the cases here.

matteblair avatar May 03 '19 18:05 matteblair

Yeah, CSS !important, ftw ;) What about?

  • prevail
  • evaluate_last

Others:

  • freeze
  • final

nvkelso avatar May 03 '19 19:05 nvkelso

prevail lol

winner: true

On Fri, May 3, 2019 at 3:05 PM Nathaniel V. KELSO [email protected] wrote:

Yeah, CSS !important, ftw ;) What about?

  • prevail
  • evaluate_last

Others:

  • freeze
  • final

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/tangrams/tangram/pull/717#issuecomment-489206237, or mute the thread https://github.com/notifications/unsubscribe-auth/AAAECXOMQPJWFYV732DBQWDPTSEGPANCNFSM4HKVNGCQ .

bcamper avatar May 03 '19 19:05 bcamper

Decided not to pursue this.

bcamper avatar Dec 31 '22 19:12 bcamper