uber / h3-js Goto Github PK
View Code? Open in Web Editor NEWh3-js provides a JavaScript version of H3, a hexagon-based geospatial indexing system.
Home Page: https://uber.github.io/h3
License: Apache License 2.0
h3-js provides a JavaScript version of H3, a hexagon-based geospatial indexing system.
Home Page: https://uber.github.io/h3
License: Apache License 2.0
Emscripten adds global error handling that messes with stack traces and can cause issues in Node. We can suppress in the build with the NODEJS_CATCH_EXIT
flag - see emscripten-core/emscripten#5957
I'm trying to us the h3-js library in a react-native app. I npm installed the library, and then when I just import h3 into one of my files, it gives me an error that say's can't find variable document. I'm assuming it is coming from the libh3.js file in "./dist/out" where it has the function....
var libh3 = (function() {
var _scriptDir = typeof document !== 'undefined' && dtocument.currentScript ? document.currentScript.src : undefined;
return (
........
I don't know where the problem is coming from but it's not in my code because I'm just trying to import h3-js
I try to use polyfill
on a country like CAN
or RUS
, but I get errros like:
Cannot use 'in' operator to search for 'toJSON' in abort(Assertion failed: adjacentFaceDir[tmpFijk.face][fijk.face] == KI, at: faceijk.c,581,_faceIjkPentToGeoBoundary). Build with -s ASSERTIONS=1 for more info.
Cannot use 'in' operator to search for 'toJSON' in abort(OOM). Build with -s ASSERTIONS=1 for more info.
Any idea on how to fix this?
Getting an error attempting to load:
Invalid left-hand side expression in prefix operation
https://codesandbox.io/s/h3-js-error-3murp
import React from 'react';
import ReactDOM from 'react-dom';
import h3 from "h3-js";
function App() {
return <div>Hello world</div>
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Hello,
Suppose we are storing h3 indexes in a database column. To perform a parent/child query I was thinking of using h3 indexes. Lets say we have this index 832834fffffffff
. This cell's children are[ '8428341ffffffff', '8428343ffffffff', '8428345ffffffff', '8428347ffffffff', '8428349ffffffff', '842834bffffffff', '842834dffffffff']
. What is the logic to tell if an h3index id is a child of another id. Is there any way that we can find a range of indexies that are child of the specific id.
I already found uber/h3#320 and https://stackoverflow.com/questions/53911322/is-the-h3index-ordered but could not find my answer.
Thanks
The Snowflake data warehouse supports UDFs written in javascript.
https://docs.snowflake.net/manuals/sql-reference/udf-js.html
I am not proficient in javascript but it seems to me that h3-js relies on the original C library.
The key function I am interested in is h3.geoToH3
but eventually, would like to add a few more.
Do you have any suggestions on how I may be able to create a pure javascript version of this function?
Thanks!
The package is listening all 'UnhandledRejection' errors and throwing it's own (h3-js) error from 'dist/hs-js.js', line: 10979 even if the source of the error is not h3-js package itself.
Is there a way to overwrite this 'UnhandledRejection' errors, what do you suggest?
I am trying to add h3 layer to kepler.gl by replaceing h3-transitional
with h3-js
I am seeing different result calling h3ToGeo
function
When using h3-transitional
, the result is correct
id: 50042a8003a81, centroid: [37.60685873255048,-122.37792703211281]
id: 50042a5803a7f, centroid: [37.635939950070636,-122.39939748488374]
id: 5004295803a87, centroid: [37.79488052776275,-122.39819707999791]
id: 50042a6003a7f, centroid: [37.63064491937859,-122.39776868902631]
id: 5004296803a85, centroid: [37.78689467417056,-122.40828440667723]
id: 5004296003a85, centroid: [37.79218213227278,-122.40991607411941]
id: 5004296003a86, centroid: [37.79088770571817,-122.4032410194023]
id: 5004296803a84, centroid: [37.788188921714365,-122.41495905002361]
id: 5004296803a86, centroid: [37.78559998121372,-122.40160964134064]
id: 5004296803a83, centroid: [37.78948272367625,-122.42163357153376]
While using h3-js
, it isn't and all of the centroid are the same
id: 50042a8003a81, centroid: [20.143053033363785,-130.35704768662526]
id: 50042a5803a7f, centroid: [20.143053033363785,-130.35704768662526]
id: 5004295803a87, centroid: [20.143053033363785,-130.35704768662526]
id: 50042a6003a7f, centroid: [20.143053033363785,-130.35704768662526]
id: 5004296803a85, centroid: [20.143053033363785,-130.35704768662526]
id: 5004296003a85, centroid: [20.143053033363785,-130.35704768662526]
id: 5004296003a86, centroid: [20.143053033363785,-130.35704768662526]
id: 5004296803a84, centroid: [20.143053033363785,-130.35704768662526]
id: 5004296803a86, centroid: [20.143053033363785,-130.35704768662526]
id: 5004296803a83, centroid: [20.143053033363785,-130.35704768662526]
Is there something wrong with the address i am passing in?
When I try to use h3.UNITS
in a Typescript project, I see
'UNITS' only refers to a type, but is being used as a value here.
Probably need to change the way the types are formatted to export a constant.
Hi all,
I am attempting to use h3 to generate a GeoJSON polygon that I will then overlay on a mapbox map. When I try and polyfill(blue) a large square polygon(red) the resulting output gets really glitchy (see screenshots)
However when I halve the size of the red box, the polyfill works as intended?
const polygon = [
[minLon, maxLat],
[maxLon, maxLat],
[maxLon, minLat],
[minLon, minLat]
];
const hexagons = h3.polyfill(polygon, 1, true);
let hexFeatures = []
for(let h of hexagons){
let hexFeature = {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [h3.h3ToGeoBoundary(h, true)]
}
}
hexFeatures.push(hexFeature)
}
let hexGroup = {
"id": "hex",
"type": "fill",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": hexFeatures
}
},
'layout': {},
'paint': {
'fill-color': '#0000ff',
'fill-opacity': 0.50
}
}
map.addLayer(worldGroup)
Is this a possible bug?
Thanks
h3ToGeoboundary
can rarely create hexagons with > 6 sides.
Two examples of this behavior from different base cells: 85a60003fffffff
, 859c7003fffffff
.
See examples examples
Is there an available pre-bundled script transpiled to es5? It's not clear to me what version the various .js
files are.
I need an es5 version as I have a use case with Java 8 Nashorn (i.e. older).
Hi,
I'm using h3-js to compile isochrones (a few hundred millions), and I notices that the memory usage keep growing. After some quick investigations on my code to make sure the issue is not on my side, I think this comes from either h3SetToMultiPolygon or multiPolyfill (I investigate a while ago, and I can't remember). Anyway, after it does what it is supposed to do, a small amont of memory keep being used, and thus, after running it a couple of thousand times, node runs out of memory.
For now, as a quick dirty fix, I run it on child processes that I can restart once in a while.
Sorry for not providing more intels, I investigate this a while ago and found a quick workaround, but it still worth sharing the issue.
Note: i'm using 3.7.1
EDIT: version 3.7.1 was apparently supposed to fix this issue. I guess it's still there...
As per the following example https://github.com/uber/h3/blob/master/examples/distance.c
When running:
h3.h3Distance('842764bffffffff', '840ee05ffffffff');
I get 18, which is the number of kRings and not distance in km. Or is this intended behavior of this function?
Need to research best practices here - could export from the lib, or add directly to the flow-typed
repo.
I encountered a situation where the h3ToParent
function returns a hexagon that does not visually seem to be the parent of the original hexagon.
import { h3ToGeoBoundary, h3ToParent } from "h3-js";
const hexAtRes12 = "8c393362a49d5ff";
const parentHexAtRes6 = h3ToParent("8c393362a49d5ff", 6); // "86393362fffffff"
const polygonRes12 = h3ToGeoBoundary(hexAtRes12, true);
const polygonRes6 = h3ToGeoBoundary(parentHexAtRes6, true);
When rendering these polygons with mapbox gl we get:
I expected the neighbor hex to the bottom left of the yellow hex to be the parent hex of the green hex at resolution 12.
There are also examples the other way around. The res 12 hex "8c39336212687ff" is visually a child of the above res 6 hex "86393362fffffff" but in reality, the h3ToParent
function returns "863933627ffffff" as parent at res 6.
Is this behaviour to be expected? If so, how can it be explained?
This lib is working fine but there's a (to be expected) distortion, is there a simple way to represent the hexagons in a flat 2D way?
I'm getting some weird results from h3SetToMultiPolygon when passing large numbers of h3 indexes (in these examples the h3 cells are all adjacent). There are two issues:
h3Ids:
["8132fffffffffff","812e7ffffffffff","81303ffffffffff","815a3ffffffffff","814f7ffffffffff","81733ffffffffff","81687ffffffffff","814afffffffffff","8133bffffffffff","812f3ffffffffff","814e7ffffffffff","8130fffffffffff","815afffffffffff","8132bffffffffff","814bbffffffffff","812e3ffffffffff","81777ffffffffff","814f3ffffffffff","814abffffffffff","81337ffffffffff","812efffffffffff","814e3ffffffffff","815abffffffffff","81327ffffffffff","814b7ffffffffff","812fbffffffffff","81773ffffffffff","814efffffffffff","81317ffffffffff","815b7ffffffffff","814a7ffffffffff","81333ffffffffff","815a7ffffffffff","81737ffffffffff","81323ffffffffff","814fbffffffffff","814b3ffffffffff","812f7ffffffffff","814ebffffffffff","81313ffffffffff","815b3ffffffffff","814a3ffffffffff","8123bffffffffff","81237ffffffffff","81233ffffffffff","8147bffffffffff","8146fffffffffff","8146bffffffffff","81223ffffffffff","81463ffffffffff","81473ffffffffff","81477ffffffffff","81467ffffffffff","815dbffffffffff","815d3ffffffffff","815cbffffffffff","815c3ffffffffff","8137bffffffffff","815bbffffffffff","81373ffffffffff","8136bffffffffff","81363ffffffffff","8171bffffffffff","81717ffffffffff","81713ffffffffff"]
Gives this result:
[ [ [ [ 43.816094965537175, 142.3058437365082 ], [ 47.94353494620575, 140.81932027711576 ], [ 48.30438780776227, 137.965723000237 ], [ 48.41801789173907, 134.76393627595755 ], [ 45.253613490980094, 131.7744009814935 ], [ 45.09643436908035, 125.98114176677377 ], [ 47.997962809385406, 122.1525950681968 ], [ 47.30945130281312, 116.21289563713783 ], [ 43.25414167974314, 115.50113901102061 ], [ 41.14827082786993, 119.13690952882241 ], [ 38.614966776615006, 118.5828850895855 ], [ 37.42985448428109, 118.86929883406582 ], [ 36.20528264541884, 121.690153924224 ], [ 36.005614448071924, 123.16276457697893 ], [ 32.66144519495384, 124.02055612683286 ], [ 29.89298533869355, 120.503393859958 ], [ 26.20027606045547, 121.34751445935747 ], [ 24.728661050965936, 119.64146543031175 ], [ 23.50895195973631, 117.99047716641068 ], [ 19.252194904738655, 118.80300158646772 ], [ 18.127070267319834, 123.02355515221002 ], [ 13.797500809062361, 123.85482415801255 ], [ 10.736966167684393, 120.449366342475 ], [ 6.2891846753414375, 121.26764633911117 ], [ 4.76343118357537, 125.5023153387887 ], [ 7.805398745803346, 129.0449200915637 ], [ 6.19767652780886, 133.49441060685513 ], [ 9.23145267029969, 137.1970727246292 ], [ 7.537486471095007, 141.69432910913807 ], [ 10.472716898667054, 145.410940917621 ], [ 8.701739974658008, 149.7748737561887 ], [ 4.084015752678338, 150.44123001544202 ], [ 2.3920322085174597, 154.598935323174 ], [ 5.189055516512115, 158.0067643262748 ], [ 3.50810422466813, 161.8156148096885 ], [ 6.119591258608643, 164.93539603741024 ], [ 4.4670316097845255, 168.3352524578736 ], [ 4.467031609784517, 168.3352524578736 ], [ 6.172978893164634, 172.0341823693935 ], [ 4.248592317017831, 175.46041201203371 ], [ 5.8899217543139155, 179.21716082489448 ], [ 5.889921754313889, 179.21716082489448 ], [ 2.9040374505798128, -178.0251966524985 ], [ 3.821024494330419, -174.31673738369324 ], [ 7.972793830841406, -173.38014762578527 ], [ 9.060308038526605, -169.29312998396932 ], [ 5.767146686378422, -166.16940101623453 ], [ 6.766536253596447, -161.77338167921764 ], [ 3.3357348575173495, -158.59967491814012 ], [ 4.260374459536216, -154.0294052002189 ], [ 8.71898308656318, -152.5335322367957 ], [ 9.628747217956542, -147.80006555587835 ], [ 14.110797540904425, -146.16007687374923 ], [ 17.737530353545214, -149.3676428224656 ], [ 22.166939007405805, -147.69594788211106 ], [ 25.669243623986258, -151.04796662686522 ], [ 29.891830084602514, -149.34707529879068 ], [ 30.56995088296885, -144.17342232410294 ], [ 34.454167617014946, -142.3232078622538 ], [ 37.68759229063255, -145.7463690434673 ], [ 41.20828589932378, -143.84631120128412 ], [ 44.09362423911827, -147.45009391663316 ], [ 43.44325276436555, -153.03739182353246 ], [ 43.44325276436556, -153.03739182353243 ], [ 46.9088746957617, -156.03631344405528 ], [ 46.51349897531834, -161.56979335131368 ], [ 49.895974148750696, -165.61336675442524 ], [ 49.05085282910133, -171.87311046039585 ], [ 44.74985555511408, -173.25136162888563 ], [ 43.33462463706693, -179.170112546831 ], [ 46.18001465709014, 175.62099681678237 ], [ 44.17622039141846, 169.66101739290986 ], [ 46.48282657751592, 163.91021485526238 ], [ 43.912304017571394, 158.38289640953528 ], [ 45.62266462732751, 152.54480605394903 ], [ 42.63340688235615, 147.81728377284588 ] ] ], [ [ [ 27.949605976503907, 142.4332217566576 ] ] ], [ [ [ 34.33115860097916, 132.30837745804206 ] ] ], [ [ [ 12.194726726167971, 160.7733897026288 ] ] ] ]
The first polygon is accurate but the others are single points and seem unnecessary. Not a big deal as I can easily filter these out. This doesn't seem to happen at lower H3 resolutions.
For example with these h3 ids:
[ "816efffffffffff", "8126bffffffffff", "8148fffffffffff", "8113bffffffffff", "8122fffffffffff", "810c3ffffffffff", "8150bffffffffff", "815c3ffffffffff", "8126fffffffffff", "81493ffffffffff", "81363ffffffffff", "81457ffffffffff", "81233ffffffffff", "810c7ffffffffff", "8150fffffffffff", "815c7ffffffffff", "81273ffffffffff", "81497ffffffffff", "81367ffffffffff", "81237ffffffffff", "810cbffffffffff", "81513ffffffffff", "815cbffffffffff", "8149bffffffffff", "8136bffffffffff", "8123bffffffffff", "810cfffffffffff", "81517ffffffffff", "811c3ffffffffff", "815cfffffffffff", "816c3ffffffffff", "8127bffffffffff", "8136fffffffffff", "81463ffffffffff", "8151bffffffffff", "81703ffffffffff", "815d3ffffffffff", "81373ffffffffff", "81467ffffffffff", "811cbffffffffff", "81707ffffffffff", "815d7ffffffffff", "816cbffffffffff", "81283ffffffffff", "81377ffffffffff", "8146bffffffffff", "811cfffffffffff", "815dbffffffffff", "81287ffffffffff", "8137bffffffffff", "8146fffffffffff", "811d3ffffffffff", "816d3ffffffffff", "8128bffffffffff", "81473ffffffffff", "811d7ffffffffff", "81713ffffffffff", "8128fffffffffff", "81477ffffffffff", "81123ffffffffff", "811dbffffffffff", "81717ffffffffff", "816dbffffffffff", "81293ffffffffff", "8147bffffffffff", "81127ffffffffff", "81793ffffffffff", "810ebffffffffff", "8171bffffffffff", "81297ffffffffff", "81797ffffffffff", "8112bffffffffff", "816e3ffffffffff", "8129bffffffffff", "81483ffffffffff", "8179bffffffffff", "8112fffffffffff", "81447ffffffffff", "81223ffffffffff", "816e7ffffffffff", "81263ffffffffff", "81487ffffffffff", "81227ffffffffff", "81503ffffffffff", "816ebffffffffff", "81267ffffffffff", "8148bffffffffff", "81137ffffffffff", "8122bffffffffff", "81507ffffffffff", "815fbffffffffff", "814cbffffffffff", "812a7ffffffffff", "8139bffffffffff", "81453ffffffffff", "81677ffffffffff", "81547ffffffffff", "811b7ffffffffff", "812abffffffffff", "814cfffffffffff", "8167bffffffffff", "8154bffffffffff", "811bbffffffffff", "812afffffffffff", "814d3ffffffffff", "813a3ffffffffff", "8145bffffffffff", "8154fffffffffff", "812b3ffffffffff", "814d7ffffffffff", "81183ffffffffff", "813a7ffffffffff", "81277ffffffffff", "81553ffffffffff", "814dbffffffffff", "812b7ffffffffff", "81187ffffffffff", "813abffffffffff", "81557ffffffffff", "812bbffffffffff", "8118bffffffffff", "813afffffffffff", "816c7ffffffffff", "8155bffffffffff", "81743ffffffffff", "8118fffffffffff", "813b3ffffffffff", "8159bffffffffff", "81193ffffffffff", "813b7ffffffffff", "81563ffffffffff", "81197ffffffffff", "813bbffffffffff", "81067ffffffffff", "817c7ffffffffff", "81567ffffffffff", "81343ffffffffff", "810e3ffffffffff", "8119bffffffffff", "815e3ffffffffff", "816d7ffffffffff", "81383ffffffffff", "817cbffffffffff", "8156bffffffffff", "81347ffffffffff", "81753ffffffffff", "810e7ffffffffff", "815e7ffffffffff", "817cfffffffffff", "8156fffffffffff", "8134bffffffffff", "81663ffffffffff", "81757ffffffffff", "8180fffffffffff", "811a3ffffffffff", "815ebffffffffff", "8138bffffffffff", "8134fffffffffff", "81573ffffffffff", "81667ffffffffff", "81443ffffffffff", "8175bffffffffff", "810efffffffffff", "811a7ffffffffff", "815efffffffffff", "81077ffffffffff", "81353ffffffffff", "81577ffffffffff", "8166bffffffffff", "815f3ffffffffff", "811abffffffffff", "814c3ffffffffff", "81393ffffffffff", "81357ffffffffff", "8157bffffffffff", "8144bffffffffff", "810f7ffffffffff", "815f7ffffffffff", "811afffffffffff", "812a3ffffffffff", "8135bffffffffff", "8144fffffffffff", "81673ffffffffff", "81543ffffffffff", "811b3ffffffffff" ]
I get:
[ [ [ [ 43.44325276436555, -153.03739182353246 ] ] ], [ [ [ 14.48240061773311, -65.76882190787967 ] ] ], [ [ [ 19.358823435394214, -75.99854824376126 ] ] ], [ [ [ 8.931891500446854, -127.11406580207421 ] ] ], [ [ [ 59.16948256665965, -139.68359348160976 ] ] ], [ [ [ 40.975558199255886, -54.879012779249344 ] ] ], [ [ [ 31.285608665560563, -134.10648897177788 ] ] ], [ [ [ 29.30037465923499, 0.2609468260311339 ] ] ], [ [ [ 41.45713981733575, -138.450291223663 ] ] ], [ [ [ 29.82877615972559, -1.240802016513824 ] ] ], [ [ [ 31.877885956365837, -62.02252554784451 ] ] ], [ [ [ 11.545295975414758, -4.01399844347046 ] ] ] ]
i.e. no actual polygon, just a series of points — seems like a bug?
The docs say it "can be used either in Node >= 4 or in the browser", but the package.json specifies node < 10
.
"engines": {
"node": ">=4 <10",
Just wondering if there's anything in the current version that breaks this library? or if the package.json is just being overly restrictive?
importing h3-js this way import * as h3 from "h3-js";
would trigger the error below:
[Sat May 08 2021 16:50:27.116] ERROR Error: Requiring module "node_modules/h3-js/dist/browser/h3-js.js", which threw an exception: ReferenceError: Can't find variable: document
[Sat May 08 2021 16:50:27.132] ERROR ReferenceError: Can't find variable: document
I am wondering if this could be easily fixed? I am reading that there is a node version of h3-js, how can I import it instead of the browser version?
I tried to only import the function I was using at the time but I am still getting the same error
import {geoToH3} from 'h3-js';
I think the error is pointing to this code here in h3-js
var readAsync;
{
if (document.currentScript) {
scriptDirectory = document.currentScript.src;
}
if (scriptDirectory.indexOf("blob:") !== 0) {
scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf("/") + 1);
} else {
scriptDirectory = "";
}
While using the compact feature to optimize a cluster of hexes at high resolution, I noticed the introduction of gaps into the cluster like so:
I understand that these gaps are an expected distortion as a result of choosing hexagons as the preferred tessellation shape (as outlined in the H3 eng blog announcement). I was looking to understand more details about this tessellation algorithm and if its possible to close these gaps.
Perhaps, we could create a tangential compact function that slightly increases the area covered by these hexagons in order to fill these gaps? I understand this would cause more extensive overlaps, but in our use case that would be preferable to having gaps in the area.
Could you provide more details regarding this algorithm? Thanks! @nrabinowitz
This might make the library a bit more accessible, and easier to use in Observable etc.
All current functions accept H3 indexes as strings, but we could potentially accept [int, int]
as well - two 32-bit integers representing the 64-bit index, probably in [lower, upper]
order to match the h3IndexToSplitLong
output. This should offer slightly better performance by skipping the string-parsing step.
Seems to run faster and has Windows, Mac, and Linux in a single CI.
#55 added auto-generated TypeScript types, but it seems like some of the functions (e.g. h3ToGeoBoundary
) that return an array of arrays (i.e. Array[]
) don't type-check properly in TypeScript, since the compiler expects the outer Array
to have a type parameter:
Line 566 in c5f653f
The fix is likely to specify the inner-most type explicitly (e.g. Number[][]
) in the JSDoc.
Hi!
I'm creating an app which shows nearby posts in a customizeable radius (with accuracy of ~100m). I've found h3 to be a very efficient library, but I couldn't quite figure out how to efficiently query my firestore NoSQL database using H3, since firestore is very limited in querying capabilities.
I've currently come up with this solution:
export async function loadNearbyPosts(coordinates: Coordinates, radius: number): Promise<Post[]> {
const h3 = geoToH3(coordinates.latitude, coordinates.longitude, H3_RESOLUTION);
console.log(`${JSON.stringify(coordinates)} -> ${h3}`);
const neighbours = kRing(h3, 10); // <-- how do I convert my 'radius' in metres to the k-ring range ('10')?
console.log(`Neighbours of ${h3} include: ${JSON.stringify(neighbours)}`);
const batchedNeighbours: string[][] = [];
for (let i = 0; i < neighbours.length; i += 10) batchedNeighbours.push(neighbours.splice(i, 10));
console.log(`Batched to size of 10s: ${JSON.stringify(batchedNeighbours)}`);
console.log(`Running ${batchedNeighbours.length} queries...`);
const start = global.nativePerformanceNow();
// how do I remove this batching and instead use range checks? something like `greater than this h3 and smaller than this h3`
const queries = batchedNeighbours.map((n) => firestore().collection('posts').where('location.h3', 'in', n).get());
const results = await Promise.all(queries);
const end = global.nativePerformanceNow();
const docs: Post[] = [];
results.forEach((r) => docs.push(...r.docs.map((d) => build<Post>(d))));
console.log(`Executed ${batchedNeighbours.length} queries and received ${docs.length} results, all within ${end - start}ms.`);
return docs;
}
While this does indeed return results for me, it is very inefficient. For this simple query, it actually executes 17 queries (!!) because firestore has a limit of maximum 10
items in an array in the in
query (that's why I'm batching the neighbours into arrays of 10 elements), and I'm comparing for exact matches, so I'm forced to using the same precision for all my h3 hexagons.
Using geohashes, I can find by range since they're alphabetically sorted. E.g. I can filter for bc
-> bc~
which gives me all squares that start with bc
.
Now let's get to my actual questions:
871e064d5ffffff
-> 871e06498ffffff
, plus everything in range of 871e0649bffffff
-> 871e06509ffffff
... or in other words "larger than this h3 but smaller than this h3")Thanks for your help!
Any reason why h3Distance is not in the JS API?
Hi,
I encounter an indexing problem when I want to index a polyline with the h3Line function.
You can see on the picture (below) that the polyline is not indexed correctly.
Some hexagon has the index of the line while it is not there and vice versa.
Is this a known problem of the h3Line function or an implementation problem?
Thank you for your help.
Below is the image and the code used.
function indexLinePetiteEchelle(req){
const layer = {};
// This first piece of code creates the indexing for each node of the polyline.
jsonDataLPE.features.forEach(feature => {
const ind = [];
for (let i = 0; i < feature.geometry.coordinates.length; i++) {
const [lng, lat] = [feature.geometry.coordinates[i][0],feature.geometry.coordinates[i][1]];
const stationIndex = h3.geoToH3(lat, lng, parseInt(req.body.resolution));
const ring = h3.kRing(stationIndex, 1);
ind.push(h3Index);
);
}
// The second allows to create an indexation between point n and point n+1 of the polyline. (h3line)
for(let i=0;i<ind.length-1;i++){
const layerB = h3.h3Line(ind[i], ind[i+1]);
layerB.forEach(h3Index => {
layer[h3Index] = (layer[h3Index] || 0) + 1;
});
}
});
const geojsonLPE = geojson2h3.h3SetToFeatureCollection(
Object.keys(layer),
hex => ({value: layer[hex]})
);
return {indexGeoJson: geojsonLPE, hexes: layer};
}
A few questions & clarifications:
Unfortunately I do not have a background in mathematics, please be patient with me.
The gist of my use case is a geo-location based mobile game that uses a hexagonal grid to represent the world, something H3 appears to exactly solve for. Though, this use case necessitates the need to have a coordinate system that can uniquely identify each cell in the global grid for a variety of reasons. I am having a hard time figuring out how to obtain coordinates from the cells of an H3 grid.
H3 Coordinate Systems: https://h3geo.org/docs/core-library/coordsystems
Hexagonal Coordinate Systems: https://www.redblobgames.com/grids/hexagons/#coordinates
I marginally familiar three coordinate systems for hexagonal grids:
In the H3 docs, it mentions:
3 coordinate axes spaced 120° apart
which seems like a cube coordinate system. However the example picture's coordinates don't seem to line up with the expectation of i+j+k == 0
.[x,y]
coordinates for the IJK
coordinates with the +x axis
aligned on i axis
. This appears to be what I am looking for.Axial Coordinates
?IJK
to Hex2d
?local coordinates are only valid near the origin.
. Which points out that these coordinates are really only valid within the same base cell.TL;DR: How can I obtain cartesian coordinates for each cell that are globally unique?
It seems that calling polyfill
with a complex polygon (that crosses the antimeridian) messes with the h3 internals somehow, causing subsequent calls to return incorrect results.
This is best demonstrated by this jsfiddle: https://jsfiddle.net/tamaxerra/kxz865m7/1/
The console output from the fiddle is the number of h3 indexes returned:
36
56
27
The first (36) and last (27) count are the result of the same polygon being passed.
To reproduce:
It seems h3ToGeoBoundary
returns an array of vertices, that close the hexagon/pentagon/etc , i.e first and last vertices are same. When it is a hexagon it returns 7 vertices, where first and last are the same. It will be helpful to clarify this in the documentation.
Line 24 in 0ef85b2
The fusionJS
build process is misled by this line and will try to import dist/h3-js.es.js
instead of dist/h3-js.js
.
After that happens, webpack/babel transpile the module in a way that other modules will try to find the functions under h3Js.default.geoToH3
, instead of the correct h3Js.geoToH3
.
Changing this line locally to "module": "dist/h3-js.js"
fixes my issue, but I'm wondering if that will break other projects instead.
If you need to know, I'm using the package @uber/h3-overlays
, which imports @uber/h3-transitional
, which in turn imports h3-js
.
I would appreciate if you could take a look and shed some light whether we can change the module
file or not.
Hi!
I'm just confused in how I can implement on a Uber-like system.
Let's say that I have my user geolocated and also I have his h3 index, if I want to find the nearest delivery man, I can do one of the following approaches:
First approach
can cost a lot
Second approach
i think this is the best approach
Third approach
???
Thank you so much for your time in advance!
Hey @nrabinowitz
So h3-node currently (ab)uses h3-js for unit testing by just confirming that the outputs of both are identical given semi-random inputs.
I've noticed intermittent failures in the h3Line
test, and after digging through the code, I think the issue might be on the h3-js side.
We can see in the declaration of the h3Line function that it returns an integer value.
/** @brief Line of h3 indexes connecting two indexes */
int H3_EXPORT(h3Line)(H3Index start, H3Index end, H3Index *out);
And in the documentation on the implementation that the return value is an error/success status code
* @return 0 on success, or another value on failure.
So the h3-node implementation of binding h3Line includes a check for that status
int errorCode = h3Line(origin, destination, line);
if (errorCode != 0) {
napi_throw_error(env, "EINVAL", "Line cannot be calculated");
free(line);
return NULL;
}
But the h3-js implementation of binding h3Line ignores that status
function h3Line(origin, destination) {
const [oLower, oUpper] = h3IndexToSplitLong(origin);
const [dLower, dUpper] = h3IndexToSplitLong(destination);
const count = H3.h3LineSize(oLower, oUpper, dLower, dUpper);
if (count < 0) {
// We can't get the specific error code here - may be any of
// the errors possible in experimentalH3ToLocalIj
throw new Error('Line cannot be calculated');
}
const hexagons = C._calloc(count, SZ_H3INDEX);
H3.h3Line(oLower, oUpper, dLower, dUpper, hexagons); // << Not reading the return value
const out = readArrayOfHexagons(hexagons, count);
C._free(hexagons);
return out;
}
I'd normally just make a PR to fix this, but since you implemented the C version of the code and the JS bindings, I wanted to bring this up before, in case this was actually intentional?
There are no cellArea, exactEdgeLength, pointDist functions in h3-reactnative
Hi,
I know that since Js does not support BigInteger this library is returning hex results as index, but is there any safe way to use BigInt
object in js to handle these numbers? since in my case I need to manipulate the indexes.
I have already read the H3(written by c). From your work, I knew that there are a variety of different ways to render H3 hexagons on a map. But I don't know how to write an JavaScript program(html?) , can you give me a Demo?
Thank you very much! my email address:[email protected]
When installing this package vis npm, this line is imported containing the ES6 token const
, which is breaking our build process in production, as uglifiers expect only ES5 code in node_modules.
Line 36 in 5f07884
Please replace const
with var
, to make this safely importable via npm.
We should test the Emscripten build in CI and fail if the generated artifact differs from the commit.
Hi, just seeking some advice on how to correctly attribute the license for https://github.com/obrl-soil/h3jsr.
I've inherited Apache 2.0 from this project, with the attribution statement split per https://github.com/obrl-soil/h3jsr/blob/master/LICENSE.md#appendix-how-to-apply-the-apache-license-to-your-work. Is this the correct approach?
I should note your own copy of the license is still blank at
Line 189 in 6b34d6c
We previously used the following to generate all hexes at zoom 0:
h3
.polyfill([[-90, -180], [90, -180], [90, 0], [-90, 0]], 0)
.concat(h3.polyfill([[-90, 180], [90, 180], [90, 0], [-90, 0]], 0))
When upgrading to 3.6.2 from 3.5.0, the above code returns an empty array.
Hi,
Im trying to incorprate your library on a number of solutions which require realtime translations between hex ids and geojson multi/polygons.
h3.h3SetToMultiPolygon(["85291a6ffffffff"],true)
returns
[[[[-121.87310260648961,36.48355301296484],[-121.82059177712684,36.56646154014561],[-121.88144909358076,36.64149027277887],[-121.99481876336013,36.63355254199253],[-122.0471691328904,36.550641568925464],[-121.98631059624982,36.4756707384872],[-121.87310260648961,36.48355301296484]]]]
No problem with that. The issue however is displaying this now results in an askew/misrepresented polygon on a map.
The map is in EPSG:4326.
Geojson.io
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"color": "blue"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
-121.87310260648961,
36.48355301296484
],
[
-121.82059177712684,
36.56646154014561
],
[
-121.88144909358076,
36.64149027277887
],
[
-121.99481876336013,
36.63355254199253
],
[
-122.0471691328904,
36.550641568925464
],
[
-121.98631059624982,
36.4756707384872
],
[
-121.87310260648961,
36.48355301296484
]
]
]
]
}
}
]
}
Is this correct?
Hi
I am using h3 as means of generating a heatmap across a large map. Currently the drawing aspect is a little slow (many thousands of hexagons). So instead of drawing each hexagon separately I want to combine them using h3.h3SetToMultiPolygon
.
I found it quite confusing to understand what the actual return is from this method. But I attempted to draw using the return value as if it were a list of polygons. When I try to draw these polygons it fills in large areas. Am I doing something wrong? Here is my code (typescript + google maps)
var megaPolygon = h3.h3SetToMultiPolygon(h3StringArray, false);
this.displayPolygons = [];
megaPolygon.forEach(polygon => {
polygon.forEach(polygonLoop => {
var newPath: ILatLngLiteral[] = [];
polygonLoop.forEach(point => {
newPath.push({
latitude: point[0] as any,
longitude: point[1] as any
});
});
this.displayPolygons.push({
id: this.displayPolygons.length,
path: newPath,
fill: {
color: this.getHeatmapColor(0.7),
opacity: 1
},
stroke: {
weight: 0
},
});
});
});
In these screenshots the top one is all individual hexagons, the bottom one is using h3.h3SetToMultiPolygon
Hi,
Using the latest version, if I generate a cell around latitude 50º North, I get the following coordinates:
-1.3219318484448281,50.768516534439534
-1.2914715984357399,50.77757400890455
-1.2658101799357302,50.75620946752976
-1.270599641666343,50.72577692057219
-1.301064224845246,50.71670684748162
-1.3267350166044807,50.738081918893414
which results in this plot:
The cell is not even drawn in the right location, this is a screenshot of a H3 viewer which plots the cells correctly and in the correct locations:
I'm using OpenLayers, with the following code to generate the polygon vertices:
let h3Index = h3.geoToH3(lng, lat, 6);
let hexBoundary = h3.h3ToGeoBoundary(h3Index);
let polygon = new Polygon([hexBoundary]);
polygon.transform("EPSG:4326", "EPSG:3857"); // Transform to web mercator projection
hex = new Feature(polygon);
I have been digging through some code, have found a couple of other references online to this issue, which only provide "your polygons will get distorted at high latitudes". I get that, but not that distorted at 50º North.
Hi,
Just an FYI of vulnerabilities reported by npm. Seems like, as always its lodash
, and extend
.
found 3 vulnerabilities (1 moderate, 2 high) in 2278 scanned packages
Moderate Prototype Pollution
Package extend
Dependency of request
Path request > extend
More info https://npmjs.com/advisories/996
High Prototype Pollution
Package lodash
Dependency of cheerio
Path cheerio > lodash
More info https://npmjs.com/advisories/1065
High Prototype Pollution
Package lodash
Dependency of request-promise
Path request-promise > request-promise-core > lodash
More info https://npmjs.com/advisories/1065
Hi, I have noticed that h3IsValid will return true for many indexes that are not actually valid. For example:
h3IsValid("8a28308hello_world_ppppppppppppppppppqadjsadjasldajaskldlkjdklasjlk5505ffff")
Returns true even though the string is clearly invalid. I think this is due to the calls to parseInt() in the h3IndexToSplitLong method:
if (typeof h3Index !== 'string') {
return [0, 0];
}
const upper = parseInt(h3Index.substring(0, h3Index.length - 8), BASE_16);
const lower = parseInt(h3Index.substring(h3Index.length - 8), BASE_16);
return [lower, upper];
}
The first parseInt call will just ignore all of the extraneous characters in the middle of the string, only parsing "8a28308". This results in the above index being evaluated as equivalent to "8a283085505ffff".
Demo: https://uber-common-public.s3-us-west-2.amazonaws.com/svc-vis-prototype/h3-grid/index.html
The app calls h3.polyfill
to get hexagons that fill each OSM tile. The offending tiles here are
{
"x": 87,
"y": 153,
"z": 8,
"east": -56.25,
"north": -33.13755119234615,
"south": -34.30714385628804,
"west": -57.65625,
}
{
"x": 86,
"y": 154,
"z": 8,
"east": -57.65625,
"north": -34.30714385628804,
"south": -35.4606699514953,
"west": -59.0625,
}
Though the issue is observed at multiple zoom levels.
Extracting the h3 code from the Observables workbooks has been brutal. All my existing code uses jQuery so having just plain HTML, Javascript examples would save a lot of time
Per istanbuljs/nyc#1042 , the fix we need in nyc
to properly report coverage is in master but not released, which is why we currently peg the commit in package.json
. Upgrade normally when v14.0.0
is released.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.