Geo::H3::FFI - Perl FFI binding to H3 v3.x library functions
use Geo::H3::FFI;
This package is a backend FFI binding package for Uber’s H3 Hexagonal Hierarchical Spatial Index version 3.x. The user interface is Geo::H3.
This package is compatible with 3.7.2 version of the H3 library. The H3 v3.x library has undergone a re-write that is not backwards compatible. Other than naming conventions, there is no significant functional difference between v3.x and v4.x libraries. The main issue with naming was that the term "hex" in v3.x meant both cells with 5 or 6 points. Whereas in v4.x, "hexagon" means 6 points, "pentagon" means 5 points, and "cell" means 5 or 6 points.
In the future, I hope to add support for the H3 v4.x library in a Geo::H3::FFI:V4 package and update the Geo::H3 package to seamlessly work with either backend as well as possibly an XS backend.
my $gh3 = Geo::H3::FFI->new;
Returns a GeoCoord struct
my $geo = $gh3->geo; #empty struct #isa Geo::H3::FFI::Struct::GeoCoord
my $geo = $gh3->geo(lat=>$lat_rad, lon=>$lon_rad); #isa Geo::H3::FFI::Struct::GeoCoord
Returns a GeoBoundary struct
my $gb = $gh3->gb; #empty struct #isa Geo::H3::FFI::Struct::GeoBoundary
These function are used for finding the H3 index containing coordinates, and for finding the center and boundary of H3 indexes.
Indexes the location at the specified resolution, returning the index of the cell containing the location.
my $geo = $gh3->geo(lat=>$lat_rad, lon=>$lon_rad); #isa Geo::H3::FFI::Struct::GeoCoord
my $resolution = 8; #isa Int in (0 .. 15)
my $index = $gh3->geoToH3($geo, $resolution); #isa Int64
Returns 0 on error.
my $index = $gh3->geoToH3Wrapper(lat=>$lat_rad, lon=>$lon_rad, resolution=>$resolution);
my $index = $gh3->geoToH3Wrapper(lat=>$lat, lon=>$lon, resolution=>$resolution, uom=>"deg");
Finds the centroid of the index.
my $geo = $gh3->geo; #isa Geo::H3::FFI::Struct::GeoCoord
$gh3->h3ToGeo($index, $geo);
my $lat = $geo->lat; #isa Float in radians
my $lon = $geo->lon; #isa Float in radians
my $geo = h3ToGeoWrapper($index); #isa Geo::H3::FFI::Struct::GeoCoord
my $lat = $geo->lat; #isa Float in radians
my $lon = $geo->lon; #isa Float in radians
Finds the boundary of the index.
my $gb = $gh3->gb; #isa empty Geo::H3::FFI::Struct::GeoBoundary
$gh3->h3ToGeoBoundary($index, $gb); #populates $gb
my $num_verts = $gb->num_verts; #isa Int
my $vert0 = $gb->verts->[0]; #isa Geo::H3::FFI::Struct::GeoCord
my $GeoBoundary = $gh3->h3ToGeoBoundaryWrapper($index); #isa Geo::H3::FFI::Struct::GeoBoundary
These functions provide metadata about an H3 index, such as its resolution or base cell, and provide utilities for converting into and out of the 64-bit representation of an H3 index.
Returns the resolution of the index.
my $resolution = $gh3->h3GetResolution($index); #isa Int
Returns the base cell number of the index.
my $baseCell = h3GetBaseCell($index);
Converts the string representation to H3Index (uint64_t) representation.
Returns 0 on error.
my $index = $gh3->stringToH3($string, length($string));
my $index = $gh3->stringToH3Wrapper($string);
Converts the H3Index representation of the index to the string representation. str must be at least of length 17.
my $size = 17; #Must be 17 for API to work
my $string = "\000" x $size;
$gh3->h3ToString($index, $string, $size);
$string =~ s/\000+\Z//;
my $string = $gh3->h3ToStringWrapper($index);
Returns non-zero if this is a valid H3 index.
my isValid = $gh3->h3IsValid($index);
Returns non-zero if this index has a resolution with Class III orientation.
my $isRC3 = $gh3->h3IsResClassIII($index);
Returns non-zero if this index represents a pentagonal cell.
my $isPentagon = $gh3->h3IsPentagon($index);
Find all icosahedron faces intersected by a given H3 index and places them in the array out. out must be at least of length maxFaceCount(h).
Faces are represented as integers from 0-19, inclusive. The array is sparse, and empty (no intersection) array values are represented by -1.
my @array = (-1,-1,-1,-1,-1);
$gh3->h3GetFaces($index, \@array); #sets values into initialized array
my $array_ref = $gh3->h3GetFacesWrapper($index);
Returns the maximum number of icosahedron faces the given H3 index may intersect.
my $count = $gh3->maxFaceCount($index);
Grid traversal allows finding cells in the vicinity of an origin cell, and determining how to traverse the grid from one cell to another.
k-rings produces indices within k distance of the origin index.
k-ring 0 is defined as the origin index, k-ring 1 is defined as k-ring 0 and all neighboring indices, and so on.
Output is placed in the provided array in no particular order. Elements of the output array may be left zero, as can happen when crossing a pentagon.
my $size = $gh3->maxKringSize($k);
my @array = (-1) x $size;
$self->kRing($index, $k, \@array);
Returns an array reference of H3 indices with the k distance of the origin index.
my $aref = $gh3->kRingWrapper($index, $k); #ias ARRAY of H3 Indexes
Maximum number of indices that result from the kRing algorithm with the given k.
my $size = $gh3->maxKringSize($k);
k-rings produces indices within k distance of the origin index.
k-ring 0 is defined as the origin index, k-ring 1 is defined as k-ring 0 and all neighboring indices, and so on.
Output is placed in the provided array in no particular order. Elements of the output array may be left zero, as can happen when crossing a pentagon.
my $size = $gh3->maxKringSize($k);
my @array = (-1) x $size;
my @dist = (-1) x $size;
my %hash = ();
$gh3->kRingDistances($index, $k, \@array, \@dist);
Returns a hash reference where the keys are the H3 index and values are the k distance for the given index and k value.
my $href = $gh3->kRingDistancesWrapper($index, $k); #isa HASH
hexRange produces indexes within k distance of the origin index. Output behavior is undefined when one of the indexes returned by this function is a pentagon or is in the pentagon distortion area.
k-ring 0 is defined as the origin index, k-ring 1 is defined as k-ring 0 and all neighboring indexes, and so on.
Output is placed in the provided array in order of increasing distance from the origin.
Returns 0 if no pentagonal distortion is encountered.
my $distortion = $gh3->hexRange($index, $k, \@out);
my @indexes = $gh3->hexRangeWrapper($index, $k);
my $size = $gh3->maxHexRangeSize($k);
hexRange produces indexes within k distance of the origin index. Output behavior is undefined when one of the indexes returned by this function is a pentagon or is in the pentagon distortion area.
k-ring 0 is defined as the origin index, k-ring 1 is defined as k-ring 0 and all neighboring indexes, and so on.
Output is placed in the provided array in order of increasing distance from the origin. The distances in hexagons is placed in the distances array at the same offset.
Returns 0 if no pentagonal distortion is encountered.
my $distortion = $gh3->hexRangeDistances($index, $k, \@indexes, \@distances);
my $href = $gh3->hexRangeDistancesWrapper($index, $k);
hexRanges takes an array of input hex IDs and a max k-ring and returns an array of hexagon IDs sorted first by the original hex IDs and then by the k-ring (0 to max), with no guaranteed sorting within each k-ring group.
Returns 0 if no pentagonal distortion was encountered. Otherwise, output is undefined
Produces the hollow hexagonal ring centered at origin with sides of length k.
Returns 0 if no pentagonal distortion was encountered.
my $distortion = $gh3->hexRing($index, $k, \@ring);
my $aref = $gh3->hexRingWrapper($index, $k);
my $size = $gh3->maxHexRingSize($k);
Given two H3 indexes, return the line of indexes between them (inclusive).
This function may fail to find the line between two indexes, for example if they are very far apart. It may also fail when finding distances for indexes on opposite sides of a pentagon.
Notes:
- The specific output of this function should not be considered stable across library versions. The only guarantees the library provides are that the line length will be h3Distance(start, end) + 1 and that every index in the line will be a neighbor of the preceding index.
- Lines are drawn in grid space, and may not correspond exactly to either Cartesian lines or great arcs.
my $aref = $gh3->h3LineWrapper($start, $end);
Number of indexes in a line from the start index to the end index, to be used for allocating memory. Returns a negative number if the line cannot be computed.
Returns the distance in grid cells between the two indexes.
Returns a negative number if finding the distance failed. Finding the distance can fail because the two indexes are not comparable (different resolutions), too far apart, or are separated by pentagonal distortion. This is the same set of limitations as the local IJ coordinate space functions.
Produces local IJ coordinates for an H3 index anchored by an origin.
This function is experimental, and its output is not guaranteed to be compatible across different versions of H3.
Produces an H3 index from local IJ coordinates anchored by an origin.
This function is experimental, and its output is not guaranteed to be compatible across different versions of H3.
These functions permit moving between resolutions in the H3 grid system. The functions produce parent (coarser) or children (finer) cells.
Returns the parent (coarser) index containing h.
my $parent = $gh3->h3ToParent($index, $resolution);
Populates children with the indexes contained by h at resolution childRes. children must be an array of at least size maxH3ToChildrenSize(h, childRes).
my $size = $gh3->maxH3ToChildrenSize($index, $res);
my @array = (-1) x $size;
$gh3->h3ToChildren($index, $res, \@array);
my $aref = $gh3->h3ToChildrenWrapper($index, $resoultion);
my $size = $gh3->maxH3ToChildrenSize($index, $res);
Returns the center child (finer) index contained by h at resolution childRes.
Compacts the set h3Set of indexes as best as possible, into the array compactedSet. compactedSet must be at least the size of h3Set in case the set cannot be compacted.
Returns 0 on success.
my $aref = $gh3->compactWrapper(\@indexes);
Uncompacts the set compactedSet of indexes to the resolution res. h3Set must be at least of size maxUncompactSize(compactedSet, numHexes, res).
Returns 0 on success.
my $aref = $gh3->uncompactWrapper(\@indexes, $resolution);
Returns the size of the array needed by uncompact.
These functions convert H3 indexes to and from polygonal areas.
polyfill takes a given GeoJSON-like data structure and preallocated, zeroed memory, and fills it with the hexagons that are contained by the GeoJSON-like data structure.
Containment is determined by the cells' centroids. A partioning using the GeoJSON-like data structure, where polygons cover an area without overlap, will result in a partitioning in the H3 grid, where cells cover the same area without overlap.
maxPolyfillSize returns the number of hexagons to allocate space for when performing a polyfill on the given GeoJSON-like data structure.
Create a LinkedGeoPolygon describing the outline(s) of a set of hexagons. Polygon outlines will follow GeoJSON MultiPolygon order: Each polygon will have one outer loop, which is first in the list, followed by any holes.
It is the responsibility of the caller to call destroyLinkedPolygon on the populated linked geo structure, or the memory for that structure will not be freed.
It is expected that all hexagons in the set have the same resolution and that the set contains no duplicates. Behavior is undefined if duplicates or multiple resolutions are present, and the algorithm may produce unexpected or invalid output.
Free all allocated memory for a linked geo structure. The caller is responsible for freeing memory allocated to the input polygon struct.
Unidirectional edges allow encoding the directed edge from one cell to a neighboring cell.
Returns whether or not the provided H3Indexes are neighbors.
Returns 1 if the indexes are neighbors, 0 otherwise.
Returns a unidirectional edge H3 index based on the provided origin and destination.
Returns 0 on error.
Determines if the provided H3Index is a valid unidirectional edge index.
Returns 1 if it is a unidirectional edge H3Index, otherwise 0.
Returns the origin hexagon from the unidirectional edge H3Index.
Returns the destination hexagon from the unidirectional edge H3Index.
Returns the origin, destination pair of hexagon IDs for the given edge ID, which are placed at originDestination[0] and originDestination[1] respectively.
Provides all of the unidirectional edges from the current H3Index. edges must be of length 6, and the number of undirectional edges placed in the array may be less than 6.
Provides the coordinates defining the unidirectional edge.
These functions include descriptions of the H3 grid system.
Converts degrees to radians.
Converts radians to degrees.
Average hexagon area in square kilometers at the given resolution.
Average hexagon area in square meters at the given resolution.
Exact area of specific cell in square meters.
Exact area of specific cell in square radians.
Average hexagon edge length in kilometers at the given resolution.
Average hexagon edge length in meters at the given resolution.
Exact edge length of specific unidirectional edge in kilometers.
Exact edge length of specific unidirectional edge in meters.
Exact edge length of specific unidirectional edge in radians.
Number of unique H3 indexes at the given resolution.
All the resolution 0 H3 indexes. out must be an array of at least size res0IndexCount().
Number of resolution 0 H3 indexes.
All the pentagon H3 indexes at the specified resolution. out must be an array of at least size pentagonIndexCount().
Number of pentagon H3 indexes per resolution. This is always 12, but provided as a convenience.
Gives the "great circle" or "haversine" distance between pairs of GeoCoord points (lat/lon pairs) in kilometers.
Gives the "great circle" or "haversine" distance between pairs of GeoCoord points (lat/lon pairs) in meters.
Gives the "great circle" or "haversine" distance between pairs of GeoCoord points (lat/lon pairs) in radians.
https://h3geo.org/docs/api/indexing, https://h3geo.org/docs/community/bindings, FFI::CheckLib, FFI::Platypus, FFI::C
Michael R. Davis
MIT License
Copyright (c) 2020 Michael R. Davis