The package h3 provides R bindings for H3, a hexagonal hierarchical spatial indexing system.
See also H3 Tutorial.
library(h3)
# Index a lat/lng point to an H3 index
coords <- c(37.5, -122.5)
res <- 9
(h3_index <- geo_to_h3(coords, res))
## [1] "8928342e20fffff"
# Get the center of an H3 index as a lat/lng point
h3_to_geo(h3_index)
## lat lng
## [1,] 37.50125 -122.5003
# Get the vertices of an H3 index as lat/lng points
h3_to_geo_boundary(h3_index)
## [[1]]
## lat lng
## [1,] 37.49974 -122.4990
## [2,] 37.50142 -122.4980
## [3,] 37.50293 -122.4992
## [4,] 37.50275 -122.5016
## [5,] 37.50107 -122.5026
## [6,] 37.49956 -122.5014
Usually functions are vectorized:
(coords <- road_safety_greater_manchester[1:2, ])
## lat lng
## 1 53.62111 -2.461070
## 2 53.61887 -2.458324
(h3_indexes <- geo_to_h3(coords, 8))
## [1] "88195186b3fffff" "88195186b3fffff"
h3_to_geo_boundary(h3_indexes)
## [[1]]
## lat lng
## [1,] 53.62557 -2.460912
## [2,] 53.62432 -2.467959
## [3,] 53.61988 -2.469062
## [4,] 53.61670 -2.463119
## [5,] 53.61796 -2.456073
## [6,] 53.62239 -2.454970
##
## [[2]]
## lat lng
## [1,] 53.62557 -2.460912
## [2,] 53.62432 -2.467959
## [3,] 53.61988 -2.469062
## [4,] 53.61670 -2.463119
## [5,] 53.61796 -2.456073
## [6,] 53.62239 -2.454970
If sf is installed, you can get the polygons of H3 indexes like this:
h3_to_geo_boundary_sf(h3_indexes)
## Simple feature collection with 2 features and 0 fields
## geometry type: POLYGON
## dimension: XY
## bbox: xmin: -2.469062 ymin: 53.6167 xmax: -2.45497 ymax: 53.62557
## CRS: EPSG:4326
## geometry
## 1 POLYGON ((-2.460912 53.6255...
## 2 POLYGON ((-2.460912 53.6255...
# Get the children of an H3 index at the given (finer) resolution
(res <- h3_get_resolution(h3_index) + 1)
## [1] 10
h3_to_children(h3_index, res)
## [1] "8a28342e20c7fff" "8a28342e20cffff" "8a28342e20d7fff" "8a28342e20dffff"
## [5] "8a28342e20e7fff" "8a28342e20effff" "8a28342e20f7fff"
# Get the parent of an H3 index at the given (coarser) resolution
(res <- h3_get_resolution(h3_index) - 1)
## [1] 8
h3_to_parent(h3_index, res)
## [1] "8828342e21fffff"
# Find all H3 indexes within a given distance from the origin (filled ring)
radius <- 1
k_ring(h3_index, radius)
## [1] "8928342e20fffff" "8928342e20bffff" "8928342e273ffff" "8928342e277ffff"
## [5] "8928342e23bffff" "8928342e207ffff" "8928342e203ffff"
k_ring_distances(h3_index, radius = 2)
## # A tibble: 19 x 2
## h3_index distance
## <chr> <dbl>
## 1 8928342e20fffff 0
## 2 8928342e20bffff 1
## 3 8928342e273ffff 1
## 4 8928342e277ffff 1
## 5 8928342e23bffff 1
## 6 8928342e207ffff 1
## 7 8928342e203ffff 1
## 8 8928342e21bffff 2
## 9 8928342e257ffff 2
## 10 8928342e247ffff 2
## 11 8928342e27bffff 2
## 12 8928342e263ffff 2
## 13 8928342e267ffff 2
## 14 8928342e22bffff 2
## 15 8928342e223ffff 2
## 16 8928342e233ffff 2
## 17 8928342e2abffff 2
## 18 8928342e217ffff 2
## 19 8928342e213ffff 2
# Get the distance in grid cells between two H3 indexes
h3_distance("8928342e20fffff", "8928342e21bffff")
## [1] 2
# Get the multipolygon (array of polygons) for a set of H3 indexes
h3_indexes <- c("85291a6ffffffff", "85291a6bfffffff", "852834d3fffffff")
h3_set_to_multi_polygon(h3_indexes) %>%
sf::st_geometry() %>% plot(col = "blue")
# Binning
h3_index <- geo_to_h3(road_safety_greater_manchester)
tbl <- table(h3_index) %>%
tibble::as_tibble()
hexagons <- h3_to_geo_boundary_sf(tbl$h3_index) %>%
dplyr::mutate(index = tbl$h3_index, accidents = tbl$n)
head(hexagons)
## Simple feature collection with 6 features and 2 fields
## geometry type: POLYGON
## dimension: XY
## bbox: xmin: -2.144701 ymin: 53.60199 xmax: -2.027979 ymax: 53.67943
## CRS: EPSG:4326
## geometry index accidents
## 1 POLYGON ((-2.083848 53.6794... 871942403ffffff 4
## 2 POLYGON ((-2.072919 53.6433... 87194240affffff 1
## 3 POLYGON ((-2.05044 53.62609... 87194240bffffff 1
## 4 POLYGON ((-2.061349 53.6622... 87194240effffff 1
## 5 POLYGON ((-2.129491 53.6587... 871942418ffffff 3
## 6 POLYGON ((-2.106978 53.6415... 871942419ffffff 3
# Rendering
library(leaflet)
pal <- colorBin("YlOrRd", domain = hexagons$accidents)
map <- leaflet(data = hexagons, width = "100%") %>%
addProviderTiles("Stamen.Toner") %>%
addPolygons(
weight = 2,
color = "white",
fillColor = ~ pal(accidents),
fillOpacity = 0.8,
label = ~ sprintf("%i accidents (%s)", accidents, index)
)
map