add support to convert from HilbertQuadkey to s2Cell.

This commit is contained in:
Patrick 2016-08-16 22:08:21 -07:00
parent a4e97ba0a9
commit d28f0a6d3f
2 changed files with 116 additions and 0 deletions

View File

@ -200,6 +200,30 @@ S2.IJToST = function(ij,order,offsets) {
];
};
var rotateAndFlipQuadrant = function(n, point, rx, ry)
{
var newX, newY;
if(ry == 0)
{
if(rx == 1){
point.x = n - 1 - point.x;
point.y = n - 1 - point.y
}
var x = point.x;
point.x = point.y
point.y = x;
}
}
// hilbert space-filling curve
// based on http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves
// note: rather then calculating the final integer hilbert position, we just return the list of quads
@ -240,6 +264,55 @@ var pointToHilbertQuadList = function(x,y,order,face) {
S2.S2Cell = function(){};
S2.S2Cell.FromHilbertQuadKey = function(hilbertQuadkey) {
var parts = hilbertQuadkey.split('/');
var face = parseInt(parts[0]);
var position = parts[1];
var maxLevel = position.length;
var point = {
x : 0,
y: 0
}
for(var i = maxLevel - 1; i >= 0; i--)
{
var level = maxLevel - i;
var bit = position[i];
var rx = 0, ry = 0;
if(bit == '1')
{
ry = 1;
}
else if(bit == '2')
{
rx = 1;
ry = 1;
}
else if(bit == '3')
{
rx = 1;
}
var val = Math.pow(2, level - 1)
rotateAndFlipQuadrant(val, point, rx, ry);
point.x += val * rx;
point.y += val * ry;
}
if(face % 2 == 1)
{
var t = point.x;
point.x = point.y;
point.y = t;
}
return S2.S2Cell.FromFaceIJ(parseInt(face),[point.x, point.y],level)
}
//static method to construct
S2.S2Cell.FromLatLng = function(latLng, level) {
if (latLng.lat == null || latLng.lng == null) {

43
tests/hilbertToCell.js Normal file
View File

@ -0,0 +1,43 @@
var S2 = require('../src/s2geometry.js').S2;
for(var level = 1; level <= 20; level++)
{
var success = 0;
var total = 0;
for (var x = -180.0; x < 180; x += 0.5) {
for (var y = -180.0; y < 180; y += 0.5) {
var latlng = { lat: x, lng: y };
var cell = S2.S2Cell.FromLatLng(latlng, level);
var quadKey = cell.toHilbertQuadkey();
var cell2 = S2.S2Cell.FromHilbertQuadKey(quadKey);
if(cell.face != cell2.face ||
cell.ij[0] != cell2.ij[0] ||
cell.ij[1] != cell2.ij[1] ||
cell.level != cell2.level)
{
/*console.log({
cell: cell,
cell2: cell2})*/
}
else
{
success++;
}
total++;
// check equal
}
}
console.log("level:" + level + "\t total:" + total + "\t success:" + success)
}