npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

h3-node

v4.1.1

Published

H3 Bindings to node using N-API

Downloads

156

Readme

H3-Node

Unit Testing License

H3 Bindings to Node using N-API

Install

To install this package, you need several development tools available: git, gyp, make, cmake, and a C compiler (gcc or clang). Once those are available, simply

yarn add h3-node

-- or --

npm i h3-node

Versions

The 1.X.Y versions released before have varying stages of completeness of the API. From version 3.2.0 and on the major and minor versions will match the upstream C Implementation's major and minor versions, while the patch version will increment independently, including fixes for the bindings themselves as well as fixes from upstream.

Usage

h3-node is a drop-in replacement for H3-js. You can use the H3-js API reference for the available methods and the official H3 documentation to fully understand the purposes of the methods. Below is an abbreviated usage of every available method.

const h3 = require('h3-node')

const h3index = h3.latLngToCell(37.77, -122.43, 9)
const h3center = h3.cellToLatLng(h3index)
const h3outline = h3.cellToBoundary(h3index)
const h3area = h3.cellArea(h3index, h3.UNITS.m2)

const res = h3.getResolution(h3index)
const baseCell = h3.getBaseCellNumber(h3index)
const valid = h3.isValidCell(h3index)
const resIsClassIII = h3.isResClassIII(h3index)
const isPentagon = h3.isPentagon(h3index)
const faces = h3.getIcosahedronFaces(h3Index)
const neighbors = h3.gridDisk(h3index, 1)
const threeRings = h3.gridDiskDistances(h3index, 3)
const ring2Away = h3.gridRingUnsafe(h3index, 2)
const index2 = h3.latLngToCell(38.88, -122.34, 9)
const hexLine = h3.gridPathCells(h3index, index2)
const hexDistance = h3.gridDistance(h3index, index2)
const coords = h3.cellToLocalIj(h3index, index2)
const index2again = h3.localIjToCell(h3index, coords)
const parent = h3.cellToParent(h3index, 8)
const immediateChildren = h3.cellToChildren(h3index, 10)
const centerChild = h3.cellToCenterChild(h3index, 10)
const packedRings = h3.compactCells([].concat(...threeRings))
const unpackedRings = h3.uncompactCells(packedRings, 9)
const bayAreaHexes = h3.polygonToCells([
    [37.77, -122.43],
    [37.55, -122.43],
    [37.55, -122.23],
    [37.77, -122.23],
    [37.77, -122.43],
  ], 9)
const bayAreaHexGeo = h3.cellsToMultiPolygon(bayAreaHexes)
const areNeighbors = h3.areNeighborCells(neighbors[0], neighbors[1])
const edgeIndex = h3.cellsToDirectedEdge(neighbors[0], neighbors[1])
const isValidEdge = h3.isValidDirectedEdge(edgeIndex)
const edgeLenM = h3.edgeLength(edgeIndex, h3.UNITS.m)
const origin = h3.getDirectedEdgeOrigin(edgeIndex)
const destination = h3.getDirectedEdgeDestination(edgeIndex)
const [start, end] = h3.directedEdgeToCells(edgeIndex)
const edges = h3.originToDirectedEdges(h3index)
const edgeBoundaries = edges.map(h3.directedEdgeToBoundary)
const sfCoordsRads = [37.77, -122.43].map(h3.degsToRads)
const sfCoordsDegs = sfCoordsRads.map(h3.radsToDegs)
const resStats = Array.from(new Array(16), (x, res) => ({
  res,
  numHexagons: h3.numHexagons(res),
  edgeLength: {
    m: h3.getHexagonEdgeLengthAvg(res, h3.UNITS.m),
    km: h3.getHexagonEdgeLengthAvg(res, h3.UNITS.km),
  },
  hexArea: {
    m2: h3.getHexagonAreaAvg(res, h3.UNITS.m2),
    km2: h3.getHexagonAreaAvg(res, h3.UNITS.km2),
  },
  pentagons: h3.getPentagons(res),
}))
const res0Indexes = h3.getRes0Cells()

Why another H3 for Node?

h3-js is an emscripten transpilation of the H3 code into Javascript with a Javascript wrapper file similar to a binding in spirit to handle calling these quasi-C functions for you.

Being 100% javascript it works across the entire Javascript ecosystem (especially when paired with browserify or babel to handle the Node-isms for non-Node JS environments), but that portability comes at a cost in performance. Preliminary benchmarks show a significant speedup with the N-API approach:

damocles@elack:~/oss/h3-node(upgrade-to-v4)$ yarn test
yarn run v1.22.19
$ nodeunit test

index
✔ isValidCell_array
✔ isValidCell_uint32array
✔ cellToLatLng_array
✔ cellToLatLng_uint32array
✔ latLngToCell
✔ cellToLatLng
✔ cellToBoundary
✔ getResolution
✔ getBaseCellNumber
✔ isValidCell
✔ isResClassIII
✔ isPentagon
✔ getIcosahedronFaces
✔ gridDisk
✔ gridDiskDistances
undefined
undefined
✔ gridRingUnsafe
✔ gridDistance
✔ cellToLocalIj
undefined
undefined
✔ localIjToCell
✔ cellToParent
✔ cellToChildren
✔ cellToCenterChild
✔ compactCells
✔ uncompactCells
✔ polygonToCells
✔ polygonToCellsWithHoles
✔ cellsToMultiPolygon
✔ cellsToMultiPolygonGeoJsonMode
✔ cellsToMultiPolygonTrueMultiPolygon
✔ areNeighborCells
✔ cellsToDirectedEdge
✔ isValidDirectedEdge
✔ getDirectedEdgeOrigin
✔ getDirectedEdgeDestination
✔ directedEdgeToCells
✔ originToDirectedEdges
✔ directedEdgeToBoundary
✔ degsToRads
✔ radsToDegs
✔ getNumCells
✔ getHexagonEdgeLengthAvg
✔ edgeLength
✔ getHexagonAreaAvg
✔ cellArea
✔ greatCircleDistance
✔ getRes0Cells
✔ getPentagons

latLngToCell Benchmark:
H3-js time in ns:    8407061
H3-node time in ns:  1696666
✔ latLngToCellBenchmark

cellToLatLng Benchmark:
H3-js time in ns:    3957443
H3-node time in ns:  1500690
✔ cellToLatLngBenchmark

cellToBoundary Benchmark:
H3-js time in ns:    7288756
H3-node time in ns:  5075260
✔ cellToBoundaryBenchmark

getResolution Benchmark:
H3-js time in ns:    2497192
H3-node time in ns:  299202
✔ getResolutionBenchmark

getBaseCellNumber Benchmark:
H3-js time in ns:    341876
H3-node time in ns:  304160
✔ getBaseCellNumberBenchmark

isValidCell Benchmark:
H3-js time in ns:    259113
H3-node time in ns:  263024
✔ isValidCellBenchmark

isResClassIII Benchmark:
H3-js time in ns:    649109
H3-node time in ns:  470734
✔ isResClassIIIBenchmark

isPentagon Benchmark:
H3-js time in ns:    477089
H3-node time in ns:  310935
✔ isPentagonBenchmark

getIcosahedronFaces Benchmark:
H3-js time in ns:    4100479
H3-node time in ns:  1311698
✔ getIcosahedronFacesBenchmark

gridDisk Benchmark:
H3-js time in ns:    119649189
H3-node time in ns:  41318171
✔ gridDiskBenchmark

gridDiskDistances Benchmark:
H3-js time in ns:    104035995
H3-node time in ns:  53421119
✔ gridDiskDistancesBenchmark

gridRingUnsafe Benchmark:
H3-js time in ns:    13028001
H3-node time in ns:  9361658
✔ gridRingUnsafeBenchmark

gridDistance Benchmark:
H3-js time in ns:    6042499
H3-node time in ns:  1839702
✔ gridDistanceBenchmark

cellToLocalIj Benchmark:
H3-js time in ns:    3213419
H3-node time in ns:  2277539
✔ cellToLocalIjBenchmark

localIjToCell Benchmark:
H3-js time in ns:    10561051
H3-node time in ns:  1960318
✔ localIjToCellBenchmark

gridPathCells Benchmark:
H3-js time in ns:    66085174
H3-node time in ns:  48151768
✔ gridPathCellsBenchmark

cellToParent Benchmark:
H3-js time in ns:    1062642
H3-node time in ns:  411856
✔ cellToParentBenchmark

cellToChildren Benchmark:
H3-js time in ns:    985474186
H3-node time in ns:  895306179
✔ cellToChildrenBenchmark

cellToCenterChild Benchmark:
H3-js time in ns:    1203932
H3-node time in ns:  454949
✔ cellToCenterChildBenchmark

compactCells Benchmark:
H3-js time in ns:    120589679
H3-node time in ns:  49026745
✔ compactCellsBenchmark

uncompactCells Benchmark:
H3-js time in ns:    51719983
H3-node time in ns:  43166044
✔ uncompactCellsBenchmark

polygonToCells Benchmark:
H3-js time in ns:    51227180
H3-node time in ns:  27323211
✔ polygonToCellsBenchmark

polygonToCellsWithHoles Benchmark:
H3-js time in ns:    57260529
H3-node time in ns:  41699019
✔ polygonToCellsWithHolesBenchmark

cellsToMultiPolygon Benchmark:
H3-js time in ns:    471233062
H3-node time in ns:  393672608
✔ cellsToMultiPolygonBenchmark

cellsToMultiPolygonGeoJsonMode Benchmark:
H3-js time in ns:    443336590
H3-node time in ns:  390950036
✔ cellsToMultiPolygonGeoJsonModeBenchmark

cellsToMultiPolygonTrueMultiPolygon Benchmark:
H3-js time in ns:    578690116
H3-node time in ns:  518527732
✔ cellsToMultiPolygonTrueMultiPolygonBenchmark

areNeighborCells Benchmark:
H3-js time in ns:    2038122
H3-node time in ns:  647922
✔ areNeighborCellsBenchmark

cellsToDirectedEdge Benchmark:
H3-js time in ns:    1948026
H3-node time in ns:  993080
✔ cellsToDirectedEdgeBenchmark

isValidDirectedEdge Benchmark:
H3-js time in ns:    635001
H3-node time in ns:  294313
✔ isValidDirectedEdgeBenchmark

getDirectedEdgeOrigin Benchmark:
H3-js time in ns:    717554
H3-node time in ns:  400194
✔ getDirectedEdgeOriginBenchmark

getDirectedEdgeDestination Benchmark:
H3-js time in ns:    1119284
H3-node time in ns:  978832
✔ getDirectedEdgeDestinationBenchmark

directedEdgeToCells Benchmark:
H3-js time in ns:    1186332
H3-node time in ns:  933715
✔ directedEdgeToCellsBenchmark

originToDirectedEdges Benchmark:
H3-js time in ns:    2235844
H3-node time in ns:  2371965
✔ originToDirectedEdgesBenchmark

directedEdgeToBoundary Benchmark:
H3-js time in ns:    3099228
H3-node time in ns:  2619554
✔ directedEdgeToBoundaryBenchmark

degsToRads Benchmark:
H3-js time in ns:    33804
H3-node time in ns:  98267
✔ degsToRadsBenchmark

radsToDegs Benchmark:
H3-js time in ns:    87302
H3-node time in ns:  90584
✔ radsToDegsBenchmark

getNumCells Benchmark:
H3-js time in ns:    330701
H3-node time in ns:  88140
✔ getNumCellsBenchmark

getHexagonEdgeLengthAvg Benchmark:
H3-js time in ns:    352072
H3-node time in ns:  111467
✔ getHexagonEdgeLengthAvgBenchmark

edgeLength Benchmark:
H3-js time in ns:    4884662
H3-node time in ns:  2593644
✔ edgeLengthBenchmark

getHexagonAreaAvg Benchmark:
H3-js time in ns:    320085
H3-node time in ns:  112515
✔ getHexagonAreaAvgBenchmark

cellArea Benchmark:
H3-js time in ns:    8145085
H3-node time in ns:  3914910
✔ cellAreaBenchmark

greatCircleDistance Benchmark:
H3-js time in ns:    1210916
H3-node time in ns:  730614
✔ greatCircleDistanceBenchmark

getRes0Cells Benchmark:
H3-js time in ns:    35733206
H3-node time in ns:  28694344
✔ getRes0CellsBenchmark

getPentagons Benchmark:
H3-js time in ns:    5991654
H3-node time in ns:  3668299
✔ getPentagonsBenchmark

OK: 452 assertions (9021ms)
Done in 9.18s.

h3-node is a Node N-API binding of the original C H3 code to provide a higher-performance option in backend Node.js applications.

That makes h3-node a "nice to have" but not as required as h3-js. (In a similar vein, I intend to write an h3-wasm for higher-performance H3 in modern browsers that can be a drop-in replacement for h3-js when WebAssembly is present.)