| Title: | 'A5' Discrete Global Grid System |
|---|---|
| Description: | Bindings for the "A5 geospatial index" <https://a5geo.org/>. 'A5' partitions the Earth's surface into pentagonal cells across 31 resolution levels using an equal-area projection onto a dodecahedron. Provides functions for indexing coordinates to cells, traversing the cell hierarchy, computing cell boundaries, and compacting/uncompacting cell sets. Powered by the 'A5' 'Rust' crate via 'extendr'. |
| Authors: | Hugh Graham [aut, cre], belian.earth [cph] |
| Maintainer: | Hugh Graham <[email protected]> |
| License: | Apache License (>= 2) |
| Version: | 0.4.0.9000 |
| Built: | 2026-05-14 15:21:42 UTC |
| Source: | https://github.com/belian-earth/a5r |
Create, test, and coerce A5 cell index vectors. Cells are stored as
a record with eight raw-byte fields (b1–b8) representing the
little-endian bytes of the u64 cell ID. This avoids the precision
loss of floating-point storage and keeps memory compact.
a5_cell(x = character()) is_a5_cell(x) as_a5_cell(x) a5_is_valid(x)a5_cell(x = character()) is_a5_cell(x) as_a5_cell(x) a5_is_valid(x)
x |
A character vector of hex-encoded A5 cell IDs, or an object coercible to one. |
An a5_cell vector (a5_cell, as_a5_cell), a logical
scalar (is_a5_cell), or a logical vector (a5_is_valid).
cells <- a5_cell(c("0800000000000006", "0800000000000016")) cells a5_is_valid(c("0800000000000006", "not_a_cell", NA))cells <- a5_cell(c("0800000000000006", "0800000000000016")) cells a5_is_valid(c("0800000000000006", "not_a_cell", NA))
Returns the area of a single cell in square metres at the given resolution(s). Because A5 is an equal-area DGGS, all cells at the same resolution have identical area.
a5_cell_area(resolution, units = "m^2")a5_cell_area(resolution, units = "m^2")
resolution |
Integer vector of resolutions (0–30). |
units |
Character scalar specifying the output area unit (default
|
A units::units vector of areas.
a5_cell_area(0:5) a5_cell_area(5, units = "km^2")a5_cell_area(0:5) a5_cell_area(5, units = "km^2")
Computes the distance between the centroids of pairs of A5 cells using the specified method.
a5_cell_distance( from, to, units = "m", method = c("haversine", "geodesic", "rhumb") )a5_cell_distance( from, to, units = "m", method = c("haversine", "geodesic", "rhumb") )
from, to
|
a5_cell vectors (recycled to common length). |
units |
Character scalar specifying the distance unit (default
|
method |
Distance calculation method. One of |
A units::units vector of distances.
a5_cell_to_lonlat() for cell centroids,
a5_cell_area() for cell areas.
a <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 24) b <- a5_lonlat_to_cell(-3.10, 55.90, resolution = 24) a5_cell_distance(a, b) a5_cell_distance(a, b, units = "km") a5_cell_distance(a, b, method = "geodesic")a <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 24) b <- a5_lonlat_to_cell(-3.10, 55.90, resolution = 24) a5_cell_distance(a, b) a5_cell_distance(a, b, units = "km") a5_cell_distance(a, b, method = "geodesic")
Losslessly convert between a5_cell vectors and Arrow uint64
arrays. This avoids the precision loss that occurs when Arrow
converts uint64 to R's double (which can only represent
integers exactly up to 2^53, while A5 cell IDs span the full
0–2^64 range).
a5_cell_from_arrow(x) a5_cell_to_arrow(x)a5_cell_from_arrow(x) a5_cell_to_arrow(x)
x |
For |
Internally these use Arrow's zero-copy View() to reinterpret
uint64 bytes as fixed_size_binary(8), then convert to/from the
raw-byte representation used by a5_cell. The resulting Arrow
arrays can be written directly to Parquet and read correctly by
DuckDB, Python, and other Arrow-compatible tools.
a5_cell_from_arrow() returns an a5_cell vector.
a5_cell_to_arrow() returns an Arrow Array of type uint64.
a5_u64_to_hex() for converting to hex strings instead.
cell <- a5_lonlat_to_cell(135, 0, resolution = 10) arr <- a5_cell_to_arrow(cell) back <- a5_cell_from_arrow(arr) identical(format(cell), format(back)) cells <- a5_lonlat_to_cell(c(-3.19, 135), c(55.95, 0), resolution = 10) arr <- a5_cell_to_arrow(cells) arr$type$ToString()cell <- a5_lonlat_to_cell(135, 0, resolution = 10) arr <- a5_cell_to_arrow(cell) back <- a5_cell_from_arrow(arr) identical(format(cell), format(back)) cells <- a5_lonlat_to_cell(c(-3.19, 135), c(55.95, 0), resolution = 10) arr <- a5_cell_to_arrow(cells) arr$type$ToString()
Returns the boundary of each cell as a wk::wkt() or wk::wkb()
polygon geometry. Boundaries are pentagonal polygons on the WGS 84
ellipsoid.
a5_cell_to_boundary( cell, format = c("wkb", "wkt"), closed = TRUE, segments = NULL )a5_cell_to_boundary( cell, format = c("wkb", "wkt"), closed = TRUE, segments = NULL )
cell |
An a5_cell vector. |
format |
Character scalar, either |
closed |
Logical scalar; if |
segments |
Integer scalar or |
A wk_wkt or wk_wkb vector of polygon geometries with
wk::wk_crs_longlat() CRS.
a5_cell_to_lonlat() for cell centroids.
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) a5_cell_to_boundary(cell) a5_cell_to_boundary(cell, format = "wkt")cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) a5_cell_to_boundary(cell) a5_cell_to_boundary(cell, format = "wkt")
Returns the child cells of a single cell. By default returns the 4 immediate children (one resolution finer). Optionally target a specific finer resolution.
a5_cell_to_children(cell, resolution = NULL)a5_cell_to_children(cell, resolution = NULL)
cell |
A single a5_cell value. |
resolution |
Integer scalar target child resolution, or |
An a5_cell vector of child cells.
a5_cell_to_parent(), a5_get_resolution()
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) a5_cell_to_children(cell)cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) a5_cell_to_children(cell)
Returns the centre-point longitude and latitude of each cell.
a5_cell_to_lonlat(cell, as_dataframe = FALSE)a5_cell_to_lonlat(cell, as_dataframe = FALSE)
cell |
An a5_cell vector (or character coercible to one). |
as_dataframe |
Logical scalar controlling the return container.
When |
A wk::xy() vector (if as_dataframe = FALSE) or a
data.frame with columns lon and lat (if as_dataframe = TRUE).
a5_lonlat_to_cell() for the inverse operation,
a5_cell_to_boundary() for full cell polygons.
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) a5_cell_to_lonlat(cell) # Data frame output cell2 <- a5_lonlat_to_cell(114.8, 4.1, resolution = 5) a5_cell_to_lonlat(cell2, as_dataframe = TRUE)cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) a5_cell_to_lonlat(cell) # Data frame output cell2 <- a5_lonlat_to_cell(114.8, 4.1, resolution = 5) a5_cell_to_lonlat(cell2, as_dataframe = TRUE)
Returns the parent cell of each input cell. By default returns the immediate parent (one resolution coarser). Optionally target a specific coarser resolution.
a5_cell_to_parent(cell, resolution = NULL)a5_cell_to_parent(cell, resolution = NULL)
cell |
An a5_cell vector. |
resolution |
Integer scalar target parent resolution, or |
An a5_cell vector of parent cells.
a5_cell_to_children(), a5_get_resolution()
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 10) a5_cell_to_parent(cell) a5_cell_to_parent(cell, resolution = 5)cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 10) a5_cell_to_parent(cell) a5_cell_to_parent(cell, resolution = 5)
Merges complete sibling groups into their common parent, reducing the number of cells while preserving coverage.
a5_compact(cells)a5_compact(cells)
cells |
An a5_cell vector. |
An a5_cell vector of compacted cells.
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) children <- a5_cell_to_children(cell) a5_compact(children) # back to the parentcell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) children <- a5_cell_to_children(cell) a5_compact(children) # back to the parent
Total number of cells at a given resolution
a5_get_num_cells(resolution)a5_get_num_cells(resolution)
resolution |
Integer scalar resolution (0–30). |
A numeric scalar (double) giving the total count. Returned as double because the count can exceed R's integer range.
a5_get_num_cells(0) a5_get_num_cells(10)a5_get_num_cells(0) a5_get_num_cells(10)
Returns the number of child cells each parent cell contains when expanding from one resolution to another.
a5_get_num_children(parent_resolution, child_resolution)a5_get_num_children(parent_resolution, child_resolution)
parent_resolution |
Integer scalar (0–30). |
child_resolution |
Integer scalar (0–30), must be >=
|
A numeric scalar. Returned as double because the count can exceed R's integer range at large resolution deltas.
a5_get_num_cells(), a5_cell_to_children(),
a5_uncompact()
a5_get_num_children(5, 8) # 4^3 = 64 a5_get_num_children(0, 5)a5_get_num_children(5, 8) # 4^3 = 64 a5_get_num_children(0, 5)
Returns the 12 root cells corresponding to the 12 faces of the dodecahedron.
a5_get_res0_cells()a5_get_res0_cells()
An a5_cell vector of length 12.
a5_get_res0_cells()a5_get_res0_cells()
Extracts the resolution level (0–30) encoded in each cell index.
a5_get_resolution(cell)a5_get_resolution(cell)
cell |
An a5_cell vector. |
An integer vector of resolutions.
a5_cell_to_parent(), a5_cell_to_children()
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 10) a5_get_resolution(cell)cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 10) a5_get_resolution(cell)
Generate a grid of A5 cells covering an area
a5_grid(x, resolution)a5_grid(x, resolution)
x |
An area specification. One of:
|
resolution |
Integer scalar target resolution (0–30). |
Returns all cells at the target resolution that intersect the given geometry. Uses hierarchical flood-fill: starting from the 12 resolution-0 root cells, the algorithm repeatedly expands and prunes by spatial intersection until the target resolution is reached.
Grid generation runs entirely in Rust via hierarchical flood-fill with bounding-box pruning. For non-bbox geometry inputs, an exact intersection filter removes cells that fall outside the target shape. No cell count limit is imposed — high resolutions over large areas can consume significant memory.
Input geometries must use WGS 84 coordinates; projected geometries are
not reprojected and will produce incorrect results. Multiple geometries
are collected into a GEOMETRYCOLLECTION automatically.
Antimeridian-crossing bounding boxes are supported: when xmin > xmax
(e.g. c(170, -50, -170, -30)), the bbox is split at the antimeridian.
Limitation: spatial filtering uses planar geometry on lon/lat coordinates, which can produce incomplete results very close to the poles (above ~88° latitude) or the antimeridian. Use a larger target geometry to ensure complete coverage in these areas.
An a5_cell vector of cells at resolution that intersect x.
a5_cell_to_boundary() to convert result cells to geometries.
# Grid from a bounding box cells <- a5_grid(c(-3.3, 55.9, -3.1, 56.0), resolution = 5) cells # Grid from a WKT polygon poly <- wk::wkt("POLYGON ((-3.3 55.9, -3.1 55.9, -3.1 56, -3.3 56, -3.3 55.9))") cells <- a5_grid(poly, resolution = 5)# Grid from a bounding box cells <- a5_grid(c(-3.3, 55.9, -3.1, 56.0), resolution = 5) cells # Grid from a WKT polygon poly <- wk::wkt("POLYGON ((-3.3 55.9, -3.1 55.9, -3.1 56, -3.3 56, -3.3 55.9))") cells <- a5_grid(poly, resolution = 5)
Returns all cells reachable within k edge hops of a centre cell,
including the centre cell itself.
a5_grid_disk(cell, k, vertex = FALSE)a5_grid_disk(cell, k, vertex = FALSE)
cell |
A single a5_cell value. |
k |
Integer scalar, number of hops. |
vertex |
Logical scalar. If |
A compacted a5_cell vector.
a5_spherical_cap() for distance-based selection.
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 8) a5_grid_disk(cell, k = 1)cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 8) a5_grid_disk(cell, k = 1)
Returns the A5 cells at resolution whose pentagons are intersected by
the great-circle polyline connecting the supplied waypoints. Output is
uncompacted, in discovery order along the path, with duplicates removed
first-seen. Multi-feature inputs (a MULTILINESTRING or an sfc of
multiple linestrings) are handled natively: per-feature cell sequences
are concatenated in feature order with first-seen deduplication.
a5_linestring_to_cells(x, resolution)a5_linestring_to_cells(x, resolution)
x |
A linestring-like geometry. One of:
|
resolution |
Integer scalar target resolution (0–30). |
Consecutive waypoints are connected by great-circle arcs (not rhumb lines or planar segments), so antimeridian-crossing paths work transparently when written in unwrapped lon/lat.
Matrix and data.frame inputs are treated as a single linestring;
for multi-feature data, pass an sf, sfc, wk, or SpatVector
geometry instead.
An a5_cell vector at resolution.
a5_polygon_to_cells(), a5_grid_disk().
line <- wk::wkt("LINESTRING (2.35 48.86, -0.13 51.51)") cells <- a5_linestring_to_cells(line, resolution = 6) length(cells)line <- wk::wkt("LINESTRING (2.35 48.86, -0.13 51.51)") cells <- a5_linestring_to_cells(line, resolution = 6) length(cells)
Maps longitude/latitude coordinates to A5 cell indices at the specified resolution.
a5_lonlat_to_cell(lon, lat, resolution)a5_lonlat_to_cell(lon, lat, resolution)
lon |
Numeric vector of longitudes in degrees. |
lat |
Numeric vector of latitudes in degrees. |
resolution |
Integer scalar or vector of resolutions (0–30). |
An a5_cell vector of cell indices.
a5_cell_to_lonlat() for the inverse operation.
a5_lonlat_to_cell(-3.19, 55.95, resolution = 5)a5_lonlat_to_cell(-3.19, 55.95, resolution = 5)
Returns A5 cells at resolution whose centres fall inside the polygon.
Multi-feature inputs (a MULTIPOLYGON, an sfc of multiple polygons,
or a POLYGON with holes) are handled natively: per polygon part, the
outer-ring cells are computed and any hole-ring cells are subtracted,
then the results are unioned across parts. The final cell set is
compacted; use a5_uncompact() to expand to a uniform-resolution grid.
a5_polygon_to_cells(x, resolution)a5_polygon_to_cells(x, resolution)
x |
A polygon-like geometry. One of:
|
resolution |
Integer scalar target resolution (0-30). |
Membership is determined by centre-point containment: a cell is
included iff its centroid lies inside the polygon, with hole rings
properly subtracted. This is distinct from a5_grid()'s
boundary-intersection semantics; for the same polygon the two
functions can return slightly different cell sets near the boundary.
Coordinates must be WGS 84 longitude/latitude in degrees. Rings are closed automatically; a trailing duplicate vertex is dropped if present.
Where no A5 cell centroids at the specified resolution fall within
the geometry, an empty a5_cell vector is returned.
Matrix and data.frame inputs are treated as a single ring; for
multi-feature data or polygons with holes, pass an sf, sfc, wk,
or SpatVector geometry instead.
An a5_cell vector at or coarser than resolution.
a5_linestring_to_cells(), a5_uncompact().
poly <- wk::wkt( "POLYGON ((-3.3 55.9, -3.1 55.9, -3.1 56, -3.3 56, -3.3 55.9))" ) cells <- a5_polygon_to_cells(poly, resolution = 8) length(cells)poly <- wk::wkt( "POLYGON ((-3.3 55.9, -3.1 55.9, -3.1 56, -3.3 56, -3.3 55.9))" ) cells <- a5_polygon_to_cells(poly, resolution = 8) length(cells)
Controls the number of threads used for parallel processing in vectorised functions. Set to 1 (the default) for sequential processing with zero overhead, or higher for parallel execution via rayon.
a5_set_threads(n = 1L) a5_get_threads()a5_set_threads(n = 1L) a5_get_threads()
n |
Integer scalar. Number of threads. Must be >= 1. |
Invisibly returns the previous thread count.
Integer scalar.
Returns all cells whose centres fall within a great-circle distance of a given cell's centre.
a5_spherical_cap(cell, radius)a5_spherical_cap(cell, radius)
cell |
A single a5_cell value. |
radius |
Numeric scalar, great-circle radius in metres. |
A compacted a5_cell vector.
a5_grid_disk() for hop-based selection.
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 8) a5_spherical_cap(cell, radius = 1000)cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 8) a5_spherical_cap(cell, radius = 1000)
a5_u64_to_hex() converts an a5_cell vector to 16-character
zero-padded hex strings. a5_hex_to_u64() converts hex strings to
an a5_cell vector.
a5_u64_to_hex(x) a5_hex_to_u64(x)a5_u64_to_hex(x) a5_hex_to_u64(x)
x |
For |
These are named to match u64_to_hex / hex_to_u64 in the upstream
Python, JavaScript, and DuckDB A5 bindings. In those languages the
functions convert between a native 64-bit unsigned integer and its hex
representation. Because R has no native uint64 type, a5_u64_to_hex()
accepts an a5_cell (which stores the u64 internally as eight raw
bytes) instead of a bare integer.
a5_u64_to_hex() returns a character vector. a5_hex_to_u64()
returns an a5_cell vector.
a5_cell_from_arrow() and a5_cell_to_arrow() for lossless
conversion between a5_cell and Arrow uint64 arrays.
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) hex <- a5_u64_to_hex(cell) hex a5_hex_to_u64(hex)cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) hex <- a5_u64_to_hex(cell) hex a5_hex_to_u64(hex)
Expands each cell to its descendants at the target resolution.
a5_uncompact(cells, resolution)a5_uncompact(cells, resolution)
cells |
An a5_cell vector. |
resolution |
Integer scalar target resolution (0–30). |
An a5_cell vector of uncompacted cells.
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) a5_uncompact(cell, resolution = 7)cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 5) a5_uncompact(cell, resolution = 7)
Integration with the wk geometry framework. Allows
a5_cell vectors to be handled as geometry (via their boundary polygons)
and to report their CRS.
## S3 method for class 'a5_cell' wk_handle(handleable, handler, ...) ## S3 method for class 'a5_cell' wk_crs(x)## S3 method for class 'a5_cell' wk_handle(handleable, handler, ...) ## S3 method for class 'a5_cell' wk_crs(x)
handleable, x
|
An a5_cell vector. |
handler |
A wk handler. |
... |
Passed to underlying methods. |
wk_handle(): the result of the handler.
wk_crs(): a wk::wk_crs object (WGS 84 lon/lat).