mapbox / mapbox-gl-style-spec

76 stars 38 forks source link

Document quirks of using functions with layout properties #514

Closed lucaswoj closed 7 years ago

lucaswoj commented 8 years ago

Users may use zoom-functions with layout properties. These functions, however, cannot update at fractional zoom levels. We should clearly document this fact in the documentation and in the Studio UI.

Continued from https://github.com/mapbox/mapbox-gl-js/issues/3289

scothis commented 8 years ago

These functions, however, cannot update at fractional zoom levels.

Except for when they do... For example, text-size is a layout property that does update at fractional zoom levels. One gotcha is that the collision box is calculated at integer zoom levels, so depending on the direction of the function, the collision box will either be too big or too small for the content.

It seems like text-size and text-rotate should behave consistently.

davidtheclark commented 7 years ago

I'm looking for some clarification on this issue so we can ensure the Studio UI is correct.

@lucaswoj @scothis should we accept the statement that "Layout properties can only update on integer zooms", and make the UI enforce this?

If so, I will update Studio and the docs here.

davidtheclark commented 7 years ago

Word from @samanpwbb is that the factor determining when a zoom level must be an integer is the function type, not whether the property is paint or layout. Specifically, piecewise-constant functions must have integer zoom levels; all other functions can have fractional ones.

Any disagreement there? If not, I'll look into communicating this in the docs.

jfirebaugh commented 7 years ago

That's incorrect -- the zoom value in a stop can be any number; it's never required to be an integer.

interpolated functions interpolate between stops. piecewise-constant functions are used where the property type isn't interpolatable: enums, booleans, and strings. (I believe piecewise-constant vs interpolated are actually redundant, in the sense that they're entirely determined by the type.)

Regarding function evaluation, the difference between paint properties and layout properties is that paint properties are continuously reevaluated whenever the zoom changes, even fractionally, whereas layout properties are evaluated only once per tile, at the zoom level of the tile.

However, this doesn't mean that a function for a layout property has to use integer zoom stops. It could, for example, have stops at z5.5 and z6.5, and when evaluated for a z6 tile, it would interpolate halfway between the two, assuming the property is interpolated. Is that useful in practice? I don't know.

davidtheclark commented 7 years ago

Thanks, @jfirebaugh.

It sounds to me, then, like we have two problems: a documentation problem, and a UI problem.

Maybe we need to add a note in https://www.mapbox.com/mapbox-gl-style-spec/#types-function in "Zoom functions". Here's my attempt — what do you think?

There is an important difference between how layout and paint property functions render. Paint property values are continuously re-evaluated whenever the zoom level changes, even fractionally. Layout properties, on the other hand, are evaluated only once for each integer zoom level. For example, the rendering of a layout property will not change between zoom levels 4.01 and 4.99, no matter the function; but at zoom level 5, the function will be re-evaluated and the property's rendering will change. (You can still include fractional zoom levels in a layout property function, and it will affect the generated values; but the rendering will only change at integer zoom levels.)

For the UI problem, I will open a ticket in Studio.

jfirebaugh commented 7 years ago

That's incorrect -- the zoom value in a stop can be any number; it's never required to be an integer.

Turns out I was wrong about this: the validator currently does enforce integer zoom levels for piecewise-constant functions. This dates from https://github.com/cutting-room-floor/mapbox-gl-style-lint/issues/45. I don't remember what the original rationale was. I can't think of any, and I would like to remove this restriction.