An R interface to Rust's h3o library

Related tags

Security tools h3o
Overview

h3o

h3o is a system-dependency free package to interact with the H3 Geospatial Indexing system by Uber. h3o utilizes the Rust library h3o with is a pure rust implementation of H3 and does not link or use Uber’s H3 C library. h3o R interface is powered by extendr and should be able to compile on any machine.

Installation

You can install the development version of h3o from GitHub with:

# install.packages("remotes")
remotes::install_github("JosiahParry/h3o")

Example

To illustrate the basic usage, we can first create an sf object of random points.

pnts <- tibble::tibble(
  x = runif(100, -5, 10),
  y = runif(100, 40, 50)
) |> 
  sf::st_as_sf(
    coords = c("x", "y"), 
    crs = 4326
  )

h3o utilizes vctrs to create H3 class vectors so that they can work seemlessly within a tidyverse workflow.

h3o is intended to work with the sf package for geometric operations. H3 vectors can be created from POINT geometry columns (sfc objects).

library(h3o)

pnts |> 
  dplyr::mutate(h3 = h3_from_points(geometry, 5))
#> Simple feature collection with 100 features and 1 field
#> Geometry type: POINT
#> Dimension:     XY
#> Bounding box:  xmin: -4.640664 ymin: 40.12973 xmax: 9.89838 ymax: 49.99956
#> Geodetic CRS:  WGS 84
#> # A tibble: 100 × 2
#>                  geometry              h3
#>  *            <POINT [°]>            <H3>
#>  1  (-0.1748193 48.79705) 8518656bfffffff
#>  2   (0.8532506 46.80069) 85186893fffffff
#>  3     (6.62694 42.85004) 85396bb7fffffff
#>  4 (-0.03733749 48.06814) 8518610ffffffff
#>  5    (0.464929 45.62997) 85186b97fffffff
#>  6    (6.293697 42.92604) 8539694bfffffff
#>  7  (-0.6392504 42.96113) 85397593fffffff
#>  8    (2.020749 45.14571) 85396597fffffff
#>  9     (6.787495 41.8565) 85394d8bfffffff
#> 10   (-2.065804 49.31534) 85186293fffffff
#> # … with 90 more rows

Additionally, H3 vectors also have an st_as_sfc() method which lets us convert vectors of H3 cell indexes into POLYGONs.

h3_cells <- pnts |> 
  dplyr::mutate(
    h3 = h3_from_points(geometry, 4),
    # replace geometry
    geometry = sf::st_as_sfc(h3)
    )

# plot the hexagons
plot(sf::st_geometry(h3_cells))

H3 cell centroids can be returned using h3_to_points(). If sf is avilable the results will be returned as an sfc (sf column) object. Otherwise it will return a list of sfg (sf geometries).

# fetch h3 column
h3s <- h3_cells$h3

# get there centers
h3_centers <- h3_to_points(h3s) 

# plot the hexagons with the centers
plot(sf::st_geometry(h3_cells))
plot(h3_centers, pch = 16, add = TRUE, col = "black")

sf compatibility

h3o was designed with sf in mind. H3 is a geospatial indexing system so it is important to be able to go back and from from H3 and sf objects. H3 object can be created from sfc objects and vice versa.sfc objects can also be created using the sf::sf_as_sfc() method for H3 or H3Edge vectors.

H3Edge vectors represent the boundaries of H3 cells. They can be created with h3_edges(), h3_shared_edge_pairwise(), and h3_shared_edge_sparse().

cell_edges <- h3_edges(h3s[1:3])
cell_edges
#> [[1]]
#> <H3Edge[6]>
#> [1] 11418657ffffffff 12418657ffffffff 13418657ffffffff 14418657ffffffff
#> [5] 15418657ffffffff 16418657ffffffff
#> 
#> [[2]]
#> <H3Edge[6]>
#> [1] 114186c3ffffffff 124186c3ffffffff 134186c3ffffffff 144186c3ffffffff
#> [5] 154186c3ffffffff 164186c3ffffffff
#> 
#> [[3]]
#> <H3Edge[6]>
#> [1] 114396bbffffffff 124396bbffffffff 134396bbffffffff 144396bbffffffff
#> [5] 154396bbffffffff 164396bbffffffff

We’ve created a list of each cell’s edges. We can flatten them using flatten_edges().

cell_edges <- flatten_edges(cell_edges)
cell_edges
#> <H3Edge[18]>
#>  [1] 11418657ffffffff 12418657ffffffff 13418657ffffffff 14418657ffffffff
#>  [5] 15418657ffffffff 16418657ffffffff 114186c3ffffffff 124186c3ffffffff
#>  [9] 134186c3ffffffff 144186c3ffffffff 154186c3ffffffff 164186c3ffffffff
#> [13] 114396bbffffffff 124396bbffffffff 134396bbffffffff 144396bbffffffff
#> [17] 154396bbffffffff 164396bbffffffff

These can be cast to sfc objects using its st_as_sfc() method.

sf::st_as_sfc(cell_edges)
#> Geometry set for 18 features 
#> Geometry type: LINESTRING
#> Dimension:     XY
#> Bounding box:  xmin: -0.1887568 ymin: 42.46421 xmax: 6.894879 ymax: 49.06668
#> Geodetic CRS:  WGS 84
#> First 5 geometries:
#> LINESTRING (0.06718183 48.61807, 0.3797637 48.6...
#> LINESTRING (-0.1314807 49.00394, -0.1887568 48....
#> LINESTRING (-0.1887568 48.77929, 0.06718183 48....
#> LINESTRING (0.438739 48.9049, 0.1834448 49.06668)
#> LINESTRING (0.3797637 48.68094, 0.438739 48.9049)

Additionally, you can get the vertexes of H3 cell indexes using h3_to_vertexes() which returns an sfc_MULTIPOINT.

h3_to_vertexes(h3s)
#> Geometry set for 100 features 
#> Geometry type: MULTIPOINT
#> Dimension:     XY
#> Bounding box:  xmin: -5.026879 ymin: 39.94716 xmax: 10.23339 ymax: 50.28041
#> Geodetic CRS:  WGS 84
#> First 5 geometries:
#> MULTIPOINT ((0.1834448 49.06668), (-0.1314807 4...
#> MULTIPOINT ((1.137485 47.13162), (0.8340071 47....
#> MULTIPOINT ((6.354821 42.84855), (6.282053 42.6...
#> MULTIPOINT ((0.009641755 48.393), (-0.3021414 4...
#> MULTIPOINT ((0.2465874 45.86362), (-0.05258159 ...

Bench marks:

Since h3o is written in Rust, it is very fast.

Creating polygons

h3_strs <- as.character(h3s)
bench::mark(
  h3o = sf::st_as_sfc(h3s),
  h3jsr = h3jsr::cell_to_polygon(h3_strs)
)
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 h3o        305.98µs 327.59µs     2997.   26.84KB     8.23
#> 2 h3jsr        7.51ms   7.81ms      124.    3.02MB    24.8

Converting points to cells

bench::mark(
  h3o = h3_from_points(pnts$geometry, 3),
  h3jsr = h3jsr::point_to_cell(pnts$geometry, 3),
  check = FALSE
)
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 h3o        108.49µs 124.93µs     6254.      848B     11.5
#> 2 h3jsr        2.03ms   2.17ms      424.     856KB     13.0

Retrieve edges

bench::mark(
  h3o = h3_edges(h3s),
  h3jsr = h3jsr::get_udedges(h3_strs),
  check = FALSE
)
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 h3o         596.6µs 641.12µs     1103.      848B     12.1
#> 2 h3jsr         1.8ms   2.04ms      456.    82.8KB     13.0

Get origins and destinations from edges.

# get edges for a single location
eds <- h3_edges(h3s[1])[[1]]
# strings for h3jsr
eds_str <- as.character(eds)

bench::mark(
  h3o = h3_edge_cells(eds),
  h3jsr = h3jsr::get_udends(eds_str),
  check = FALSE
)
#> # A tibble: 2 × 6
#>   expression      min   median `itr/sec` mem_alloc `gc/sec`
#>   <bch:expr> <bch:tm> <bch:tm>     <dbl> <bch:byt>    <dbl>
#> 1 h3o          20.1µs   25.4µs    33736.    12.7KB     13.5
#> 2 h3jsr         464µs  628.7µs     1461.    34.8KB     18.6
You might also like...
Memory hacking library for windows.

Memory hacking library for windows.

An attempt to rewrite lite-client for TON Blockchain in Rust using ton-labs-adnl library.

An attempt to rewrite lite-client for TON Blockchain in Rust using ton-labs-adnl library.

A new shellcode injection technique. Given as C++ header, standalone Rust program or library.
A new shellcode injection technique. Given as C++ header, standalone Rust program or library.

FunctionStomping Description This is a brand-new technique for shellcode injection to evade AVs and EDRs. This technique is inspired by Module Stompin

Extended precision integer Rust library. Provides signed/unsigned integer 256 to 2048.

Extended precision integer Rust library. Provides signed/unsigned integer 256 to 2048.

Linux anti-debugging and anti-analysis rust library
Linux anti-debugging and anti-analysis rust library

DebugOff Library Linux anti-analysis Rust library The goal of this library is to make both static and dynamic (debugging) analysis more difficult. The

A library for building tools to determine if vulnerabilities are reachable in a code base.
A library for building tools to determine if vulnerabilities are reachable in a code base.

Overview Vuln Reach is a library for developing tools that determine if a given vulnerability is reachable. Provided to the open source community by P

A rust library for sharing and updating arbitrary slices between threads, optimized for wait-free reads

atomicslice A Rust library for thread-safe shared slices that are just about as fast as possible to read while also being writable. Overview Use Atomi

A CLI app that exposes most of the h3o API for scripting.

h3o-cli — A CLI app exposing the h3o API for scripting How to install Pre-compiled binaries You can download a pre-compiled executable for Linux, MacO

Rust library to interface with Lua

hlua This library is a high-level binding for Lua 5.2. You don't have access to the Lua stack, all you can do is read/write variables (including callb

Low-level Rust library for implementing terminal command line interface, like in embedded systems.

Terminal CLI Need to build an interactive command prompt, with commands, properties and with full autocomplete? This is for you. Example, output only

A Text User Interface library for the Rust programming language
A Text User Interface library for the Rust programming language

Cursive Cursive is a TUI (Text User Interface) library for rust. It uses ncurses by default, but other backends are available. It allows you to build

A Text User Interface library for the Rust programming language
A Text User Interface library for the Rust programming language

Cursive Cursive is a TUI (Text User Interface) library for rust. It uses ncurses by default, but other backends are available. It allows you to build

A cross-platform serial port library in Rust. Provides a blocking I/O interface and port enumeration including USB device information.

Note: This is a fork of the original serialport-rs project on GitLab. Please note there have been some changes to both the supported targets and which

A Rust library for interacting with OpenAI's ChatGPT API, providing an easy-to-use interface and strongly typed structures.

ChatGPT Rust Library A Rust library for interacting with OpenAI's ChatGPT API. This library simplifies the process of making requests to the ChatGPT A

A user-friendly database interface
A user-friendly database interface

Diwata Diwata is a database interface for PostgreSQL,Mysql, Sqlite with the goal of being usable, user-friendly with its basic and advanced functional

Cardano Command Line Interface (CLI) (Deprecated)

Deprecated Note: This repository implements supports for Cardano Byron, and will not be updated to works on Cardano Shelley and further. cardano-cli T

Command line interface to manage clipboard

cb Command line interface to manage clipboard How to install Pre-Compiled you can download a pre-compiled executable, then you should copy that execut

A cross platform minimalistic text user interface
A cross platform minimalistic text user interface

titik Titik is a crossplatform TUI widget library with the goal of being able to interact intuitively on these widgets. It uses crossterm as the under

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies

Dear ImGui (This library is available under a free and permissive license, but needs financial support to sustain its continued improvements. In addit

Comments
  • Error: protect(): protection stack overflow

    Error: protect(): protection stack overflow

    Hello, I've been following a bit your repos that use extendr since I'm trying to learn it. I ran some of your examples with more points to see if the performance gains scale well and I came across this error in h3_from_points():

    library(h3o)
    
    # works fine with 10,000 points
    pnts <- tibble::tibble(
      x = runif(10000, -5, 10),
      y = runif(10000, 40, 50)
    ) |> 
      sf::st_as_sf(
        coords = c("x", "y"), 
        crs = 4326
      )
    
    foo <- h3_from_points(pnts$geometry, 4)
    
    # error with 100,000 points
    pnts <- tibble::tibble(
      x = runif(100000, -5, 10),
      y = runif(100000, 40, 50)
    ) |> 
      sf::st_as_sf(
        coords = c("x", "y"), 
        crs = 4326
      )
    
    foo <- h3_from_points(pnts$geometry, 4)
    #> Error: protect(): protection stack overflow
    

    I know it's still early in development and I'm not using these geospatial features anyway, but I just thought you'd want to know.

    Session info if needed
    ─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
     setting  value
     version  R version 4.2.2 (2022-10-31 ucrt)
     os       Windows 10 x64 (build 19044)
     system   x86_64, mingw32
     ui       RStudio
     language (EN)
     collate  English_Europe.utf8
     ctype    English_Europe.utf8
     tz       Europe/Paris
     date     2023-03-13
     rstudio  2022.12.0+353 Elsbeth Geranium (desktop)
     pandoc   3.1 @ C:/Users/etienne/AppData/Local/Pandoc/ (via rmarkdown)
    

    ─ Packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── package * version date (UTC) lib source bench 1.1.2 2021-11-30 [1] CRAN (R 4.2.0) callr 3.7.3 2022-11-02 [1] CRAN (R 4.2.2) class 7.3-21 2023-01-23 [1] CRAN (R 4.2.2) classInt 0.4-9 2023-02-28 [1] CRAN (R 4.2.2) cli 3.6.0 2023-01-09 [1] CRAN (R 4.2.2) clipr 0.8.0 2022-02-22 [1] CRAN (R 4.2.0) curl 5.0.0 2023-01-12 [1] CRAN (R 4.2.2) DBI 1.1.3 2022-06-18 [1] CRAN (R 4.2.1) digest 0.6.31 2022-12-11 [1] CRAN (R 4.2.2) dplyr 1.1.0 2023-01-29 [1] CRAN (R 4.2.2) e1071 1.7-13 2023-02-01 [1] CRAN (R 4.2.2) evaluate 0.20 2023-01-17 [1] CRAN (R 4.2.2) fansi 1.0.4 2023-01-22 [1] CRAN (R 4.2.2) fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.2.2) fs 1.6.0 2023-01-23 [1] CRAN (R 4.2.2) generics 0.1.3 2022-07-05 [1] CRAN (R 4.2.1) geojsonsf 2.0.3 2022-05-30 [1] CRAN (R 4.2.1) glue 1.6.2 2022-02-24 [1] CRAN (R 4.2.0) h3jsr 1.3.1 2023-01-21 [1] CRAN (R 4.2.2) h3o * 0.1.0 2023-03-13 [1] Github (JosiahParry/h3o@e50144c) htmltools 0.5.4 2022-12-07 [1] CRAN (R 4.2.2) jsonlite 1.8.4 2022-12-06 [1] CRAN (R 4.2.2) KernSmooth 2.23-20 2021-05-03 [2] CRAN (R 4.2.2) knitr 1.42 2023-01-25 [1] CRAN (R 4.2.2) lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.2.1) magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.2.0) pillar 1.8.1 2022-08-19 [1] CRAN (R 4.2.1) pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.2.0) processx 3.8.0 2022-10-26 [1] CRAN (R 4.2.2) profmem 0.6.0 2020-12-13 [1] CRAN (R 4.2.0) proxy 0.4-27 2022-06-09 [1] CRAN (R 4.2.0) ps 1.7.2 2022-10-26 [1] CRAN (R 4.2.2) purrr 1.0.1 2023-01-10 [1] CRAN (R 4.2.2) R.cache 0.16.0 2022-07-21 [1] CRAN (R 4.2.1) R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.2.0) R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.2.0) R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.2.1) R6 2.5.1 2021-08-19 [1] CRAN (R 4.2.0) rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.2.0) Rcpp 1.0.10 2023-01-22 [1] CRAN (R 4.2.2) reprex 2.0.2 2022-08-17 [1] CRAN (R 4.2.1) rlang 1.0.6.9000 2023-02-20 [1] Github (r-lib/rlang@394204f) rmarkdown 2.20 2023-01-19 [1] CRAN (R 4.2.2) roxygen2 7.2.3.9000 2023-01-04 [1] Github (r-lib/roxygen2@39d2dbe) rstudioapi 0.14 2022-08-22 [1] CRAN (R 4.2.1) sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.2.0) sf 1.0-9 2022-11-08 [1] CRAN (R 4.2.2) shrtcts 0.1.2 2022-04-29 [1] Github (gadenbuie/shrtcts@12ef67f) stringi 1.7.12 2023-01-11 [1] CRAN (R 4.2.2) stringr 1.5.0 2022-12-02 [1] CRAN (R 4.2.2) styler 1.9.1 2023-03-04 [1] CRAN (R 4.2.2) tibble 3.1.8 2022-07-22 [1] CRAN (R 4.2.1) tidyr 1.3.0 2023-01-24 [1] CRAN (R 4.2.2) tidyselect 1.2.0 2022-10-10 [1] CRAN (R 4.2.1) units 0.8-1 2022-12-10 [1] CRAN (R 4.2.2) utf8 1.2.3 2023-01-31 [1] CRAN (R 4.2.2) V8 4.2.2 2022-11-03 [1] CRAN (R 4.2.2) vctrs 0.5.2.9000 2023-02-20 [1] Github (r-lib/vctrs@303b5dd) withr 2.5.0 2022-03-03 [1] CRAN (R 4.2.0) xfun 0.37 2023-01-31 [1] CRAN (R 4.2.2) xml2 1.3.3 2021-11-30 [1] CRAN (R 4.2.0) yaml 2.3.7 2023-01-23 [1] CRAN (R 4.2.2) [1] C:/Users/etienne/AppData/Local/R/win-library/4.2 [2] C:/R/library

    opened by etiennebacher 4
Owner
Josiah Parry
Social Scientist. Spatial Stats @ Esri
Josiah Parry
CVEs for the Rust standard library

Rust CVE Preface This is a list of CVEs for unsound APIs in the Rust standard library. These bugs break Rust's memory safety guarantee and lead to sec

Yechan Bae 26 Dec 4, 2022
Rust library for building and running BPF/eBPF modules

RedBPF A Rust eBPF toolchain. Overview The redbpf project is a collection of tools and libraries to build eBPF programs using Rust. It includes: redbp

foniod 1.5k Jan 1, 2023
unfuck is a utility and library for deobfuscating obfuscated Python 2.7 bytecode

unfuck is a utility and library for deobfuscating obfuscated Python 2.7 bytecode. It is essentially a reimplementation of the Python VM with taint tracking.

Lander Brandt 171 Dec 14, 2022
Rust library for developing safe canisters.

IC Kit This library provides an alternative to ic-cdk that can help developers write canisters and unit test them in their Rust code. Install Add this

Psychedelic 26 Nov 28, 2022
Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ...

LibAFL, the fuzzer library. Advanced Fuzzing Library - Slot your own fuzzers together and extend their features using Rust. LibAFL is written and main

Advanced Fuzzing League ++ 1.2k Jan 6, 2023
Xori is an automation-ready disassembly and static analysis library for PE32, 32+ and shellcode

Xori - Custom disassembly framework Xori is an automation-ready disassembly and static analysis library that consumes shellcode or PE binaries and pro

ENDGAME 712 Nov 28, 2022
QuickCheck bug hunting in Rust standard library data structures

BugHunt, Rust This project is aiming to provide "stateful" QuickCheck models for Rust's standard library. That is, we build up a random list of operat

Brian L. Troutwine 161 Dec 15, 2022
Mundane is a Rust cryptography library backed by BoringSSL that is difficult to misuse, ergonomic, and performant (in that order).

Mundane Mundane is a Rust cryptography library backed by BoringSSL that is difficult to misuse, ergonomic, and performant (in that order). Issues and

Google 1.1k Jan 3, 2023
Cross-platform async library for system information fetching 🦀

heim Cross-platform library for system information fetching heim is an ongoing attempt to create the best tool for system information fetching (ex., C

null 782 Jan 2, 2023
A simple rust library for working with ZIP archives

rust-zip A simple rust library to read and write Zip archives, which is also my pet project for learning Rust. At the moment you can list the files in

Jorge Gorbe Moya 11 Aug 6, 2022