# `TzWorld.Backend.SpatialIndex`
[🔗](https://github.com/kipcole9/tz_world/blob/v2.1.0/lib/tz_world/backend/spatial_index.ex#L1)

Resolves timezones from a coordinate using an R-tree spatial index
held in `:persistent_term`.

This is the recommended backend and is also the default — applications
that do not pin `:default_backend` will pick it up automatically as
long as it is started in the supervision tree.

## How it works

At startup the backend reads the compressed timezone shape data
shipped in `priv/`, builds a Sort-Tile-Recursive packed R-tree over
every shape's bounding box (one entry per sub-polygon for
`Geo.MultiPolygon` shapes), and stores three terms in
`:persistent_term`:

* the R-tree itself,

* a tuple of every shape geometry indexed by leaf id,

* the data version string.

Lookups (`TzWorld.timezone_at/1` and `TzWorld.all_timezones_at/1`)
read these terms directly. They do not go through the GenServer
mailbox and do not copy any term, which makes them lock-free and
safe to call from any number of processes concurrently.

## Reload

`reload_timezone_data/0` rebuilds the index and rewrites all three
persistent terms. Each `:persistent_term.put/2` triggers a global
garbage collection for every process that references any persistent
term — this is fine when reload is invoked manually after a data
update but would be costly on the hot path. Reload should not be
called on every request.

## Memory profile

The full shape data is held in memory (typically several hundred
megabytes depending on whether ocean coverage is included). For
memory-constrained environments, consider
`TzWorld.Backend.DetsWithIndexCache`.

## Public API

In normal use you will not call functions on this module directly —
use `TzWorld.timezone_at/1`, `TzWorld.all_timezones_at/1`,
`TzWorld.version/0`, and `TzWorld.reload_timezone_data/0`. Add this
module to your supervision tree to make it the running backend:

    children = [
      TzWorld.Backend.SpatialIndex
    ]

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `start_link`

Start the backend and bulk-load the spatial index.

The load is performed synchronously inside `init/1`, so once
`start_link/1` returns the persistent terms are populated and
lookups are immediately ready to serve.

### Arguments

* `options` is a keyword list passed through to
  `GenServer.start_link/3`. There are no backend-specific options.

### Returns

* `{:ok, pid}` if the backend started and finished loading.

* `{:error, reason}` if the compressed timezone data could not be
  found or decoded — typically because `mix tz_world.update` has not
  yet been run.

---

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