Skip to content
This repository has been archived by the owner on Apr 10, 2018. It is now read-only.

Add "cover" layer type #626

Closed
jfirebaugh opened this issue Dec 19, 2016 · 5 comments
Closed

Add "cover" layer type #626

jfirebaugh opened this issue Dec 19, 2016 · 5 comments

Comments

@jfirebaugh
Copy link
Contributor

Add a new layer type: cover.

This layer requires a source property, and prohibits the source-layer and filter properties. It has the paint properties cover-color, cover-pattern, cover-opacity, which behave the same as the equivalent background layer properties. In addition, it has a cover-type paint property, which is an enumeration with the following values:

  • "tile-loaded" (default) -- The layer is rendered wherever a tile for the specified source is in the "loaded" state: a request for the tile has received a successful response, including responses indicating no data is present in the tile.
  • "tile-loading" -- The layer is rendered wherever a tile for the specified source is in the process of being loaded: it's known to be needed for rendering, but not yet successfully or unsuccessfully loaded.
  • "tile-failed" -- The layer is rendered wherever a tile for the specified source has failed to load: a request for the tile has produced a 4xx or 5xx HTTP status response (excluding legacy 404 responses interpreted as "no data"), or failed at the network level.

The cover-type paint property does not support property or zoom-and-property functions.


This proposal aims to satisfy two distinct use cases.

Use case: show a pattern or color in lieu of a loading or errored raster tile (mapbox/mapbox-gl-js#3694). When raster tiles use fully transparent pixels to represent "no data", it is difficult or impossible to distinguish between an area fully without data, an area in which a tile or tiles have yet to be loaded, and an area in which tiles have failed to load due to network or other errors. The cover layer type provides a means to do so. To distinguish areas that have yet to be loaded, one can add a cover layer at the desired z-index with cover-type: "tile-loading". Likewise cover-type: "tile-failed" to distinguish areas where tiles have failed to load.

Use case: allow a platform- or application-defined "matte" color or pattern to show through areas of the map where no tile data has been loaded (mapbox/mapbox-gl-native#119). For example:

image

A background layer does not suffice for this use case for two reasons:

  • The matte pattern must be renderable prior to even the style itself being loaded.
  • Once the style is loaded, a background layer is rendered across the whole canvas, including areas of the map where no tile data has been loaded.

However, the combination of a platform- or application-defined background rendering step, plus cover layer does suffice:

  • The application or platform SDK is responsible for rendering the matte pattern.
  • The style omits any background layers.
  • The style includes a cover layer with cover-type: "tile-loaded" (or no cover-type per the default value) and other properties which produce the desired rendering for loaded tiles. For vector tilesets consisting of an implicit "land" background and explicit "water" polygons, this would mean a cover-color value indicative of land.

Implementation notes and future directions.

Implementing a cover layer type provides us with a pathway, in a future revision of the specification, to replace the background layer type with a single set of top-level style properties nested under a background key (in the style of light). The background then would then be defined statically, with multiple instances, or interleaving with other layers, being prohibited.

This would simplify the rendering implementations, which currently rely on analysis of all style layers to determine if the background can be rendered with a simple glClear operation or not.

This would also lead to better clarity in naming (#219): "background" would refer to a portion of the rendering that is truly in the background, behind all layers, and "cover" to layers which can be arbitrarily z-ordered but do behave relative to layers underneath them as their name suggests.

It would also provide a clearer path to adding rendering support for a sky color distinct from the ground (mapbox/mapbox-gl-native#2190).

@1ec5
Copy link
Contributor

1ec5 commented Dec 20, 2016

This layer requires a source property, and prohibits the source-layer and filter properties.

This maps cleanly to what the iOS and macOS SDKs are calling a “foreground style layer”, as opposed to the background style layer type we’re trying to phase out. (It isn’t much of a problem that cover layers would provide a background in the artistic sense; we can always massage the class hierarchy in the future.)

@lucaswoj
Copy link

lucaswoj commented Dec 22, 2016

It is desirable to continue having our layer types correspond with drawing primitives as they are implemented by most graphics editing software (fill, polygon, line, ...). This correspondence is possible if we reframe "covering a source" as a behaviour that can be applied to a fill layer rather than a layer type itself.

In practice, this could look like making the cover-type property available to the fill layer (with a some renaming, thanks for the ideas @1ec5 #624 (comment)).

{
    "type": "fill",
    "tile-filter": "loading",
    "tile-filter-source": "mapbox"
    ....
}

Points of Discussion

  • Would it make sense to expose this feature on raster sources too? (They are also sometimes used as backgrounds to vector data.)
  • Should tile-filter be a paint property or a top-level layer property?
  • Should we specify the tile-filter's source via a tile-filter-source property or a plain source property?

@jfirebaugh
Copy link
Contributor Author

jfirebaugh commented Dec 22, 2016

@lucaswoj I'm not 100% sure I understand what you're proposing. Is it like:

  • A fill layer without a tile-filter property renders feature geometries from a source (existing behavior)
  • A fill layer with a tile-filter property ignores source features, and instead fills the entire tile with a solid color or pattern

I think that behavior would make the rendering model more confusing, because it would mean that fill layers have two drastically different behaviors depending on the presence or absence of tile-filter.

Would it make sense to expose this feature on raster sources too?

Raster sources are one of the two primary use case for this feature, so... yes? This answer seems obvious, so I feel like I must be misunderstanding what you're getting at here.

@lucaswoj
Copy link

Eek. A few things I said in there were confusing / wrong. Let me try to clarify:


I was thinking so much about the background -> fill / fill -> polygon mapping that I wrote this comment as if that had already happened. What I intended is better specified by

{
    "type": "background",
    "tile-filter": "loading",
    "tile-filter-source": "mapbox"
    ....
}

Raster sources are one of the two primary use case for this feature, so... yes? This answer seems obvious, so I feel like I must be misunderstanding what you're getting at here.

Here I was thinking about exposing tile-filter on raster layers. For example, on the satellite / hybrid style, we might choose to hide the satellite raster layer until the vector features had loaded.

We don't need to implement this immediately. I brought it up as an example of the benefits of thinking about tile-filter as a composable behaviour rather than a layer type.

@lucaswoj
Copy link

lucaswoj commented Feb 1, 2017

This issue was moved to mapbox/mapbox-gl-js#4156

@lucaswoj lucaswoj closed this as completed Feb 1, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants