add next(), prev(), and other helpers

This commit is contained in:
AJ ONeal 2016-07-28 02:13:05 -04:00
parent 7ca690db14
commit 103d955300
2 changed files with 113 additions and 3 deletions

View File

@ -202,7 +202,6 @@ var pointToHilbertQuadList = function(x,y,order) {
return positions; return positions;
}; };
// S2Cell class // S2Cell class
S2.S2Cell = function(){}; S2.S2Cell = function(){};
@ -340,10 +339,16 @@ S2.fromFacePosLevel = function (faceN, posS, levelN) {
bin += '0'; bin += '0';
} }
return Long.fromString(bin, true, 2).toString(); return Long.fromString(bin, true, 2).toString(10);
}; };
S2.toHilbertQuadkey = function (idS) { S2.toId = S2.toCellId = S2.fromKey = function (key) {
var parts = key.split('/');
return S2.fromFacePosLevel(parts[0], parts[1], parts[1].length);
};
S2.toKey = S2.fromId = S2.fromCellId = S2.toHilbertQuadkey = function (idS) {
var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long'); var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long');
var bin = Long.fromString(idS, true, 10).toString(2); var bin = Long.fromString(idS, true, 10).toString(2);
var lsbIndex = bin.lastIndexOf('1'); var lsbIndex = bin.lastIndexOf('1');
@ -365,6 +370,61 @@ S2.toHilbertQuadkey = function (idS) {
return faceS + '/' + posS; return faceS + '/' + posS;
}; };
S2.latLngToKey = S2.latLngToQuadkey = function (lat, lng, level) {
// TODO
//
// S2.idToLatLng(id)
// S2.keyToLatLng(key)
//
// .toKeyArray(id) // face,quadtree
// .toKey(id) // hilbert
// .toPoint(id) // ij
// .toId(key) // uint64 (as string)
// .toLong(key) // long.js
// .toLatLng(id) // object? or array?, or string (with comma)?
// maybe S2.HQ.x, S2.GPS.x, S2.CI.x?
return S2.S2Cell.FromLatLng({ lat: lat, lng: lng }, level).toHilbertQuadkey();
};
S2.stepKey = function (key, num) {
var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long');
var parts = key.split('/');
var faceS = parts[0];
var posS = parts[1];
var level = parts[1].length;
var posL = Long.fromString(posS, true, 4);
// TODO handle wrapping (0 === pos + 1)
// (only on the 12 edges of the globe)
var otherL;
if (num > 0) {
otherL = posL.add(Math.abs(num));
}
else if (num < 0) {
otherL = posL.subtract(Math.abs(num));
}
var otherS = otherL.toString(4);
if ('0' === otherS) {
console.warning(new Error("face/position wrapping is not yet supported"));
}
while (otherS.length < level) {
otherS = '0' + otherS;
}
return faceS + '/' + otherS;
};
S2.prevKey = function (key) {
return S2.stepKey(key, -1);
};
S2.nextKey = function (key) {
return S2.stepKey(key, 1);
};
})('undefined' !== typeof window ? window : module.exports); })('undefined' !== typeof window ? window : module.exports);
(function (exports) { (function (exports) {

50
tests/prev-next.js Normal file
View File

@ -0,0 +1,50 @@
'use strict';
var S2 = require('../src/s2geometry.js').S2;
function getNeighbors(lat, lng, step) {
//var step = 10;
var level = 15;
var origin = S2.latLngToQuadkey(lat, lng, level);
var walk = [];
// 10 before and 10 after
var next = S2.nextKey(origin);
var prev = S2.prevKey(origin);
var i;
for (i = 0; i < step; i++) {
walk.unshift(S2.toId(prev));
prev = S2.prevKey(prev);
}
walk.push(S2.toId(origin));
for (i = 0; i < step; i++) {
// in range(10):
walk.push(S2.toId(next));
next = S2.nextKey(next);
}
return walk;
}
// Startup Building in Provo
var lat = 40.2262363;
var lng = -111.6630927;
var walk = getNeighbors(lat, lng, 5);
walk.forEach(function (cellId, i) {
var key = S2.fromId(cellId);
var face = parseInt(key.substr(0, 1), 10);
var pos = key.substr(2);
var level = pos.length;
// TODO
// S2.keyToLatLng(key);
// S2.idToLatLng(id);
// ! because converting CellId / HilbertQuadkey to LatLng is not implemented... yet
console.log(-((walk.length - 1) / 2) + i, face, cellId, S2.fromId(cellId), '!', level);
});