The arithmetic of a Web-Mercator basemap (spec/07 §8, #475): the zoom level whose 256-pixel tiles match a Mercator projection, the tiles covering a plot, where each goes in plot pixels, and its URL.
It never fetches anything: it computes URLs and rectangles, and the browser loads each
tile as it loads any <image href>.
Examples
iex> proj =
...> Visualize.Geo.Projection.new(:mercator)
...> |> Visualize.Geo.Projection.scale(256 / (2 * :math.pi()))
...> |> Visualize.Geo.Projection.translate(128, 128)
iex> Visualize.Geo.Tiles.zoom(proj)
0
iex> [tile] = Visualize.Geo.Tiles.cover(proj, {256, 256})
iex> {tile.z, tile.x, tile.y, Float.round(tile.left, 6), Float.round(tile.size, 6)}
{0, 0, 0, 0.0, 256.0}
iex> Visualize.Geo.Tiles.url("https://{s}.tile.example/{z}/{x}/{y}.png", tile, ["a", "b"])
"https://a.tile.example/0/0/0.png"
Summary
Functions
:ok when the projection is tile-aligned — :mercator, a zero centre latitude, no
tilt or roll — else {:error, reason} (spec/07 §8.1).
As cover/3 with no options.
The tiles covering a plot of {width, height} pixels (spec/07 §8.3), in row-then-column
order, each with its wrapped column x, its row y and its square in plot pixels.
A tile's URL (spec/07 §8.4): {z}, {x} and {y} replaced by its address and {s}
by subdomains[rem(x + y, n)]. Raises ArgumentError for {s} with no subdomains.
As zoom/2 with no options.
The zoom level whose 256-pixel tiles are nearest the projection's scale (spec/07 §8.2):
round(log2(2πk / 256)), clamped to [0, max_zoom].
Types
@type tile() :: %{ z: non_neg_integer(), x: non_neg_integer(), y: non_neg_integer(), left: float(), top: float(), size: float() }
One tile of the covering set: its address and its square in plot pixels.
Functions
@spec aligned(Visualize.Geo.Projection.t()) :: :ok | {:error, {:type, atom()} | :center | :rotate}
:ok when the projection is tile-aligned — :mercator, a zero centre latitude, no
tilt or roll — else {:error, reason} (spec/07 §8.1).
iex> Visualize.Geo.Tiles.aligned(Visualize.Geo.Projection.new(:mercator))
:ok
iex> Visualize.Geo.Tiles.aligned(Visualize.Geo.Projection.new(:orthographic))
{:error, {:type, :orthographic}}
@spec cover(Visualize.Geo.Projection.t(), {number(), number()}) :: [tile()]
As cover/3 with no options.
@spec cover(Visualize.Geo.Projection.t(), {number(), number()}, keyword()) :: [tile()]
The tiles covering a plot of {width, height} pixels (spec/07 §8.3), in row-then-column
order, each with its wrapped column x, its row y and its square in plot pixels.
Raises ArgumentError for a projection that is not tile-aligned (aligned/1).
Options
:max_zoom- aszoom/2
A tile's URL (spec/07 §8.4): {z}, {x} and {y} replaced by its address and {s}
by subdomains[rem(x + y, n)]. Raises ArgumentError for {s} with no subdomains.
@spec zoom(Visualize.Geo.Projection.t()) :: non_neg_integer()
As zoom/2 with no options.
@spec zoom(Visualize.Geo.Projection.t(), keyword()) :: non_neg_integer()
The zoom level whose 256-pixel tiles are nearest the projection's scale (spec/07 §8.2):
round(log2(2πk / 256)), clamped to [0, max_zoom].
Options
:max_zoom- the deepest level the provider serves (default19)