|
1 | 1 | --- |
2 | 2 | id: z7-indexing |
| 3 | +sidebar_position: 5 |
3 | 4 | title: Z7 Indexing |
4 | 5 | --- |
5 | 6 |
|
6 | 7 | # Z7 Indexing |
7 | 8 |
|
8 | | -:::note Coming soon |
9 | | -This page is under construction. |
10 | | -::: |
| 9 | +The **Z7 index** is the core data structure of IGEO7. A single 64-bit integer encodes everything needed to identify a cell: which base cell it belongs to, its resolution, and its exact position within the hierarchy. |
| 10 | + |
| 11 | +## Why a Hierarchical Index? |
| 12 | + |
| 13 | +Traditional geographic coordinate systems (lat/lng, UTM) identify a *point* on the Earth's surface. For spatial analysis at scale, you often need: |
| 14 | + |
| 15 | +- **Aggregation:** group fine-resolution observations into coarser cells |
| 16 | +- **Neighbourhood queries:** find all cells adjacent to a given cell |
| 17 | +- **Spatial joins:** map observations to a uniform grid |
| 18 | + |
| 19 | +A hierarchical index like Z7 enables all of these in O(1) or O(r) time (where r is the resolution), without any geometry computation. |
| 20 | + |
| 21 | +## Structure |
| 22 | + |
| 23 | +A Z7 index is a 64-bit unsigned integer with this layout: |
| 24 | + |
| 25 | +``` |
| 26 | +Bits 63–60 │ Bits 59–57 │ Bits 56–54 │ ... │ Bits 2–0 |
| 27 | +────────────┼──────────────┼──────────────┼───────┼────────── |
| 28 | + Base cell │ Digit 1 │ Digit 2 │ ... │ Digit 20 |
| 29 | + (4 bits) │ (3 bits) │ (3 bits) │ │ (3 bits) |
| 30 | +``` |
| 31 | + |
| 32 | +- **Base cell (4 bits):** which of the 12 icosahedral pentagonal base cells (0–11) the cell belongs to |
| 33 | +- **Resolution digits (20 × 3 bits):** one digit per resolution level, value 0–6 for valid digits, 7 as an "end-of-resolution" sentinel |
| 34 | + |
| 35 | +## The 12 Base Cells |
| 36 | + |
| 37 | +IGEO7 starts from the **12 vertices of the icosahedron**, which become the 12 pentagonal cells at resolution 0. All other cells at all resolutions are hexagons that subdivide the faces around these vertices. |
| 38 | + |
| 39 | +This is fundamentally different from H3, which has 122 resolution-0 cells formed by a mixed aperture 4→3 pre-subdivision. IGEO7's simpler base gives it 5 additional resolution levels. |
| 40 | + |
| 41 | + |
| 42 | + |
| 43 | +## Aperture 7 Subdivision |
| 44 | + |
| 45 | +At each resolution step, every hexagonal cell is subdivided into **7 children**: |
| 46 | + |
| 47 | + |
| 48 | + |
| 49 | +- **Digit 0:** centre child — directly below the parent centroid |
| 50 | +- **Digits 1–6:** six surrounding children, numbered in space-filling curve order |
| 51 | + |
| 52 | +Pentagons are an exception: they have 6 children (1 centre + 5 surrounding), since pentagons have only 5 edges. |
| 53 | + |
| 54 | +## Reading a Z7 Index |
| 55 | + |
| 56 | +The Z7 string format `"0800433"` decodes as: |
| 57 | + |
| 58 | +| Part | Value | Meaning | |
| 59 | +|---|---|---| |
| 60 | +| `08` | base cell 8 | one of the 12 icosahedron vertices | |
| 61 | +| `0` | digit 1 = 0 | centre child at resolution 1 | |
| 62 | +| `0` | digit 2 = 0 | centre child at resolution 2 | |
| 63 | +| `4` | digit 3 = 4 | child 4 at resolution 3 | |
| 64 | +| `3` | digit 4 = 3 | child 3 at resolution 4 | |
| 65 | +| `3` | digit 5 = 3 | child 3 at resolution 5 | |
| 66 | + |
| 67 | +This cell is at **resolution 5** (5 valid digits after the base cell). |
| 68 | + |
| 69 | +## Parent–Child Relationships |
| 70 | + |
| 71 | +**Parent:** remove the last digit. |
| 72 | + |
| 73 | +```python |
| 74 | +z7_str = "0800433" |
| 75 | +parent = z7_str[:-1] # "080043" (resolution 4) |
| 76 | +``` |
| 77 | + |
| 78 | +**Children:** append digits 0–6. |
| 79 | + |
| 80 | +```python |
| 81 | +children = [z7_str + str(d) for d in range(7)] |
| 82 | +# ["08004330", "08004331", ..., "08004336"] |
| 83 | +``` |
| 84 | + |
| 85 | +This works identically on the integer representation via bit operations: |
| 86 | + |
| 87 | +```python |
| 88 | +# Get parent (set last valid digit group to 0b111) |
| 89 | +def get_parent(z7_int: int, resolution: int) -> int: |
| 90 | + shift = 57 - 3 * (resolution - 1) |
| 91 | + mask = ~(0x7 << shift) |
| 92 | + return (z7_int & mask) | (0x7 << shift) |
| 93 | +``` |
| 94 | + |
| 95 | +## The Space-Filling Curve |
| 96 | + |
| 97 | +The Z7 index order is not arbitrary — it defines a **space-filling curve** over the sphere. Cells that are adjacent in Z7 integer order tend to be spatially close. This property: |
| 98 | + |
| 99 | + |
| 100 | + |
| 101 | +- Improves cache locality when processing large datasets in index order |
| 102 | +- Makes range scans on indexed database columns spatially coherent |
| 103 | +- Is analogous to the Hilbert curve used in many raster spatial indexing schemes |
| 104 | + |
| 105 | +## Digit 0: The Centre Cell |
| 106 | + |
| 107 | +The digit `0` always means "the child that contains the parent's centroid". This is a consistent orientation anchor: no matter which base cell or resolution you're at, digit `0` is always the spatial centre. |
| 108 | + |
| 109 | +This means the **path of all-zero digits** (e.g., `"080000...0"`) traces a straight line from the icosahedron vertex down to the finest resolution, always staying at the centre of each parent cell. |
| 110 | + |
| 111 | +## Comparison with H3 Indexing |
| 112 | + |
| 113 | +| Property | Z7 (IGEO7) | H3 | |
| 114 | +|---|---|---| |
| 115 | +| Index size | 64-bit integer | 64-bit integer | |
| 116 | +| Base cell bits | 4 (values 0–11) | 7 (values 0–121) | |
| 117 | +| Digit size | 3 bits (values 0–6, 7=sentinel) | 3 bits (values 0–6, 7=sentinel) | |
| 118 | +| Max resolution | 20 | 15 | |
| 119 | +| Digit encoding | 0=centre, 1–6=surrounding | 0=centre, 1–6=surrounding | |
| 120 | +| String format | `BB` + up to 20 octal digits | 15-hex-char string | |
| 121 | + |
| 122 | +The indexing philosophy is nearly identical — both use 64-bit integers with 3-bit resolution digits and a sentinel value. The key differences are at the base cell level: Z7 has 12 pure-aperture-7 base cells; H3 has 122 mixed-aperture base cells. |
| 123 | + |
| 124 | +## Neighbourhood Traversal |
| 125 | + |
| 126 | +Finding neighbours requires Z7 arithmetic — specifically, Central Place Indexing (CPI) addition with carry propagation across base cell boundaries. This is implemented in [IGEO7.jl](https://github.com/allixender/IGEO7.jl) and the [C++ work](https://github.com/wrenoud/Z7/) by W.Renoud J.Shaw. |
| 127 | + |
| 128 | + |
| 129 | + |
| 130 | +## See Also |
| 131 | + |
| 132 | +- [Z7 Bit Layout](../reference/z7-bit-layout) — detailed binary encoding |
| 133 | +- [Z7 String Format](../reference/z7-string-format) — the two external string representations |
| 134 | +- [Aperture 7 Hierarchy](./aperture7) — the subdivision geometry |
| 135 | +- [Pentagons](./pentagons) — the 12 special cells |
0 commit comments