# `StaticMaps.Source.Template`
[🔗](https://gitlab.com/tristanperalta/staticmaps/blob/v0.1.0/lib/static_maps/source/template.ex#L1)

A source for any tile server with a URL template.

    source: {StaticMaps.Source.Template,
             url: "https://{s}.tiles.example.com/{z}/{x}/{y}{r}.png?key=…",
             subdomains: ~w(a b c),
             attribution: "© Example Maps"}

## Placeholders

  * `{z}`, `{x}`, `{y}` — the tile
  * `{-y}` — the row counted from the south, for TMS servers
  * `{s}` — a subdomain from `:subdomains`, chosen from the tile so a tile always has the
    same URL
  * `{r}` — `"@2x"` for a high-density tile, `""` otherwise

## Mirrors

`:url` may be a list of templates for servers that serve identical tiles, such as your
own tile servers:

    url: ["https://tiles1.example.com/{z}/{x}/{y}.png",
          "https://tiles2.example.com/{z}/{x}/{y}.png"]

Each tile goes to a mirror chosen from its position, so a tile always has the same URL
and the load spreads evenly. If that mirror fails, the tile is fetched from the next
one, and so on; a `404` is not retried elsewhere, since the tile does not exist.

`:max_concurrency` is the limit for the source as a whole, across all its mirrors. A
per-mirror limit cannot hold during failover: while one mirror is down, its tiles go to
the others, which would then see their own share and the dead mirror's at once. With
one limit, no mirror ever sees more than `:max_concurrency` requests, so raise it by
the number of mirrors if each can take the full amount.

Mirrors must serve the same tiles. Different providers draw different maps, and mixing
their tiles makes a patchwork; for a different provider as a backup, use a fallback
source instead: `source: [primary, fallback]`.

## Options

  * `:url` — the template, or a list of mirror templates; required
  * `:attribution` — required
  * `:tile_size` — 256 (default) or 512
  * `:zoom` — the tile zooms the server serves, default `0..19`
  * `:scales` — default `[1, 2]` when the template has `{r}`, else `[1]`
  * `:subdomains` — required when the template has `{s}`
  * `:max_concurrency` — requests in flight at once, across all mirrors; default 8
  * `:cache` — `false` keeps these tiles out of the tile cache, for providers whose
    terms forbid server-side caching; default `true`. `guides/tile-providers.md` says
    which providers need it.

# `expand`

```elixir
@spec expand(String.t(), StaticMaps.Source.tile(), keyword()) :: String.t()
```

Fills the placeholders in `template` for `tile`.

    iex> StaticMaps.Source.Template.expand("https://t/{z}/{x}/{-y}{r}.png", %{z: 2, x: 1, y: 0, scale: 2})
    "https://t/2/1/3@2x.png"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
