# `Sidereon.Terrain.MmapTerrain`
[🔗](https://github.com/neilberkman/sidereon-ex/blob/main/lib/sidereon/terrain/mmap_terrain.ex#L1)

Memory-mappable terrain store conversion and lookup.

A terrain store is a single byte container built from DTED tiles. The reader
can be opened from bytes with `from_bytes/1` or from a path with `from_path/1`.
Heights returned by this module are typed as orthometric height `H` in metres
above the EGM96 mean sea level geoid. Use the ellipsoidal conversion functions
when a WGS84 ellipsoidal height `h = H + N` is needed.

Terrain lookup axes are always `(longitude_deg, latitude_deg)`.

# `interpolation`

```elixir
@type interpolation() :: :bilinear | :nearest_posting
```

Terrain interpolation method.

# `t`

```elixir
@type t() :: %Sidereon.Terrain.MmapTerrain{handle: reference()}
```

Parsed terrain store handle.

# `terrain_datum_error`

```elixir
@type terrain_datum_error() :: Sidereon.Terrain.MmapTerrain.TerrainDatumError.t()
```

Terrain datum conversion or geoid-grid loading error.

# `terrain_store_error`

```elixir
@type terrain_store_error() :: Sidereon.Terrain.MmapTerrain.TerrainStoreError.t()
```

Terrain store conversion or parse error.

# `checksum64`

```elixir
@spec checksum64(t() | binary()) :: non_neg_integer()
```

Return a checksum for a parsed store handle or terrain store bytes.

# `dted_tree_to_mmap_store`

```elixir
@spec dted_tree_to_mmap_store(String.t()) ::
  {:ok, binary()} | {:error, terrain_store_error() | term()}
```

Convert a DTED tile tree into terrain store bytes.

# `ellipsoidal_height_m`

```elixir
@spec ellipsoidal_height_m(t(), number(), number(), keyword()) ::
  {:ok, Sidereon.Terrain.MmapTerrain.EllipsoidalHeightM.t()}
  | {:error, terrain_datum_error() | term()}
```

Return WGS84 ellipsoidal terrain height using the embedded EGM96 1-degree grid.

# `ellipsoidal_height_m_with_model`

```elixir
@spec ellipsoidal_height_m_with_model(
  t(),
  number(),
  number(),
  Sidereon.Terrain.MmapTerrain.TerrainGeoidModel.t() | :egm96_one_degree,
  keyword()
) ::
  {:ok, Sidereon.Terrain.MmapTerrain.EllipsoidalHeightM.t()}
  | {:error, terrain_datum_error() | term()}
```

Return WGS84 ellipsoidal terrain height with an explicit geoid model.

Passing `TerrainGeoidModel.egm96_fifteen_minute/1` requires a loaded
`Egm96FifteenMinuteGeoid`; it never falls back to the embedded 1-degree grid.

# `ellipsoidal_height_m_with_options`

```elixir
@spec ellipsoidal_height_m_with_options(t(), number(), number(), keyword()) ::
  {:ok, Sidereon.Terrain.MmapTerrain.EllipsoidalHeightM.t()}
  | {:error, terrain_datum_error() | term()}
```

Return WGS84 ellipsoidal terrain height with lookup options.

# `from_bytes`

```elixir
@spec from_bytes(binary()) :: {:ok, t()} | {:error, terrain_store_error() | term()}
```

Parse terrain store bytes into a reader handle.

# `from_path`

```elixir
@spec from_path(String.t()) :: {:ok, t()} | {:error, terrain_store_error() | term()}
```

Read a terrain store file into a reader handle.

# `from_vec`

```elixir
@spec from_vec(binary()) :: {:ok, t()} | {:error, terrain_store_error() | term()}
```

Parse owned terrain store bytes into a reader handle.

# `height_batch`

```elixir
@spec height_batch(t(), [{number(), number()}], keyword()) ::
  [ok: Sidereon.Terrain.MmapTerrain.OrthometricHeightM.t(), error: term()]
  | {:error, term()}
```

Evaluate `(longitude_deg, latitude_deg)` points as orthometric heights.

# `height_m`

```elixir
@spec height_m(t(), number(), number(), keyword()) ::
  {:ok, Sidereon.Terrain.MmapTerrain.OrthometricHeightM.t()} | {:error, term()}
```

Return orthometric terrain height at `(longitude_deg, latitude_deg)`.

# `height_m_with_options`

```elixir
@spec height_m_with_options(t(), number(), number(), keyword()) ::
  {:ok, Sidereon.Terrain.MmapTerrain.OrthometricHeightM.t()} | {:error, term()}
```

Return orthometric terrain height at `(longitude_deg, latitude_deg)` with lookup options.

# `orthometric_height_batch`

```elixir
@spec orthometric_height_batch(t(), [{number(), number()}], keyword()) ::
  [ok: Sidereon.Terrain.MmapTerrain.OrthometricHeightM.t(), error: term()]
  | {:error, term()}
```

Evaluate `(longitude_deg, latitude_deg)` points as typed orthometric heights.

# `orthometric_height_m`

```elixir
@spec orthometric_height_m(t(), number(), number(), keyword()) ::
  {:ok, Sidereon.Terrain.MmapTerrain.OrthometricHeightM.t()} | {:error, term()}
```

Return typed orthometric terrain height at `(longitude_deg, latitude_deg)`.

# `orthometric_height_m_with_options`

```elixir
@spec orthometric_height_m_with_options(t(), number(), number(), keyword()) ::
  {:ok, Sidereon.Terrain.MmapTerrain.OrthometricHeightM.t()} | {:error, term()}
```

Return typed orthometric terrain height with lookup options.

# `terrain_store_checksum64`

```elixir
@spec terrain_store_checksum64(binary()) :: non_neg_integer()
```

Return the FNV-1a checksum for terrain store bytes.

# `tile_index`

```elixir
@spec tile_index(t()) :: [Sidereon.Terrain.MmapTerrain.TerrainStoreTileIndex.t()]
```

Return parsed tile index records.

# `to_bytes`

```elixir
@spec to_bytes(t()) :: binary()
```

Return canonical terrain store bytes from a parsed handle.

# `vertical_datum`

```elixir
@spec vertical_datum(t()) :: Sidereon.Terrain.MmapTerrain.VerticalDatum.t()
```

Return the file-level vertical datum.

# `write_dted_tree_to_mmap_store`

```elixir
@spec write_dted_tree_to_mmap_store(String.t(), String.t()) ::
  :ok | {:error, terrain_store_error() | term()}
```

Convert a DTED tile tree and write terrain store bytes to `out_path`.

---

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