Skip to content

[FEATURE] use a provided MapLibre stylesheet to prune unneeded layers and features from a profile #1554

Description

@jake-low

It would be cool if you could provide a MapLibre stylesheet to Planetiler at runtime (e.g. --optimize-for-style=example.json), which would be used to prune unused layers, features, and attributes from the output tiles (reducing their size and making your map load faster).

I know this has already been discussed in a few places, e.g. on Slack, but I couldn't find an existing issue for it, and had some thoughts I wanted to share about implementation details, so I figured I'd open one.

I think this feature is made up of four specific sub-features, which I've ordered below by how difficult I think they would be to implement (easiest first).

  1. Skip tile layers that are defined in the profile but aren't used by any style layer. This just requires looking at each style layer's source-layer property (which is always a plain identifier, not an expression), and skipping any tile layer that is not referenced anywhere.
  2. At a given zoom level, skip tile layers that are not used at that zoom level. For example, if the profile defines a railways layer, but all style layers that reference this layer have a minzoom of 12, then the profile can skip emitting features into this layer at zoom < 12. Like source-layer, minzoom is always a constant (never an expression) so this is easy to check statically. It's probably worth adding symmetric handling for maxzoom too (skip tile layers at high zooms that are only needed by the stylesheet at low zoom), though that case is probably less common in practice.
  3. Skip specific features that are not matched by any style layer's filter expression. For example, if the profile defines a shops layer which includes every OSM element tagged shop=*, but the stylesheet only renders specific shop types using a filter such as ["in", "shop", "supermarket", "department_store", "mall"], then features which do not match that filter could be excluded. This is harder because it requires evaluating arbitrary MapLibre filter expressions in Planetiler when building the tileset. Maybe MapLibre expressions could be translated into Planetiler's Expression types?
  4. Omit attributes on features if those attributes are not used in the stylesheet. Planetiler would need to make sure that the attribute is not used for filtering (in a filter property on a style layer) or for data-driven styling (in an expression on a layout or paint property). This might be tricky since there are several expression variations to detect: the expressions ["in", "foo", "a", "b"], ["==", ["get", "foo"], "x"], ["has", "foo"] all use the foo attribute, plus there are legacy forms like "text-field": "{foo}" to worry about as well.

You could technically go even deeper (such as omitting specific attributes at low zoom that are only used by the stylesheet at higher zooms), but the list above is probably enough to cover a lot of common cases.

An additional thought: stylesheets can have several sources, so the CLI should probably offer a way to indicate which of the stylesheet's sources corresponds to the Planetiler profile being built. Maybe it could be optional in the simple case where the stylesheet just has one source.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions