# How It Works

## The Problem

GPS coordinates like `(5.34519, -4.02868)` are precise but unwieldy. They're hard for humans to remember, communicate, or write on paper. In regions without postal addresses, there's no alternative — until now.

## The Solution: Hilbert Curve Bijection

Yoro uses a **2D Hilbert space-filling curve** to create a reversible mapping between GPS coordinates and short alphanumeric codes.

### Step 1: Domain Bounding Box

Each domain (e.g. `CI` for Cote d'Ivoire) defines a geographic bounding box:

```
CI: lat [4.36, 10.74], lon [-8.6, -2.49]
```

This constrains the coordinate space, giving better resolution per character than a global system.

### Step 2: Grid Discretization

The bounding box is divided into a `2^p × 2^p` grid, where `p` is the **Hilbert order** (precision). For `p=12`, that's a 4096×4096 grid = 16.7 million cells over Cote d'Ivoire.

The GPS coordinate `(lat, lon)` is mapped to a grid cell `(x, y)`:

```
x = floor((lon - lon_min) / (lon_max - lon_min) × 2^p)
y = floor((lat - lat_min) / (lat_max - lat_min) × 2^p)
```

### Step 3: Hilbert Curve Index

The 2D grid position `(x, y)` is converted to a 1D **Hilbert distance** `d` using the standard Hilbert curve algorithm. This is the key insight: the Hilbert curve preserves **spatial locality** — nearby points in 2D map to nearby values in 1D.

```
(x, y) → d    (via xy2d)
d → (x, y)    (via d2xy, the inverse)
```

### Step 4: Base-29 Encoding

The Hilbert distance `d` is encoded in **base-29** using an alphabet designed to avoid ambiguity:

```
2 3 4 5 6 7 8 9 A B C D E F G H J K M N P Q R S T V W X Y
```

Excluded characters: `0` (confused with `O`), `1` (confused with `I`/`L`), `I`, `L`, `O`, `U` (confused with `V`).

### Step 5: Domain Prefix

The final code is `{domain}-{base29}`, e.g. `CI-PV9XD`.

## Decoding

Decoding reverses the process exactly:

1. Split `CI-PV9XD` → domain `CI`, code `PV9XD`
2. Base-29 → Hilbert distance `d`
3. Hilbert distance → grid position `(x, y)`
4. Grid position → GPS center of cell `(lat, lon)` + bounding box

## Why Hilbert Curves?

Why not just use a simple row-major grid? The Hilbert curve has a unique property: **it preserves spatial locality better than any other space-filling curve**. Two codes that are numerically close are also geographically close. This means:

- **Prefix sharing** — codes in the same area tend to share leading characters
- **Neighbor queries** — the 8 adjacent cells can be computed with simple arithmetic
- **Range queries** — a bounding box maps to a small set of Hilbert index ranges

## The Base-29 Quantization Effect

The code length `k` is determined by:

```
k = ceil(2p × log(2) / log(29))
```

Since `k` must be an integer, several values of `p` produce the same `k`. Only the **canonical precision** — the highest `p` for each `k` — fully exploits the address space. Use `yoro.precision_levels()` to see them, and `yoro.snap_precision(p)` to check which canonical `p` your requested value maps to.
