
<!-- README.md is generated from README.Rmd. Please edit that file -->

# a5R <a href="https://belian-earth.github.io/a5R/"><img src="man/figures/logo.png" align="right" height="200" alt="a5R website" /></a>

<!-- badges: start -->

[![R-CMD-check](https://github.com/belian-earth/a5R/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/belian-earth/a5R/actions/workflows/R-CMD-check.yaml)
[![Codecov test
coverage](https://codecov.io/gh/belian-earth/a5R/graph/badge.svg)](https://app.codecov.io/gh/belian-earth/a5R)
[![extendr](https://img.shields.io/badge/extendr-%5E0.8.1-276DC2)](https://extendr.rs/extendr/extendr_api/)
[![Lifecycle:
stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable)
[![License:Apache](https://img.shields.io/github/license/belian-earth/a5R)](https://www.apache.org/licenses/LICENSE-2.0)
[![Github
stars](https://img.shields.io/github/stars/belian-earth/a5R?style=social)](https://github.com/belian-earth/a5R/stargazers)
[![GitHub
Issues](https://img.shields.io/github/issues/belian-earth/a5R)](https://github.com/belian-earth/a5R/issues)
[![CRAN
status](https://www.r-pkg.org/badges/version/a5R)](https://CRAN.R-project.org/package=a5R)
<!-- badges: end -->

a5R provides R bindings for the [A5](https://a5geo.org/) pentagonal
geospatial index, powered by the [a5 Rust
crate](https://github.com/felixpalmer/a5-rs) via
[extendr](https://extendr.rs/extendr/extendr_api/).

A5 partitions the Earth’s surface into pentagonal cells across 31
resolution levels. Cells are equal-area, encoded as 64-bit integers, and
achieve millimetre-level precision at the finest resolution.

## Installation

``` r
install.packages("a5R")
```

Or install the development version from GitHub:

``` r
# install.packages("pak")
pak::pak("belian-earth/a5R")
```

You will need a working [Rust toolchain](https://rustup.rs/) (`cargo`
and `rustc`).

## Quick example

``` r
library(a5R)

# Index a point to a cell
cell <- a5_lonlat_to_cell(-3.19, 55.95, resolution = 10)
cell
#> <a5_cell[1]>
#> [1] 6344be8000000000

# 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] 6344be0000000000
a5_cell_to_children(cell)
#> <a5_cell[4]>
#> [1] 6344be2000000000 6344be6000000000 6344bea000000000 6344bee000000000
```

``` r
# Create a collection of cells whose centres fall within a great-circle distance of 100km from the origin cell
cells <- a5_spherical_cap(cell, radius = 100000) |> 
  a5_uncompact(resolution = 10)
plot(a5_cell_to_boundary(cells), col = "#206ead20", border = "#206ead", asp = 1)
```

<img src="man/figures/README-grid-plot-1.png" alt="A5 grid plot showing a collection of cells around a point" width="100%" />

See `vignette("a5R")` for a full walkthrough of indexing, boundaries,
hierarchy, traversal, and grid generation.

## Features

- **Vectorised Rust core** — all operations implemented in Rust and
  called from R via extendr.
  [Benchmarks](https://github.com/belian-earth/a5R/blob/main/benchmarks/RESULTS.md)
  confirm identical results to the Python, JavaScript, and DuckDB A5
  implementations.
- **vctrs + wk integration** — cell indices use an `a5_cell` type with
  tibble support; geometries return as `wk_wkb`/`wk_wkt` vectors
  compatible with sf and terra.
- **Grid generation** — `a5_grid()` fills any bounding box or geometry
  with cells at a target resolution using hierarchical flood-fill.
- **Traversal** — `a5_grid_disk()` and `a5_spherical_cap()` select
  neighbours by hop count or great-circle distance.
- **Multi-threading** — opt-in parallel processing via rayon for
  vectorised operations. See `vignette("multithreading")`.

## Acknowledgements

A5 was created by [Felix Palmer](https://github.com/felixpalmer). This
package is a thin R wrapper around his work and would not exist without
it. The [Query-farm](https://github.com/Query-farm/a5) team maintain the
DuckDB A5 extension, which wraps the same Rust crate and provided a
valuable reference for this project.
