a5R provides R bindings for the A5 pentagonal geospatial index, powered by the a5 Rust crate via extendr.
A5 partitions the Earth’s surface into pentagonal cells across 31 resolution levels. Cells are equal-area and encoded as 64-bit integers; at the finest resolution each covers about 30 mm².
a5R 1.0 uses the A5 1.0 cell index, which numbers cells differently from
earlier versions. Convert ids stored by a5R 0.x with a5_migrate().
install.packages("a5R")
Or install the development version from GitHub:
# install.packages("pak")
# pak::pak("belian-earth/a5R")
install.packages("a5R", repos = c('https://belian-earth.r-universe.dev', 'https://cloud.r-project.org'))
Building from source needs a Rust toolchain
(cargo and rustc).
library(a5R)
# Index a point to a cell
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 10)
cell
#> <a5_cell[1]>
#> [1] 63bb948000000000
# Get the boundary polygon
a5_cell_to_boundary(cell)
#> <wk_wkb[1] with CRS=OGC:CRS84>
#> [1] <POLYGON ((-3.175718 55.93546, -3.145905 55.97569, -3.151641 56.01921, -3.219413 56.00818, -3.226037 55.96443, -3.175718 55.93546...>
# Navigate the hierarchy
a5_cell_to_parent(cell)
#> <a5_cell[1]>
#> [1] 63bb960000000000
a5_cell_to_children(cell)
#> <a5_cell[4]>
#> [1] 63bb942000000000 63bb946000000000 63bb94a000000000 63bb94e000000000
Polygons become coverings, one per feature. Here North Carolina’s counties are filled with cells, coloured by their distance from Wake County’s centroid:
nc <- sf::read_sf(system.file("shape/nc.shp", package = "sf")) |>
sf::st_transform(4326)
nc$a5 <- a5_polygon_to_cells(nc, resolution = 9, containment = "overlapping")
cells <- unique(a5_uncompact(nc$a5))
wake <- sf::st_coordinates(sf::st_centroid(nc$geometry[nc$NAME == "Wake"]))
centre <- a5_lonlat_to_cell(wake[, 1], wake[, 2], resolution = 9)
dist <- a5_cell_distance(centre, cells, units = "km")
plot(a5_cell_to_boundary(cells), col = hcl.colors(50)[cut(as.numeric(dist), 50)], border = "grey50", lwd = 0.5)
plot(nc$geometry, border = "white", lwd = 0.5, add = TRUE)

See vignette("a5R") for a full walkthrough of indexing, boundaries,
hierarchy, traversal, and geometry-to-cell conversion.
a5_cell type with
tibble support; geometries return as wk_wkb/wk_wkt vectors
compatible with sf and terra.a5_covering vectors,
one compacted cell set per feature, that combine (a5_union(),
a5_intersect(), a5_difference()), test (a5_contains()) and
measure (a5_area()) without expanding to millions of cells. See
vignette("coverings").a5_polygon_to_cells() and
a5_line_string_to_cells() map polygons and great-circle lines to
cells.a5_grid_disk() and a5_spherical_cap() select
neighbours by hop count or great-circle distance.a5_cell_to_supercell() and
a5_cell_to_subcells() move between resolutions by location, so
aggregation counts each fine cell inside the coarse cell it lies in.uint64
columns and back exactly, with the A5 index recorded in the schema.
See vignette("arrow-parquet").vignette("multithreading").A5 was created by Felix Palmer. This package is a thin R wrapper around his work and would not exist without it. The Query-farm team maintain the DuckDB A5 extension, which wraps the same Rust crate and provided a valuable reference for this project.