HoloMap.Layer.Base (HoloMap v0.1.0)

Copy Markdown View Source

The shared body of every layer component.

MapLibre's eight layer types differ only in which paint and layout properties they accept. The specification shape, the update rules and the event surface are identical. Rather than repeat that eight times, each layer component is one use away from the whole thing:

defmodule HoloMap.Layer.Fill do
  use HoloMap.Layer.Base, type: "fill"
end

Passing no :type produces HoloMap.Layer, where the caller supplies it.

How the type is fixed

A type-specific component does not declare a type prop at all. The literal is baked into its template when the macro expands. That is deliberate: a values: ["fill"] constraint would only be checked while rendering, and this way there is nothing to check, because there is no way to pass a type in.

What the injected component does

It renders one definition element whose data-hm-spec is a MapLibre layer object. When a prop changes, the reconciler picks the narrowest update available: setPaintProperty for a paint change, setLayoutProperty for layout, setFilter for a filter, setLayerZoomRange for a zoom range. Only a change to type, source or source_layer, none of which MapLibre can change in place, forces a remove-and-re-add.

Summary

Functions

Injects the props, template and specification builder of a layer component.

Builds the JSON layer specification for a definition element.

Functions

__using__(opts)

(macro)

Injects the props, template and specification builder of a layer component.

Options

  • :type, the MapLibre layer type this component is locked to. When given, the type is a literal in the generated template and there is no type prop. When omitted, type becomes a required prop.

build(props)

@spec build(map()) :: String.t()

Builds the JSON layer specification for a definition element.

Paint and layout maps are dasherized (fill_color becomes "fill-color"), the visible prop is folded into layout.visibility, and empty paint or layout maps are dropped so an untouched layer keeps MapLibre's defaults.

iex> HoloMap.Layer.Base.build(%{type: "fill", source: "parcels", paint: %{fill_color: "#f00"},
...>   layout: %{}, filter: nil, min_zoom: nil, max_zoom: nil, before_id: nil,
...>   visible: nil, metadata: nil, source_layer: nil})
~s({"paint":{"fill-color":"#f00"},"source":"parcels","type":"fill"})