mapbox / node-s2

bindings for s2 in node
88 stars 38 forks source link

CellID(0,0) mismatch with golang/geo/s2 and java s2 lib #92

Open realfun opened 7 years ago

realfun commented 7 years ago

I am trying to use this for a project, did a simple test like the following:

const s2 = require('s2');
let ll = new s2.S2LatLng(0, 0);
let cell = new s2.S2Cell(ll);
let cid = new s2.S2CellId(ll);

console.log(cid.id());
console.log(cid.parent(10).id());
console.log(cid.parent(11).id());
console.log(cid.parent(12).id());
console.log(cid.parent(13).id());

The results is like the following:

1152921504606847000
1152922604118474800 (if I use this on Java / go lib, it returns level 28)
1152921779484754000 (level 28 on java lib)
1152921573326323700 (level 29 on java lib)
1152921521786716200

On Java lib and Golang version, it is like below:

1152921504606846977
1152922604118474752
1152921779484753920
1152921573326323712
1152921521786716160

Am I using it wrong or some misunderstanding?

jkao commented 5 years ago

Hey realfun,

The IDs in mapbox s2 are corrupted because they're returning a JavaScript number type. S2 Cell IDs are 64 bit, whereas the positive limit to the number type in JavaScript is 53 bits (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER).

We're actively working on new bindings for the S2 C++ library over at Radar (https://github.com/radarlabs/s2) and we return a BigInt to address this issue.

Here's an example with that library:

const s2 = require('@radarlabs/s2');

const ll = new s2.LatLng(0, 0);
const cid = new s2.CellId(ll);

console.log(cid.id());
console.log(cid.parent(10).id());
console.log(cid.parent(11).id());
console.log(cid.parent(12).id());
console.log(cid.parent(13).id());

Which results in:

1152921504606846977n
1152922604118474752n
1152921779484753920n
1152921573326323712n
1152921521786716160n