From 3a962c195623f110d1e8d60818e14c8879ac1279 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Wed, 17 Aug 2016 23:35:20 -0600 Subject: [PATCH] further cleanup and testing for #16 --- README.md | 16 +++++ src/s2geometry.js | 63 ++++++++++++------- .../{hilbertToCell.js => hilbert-to-cell.js} | 19 ++---- tests/key-id-to-latlng.js | 48 ++++++++++++++ 4 files changed, 109 insertions(+), 37 deletions(-) rename tests/{hilbertToCell.js => hilbert-to-cell.js} (86%) create mode 100644 tests/key-id-to-latlng.js diff --git a/README.md b/README.md index 426a8c3..42ec767 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,13 @@ var key = S2.idToKey(id); // '9749618446378729472' +// +// Convert between Quadkey and Id +// +var latlng = S2.keyToLatLng(key); +var latlng = S2.idToLatLng(id); + + // // Neighbors @@ -198,3 +205,12 @@ var hilbertQuadkey = S2.idToKey(cellId); console.log(hilbertQuadkey); ``` + +Convert Key and Id to LatLng +--------------------- + +```javascript +var latlng = S2.keyToLatLng('4/032212303102210'); + +var latlng = S2.idToLatLng('9749618446378729472'); +``` diff --git a/src/s2geometry.js b/src/s2geometry.js index 807ee43..d4d1bec 100644 --- a/src/s2geometry.js +++ b/src/s2geometry.js @@ -272,50 +272,51 @@ S2.S2Cell.FromHilbertQuadKey = function(hilbertQuadkey) { var point = { x : 0, y: 0 - } + }; + var i; + var level; + var bit; + var rx, ry; + var val; - for(var i = maxLevel - 1; i >= 0; i--) - { - - var level = maxLevel - i; - var bit = position[i]; - var rx = 0, ry = 0; - if(bit == '1') - { + for(i = maxLevel - 1; i >= 0; i--) { + + level = maxLevel - i; + bit = position[i]; + rx = 0; + ry = 0; + if (bit === '1') { ry = 1; - } - else if(bit == '2') - { + } + else if (bit === '2') { rx = 1; ry = 1; - } - else if(bit == '3') - { + } + else if (bit === '3') { rx = 1; } - - var val = Math.pow(2, level - 1) + + val = Math.pow(2, level - 1); rotateAndFlipQuadrant(val, point, rx, ry); - + point.x += val * rx; point.y += val * ry; } - - if(face % 2 == 1) - { + + 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) + 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) { + if ((!latLng.lat && latLng.lat !== 0) || (!latLng.lng && latLng.lng !== 0)) { throw new Error("Pass { lat: lat, lng: lng } to S2.S2Cell.FromLatLng"); } var xyz = S2.LatLngToXYZ(latLng); @@ -327,6 +328,7 @@ S2.S2Cell.FromLatLng = function(latLng, level) { return S2.S2Cell.FromFaceIJ (faceuv[0], ij, level); }; + /* S2.faceIjLevelToXyz = function (face, ij, level) { var st = S2.IJToST(ij, level, [0.5, 0.5]); @@ -517,8 +519,21 @@ S2.idToKey = S2.S2Cell.idToKey return faceS + '/' + posS; }; +S2.keyToLatLng = S2.S2Cell.keyToLatLng = function (key) { + var cell2 = S2.S2Cell.FromHilbertQuadKey(key); + return cell2.getLatLng(); +}; + +S2.idToLatLng = S2.S2Cell.idToLatLng = function (id) { + var key = S2.idToKey(id); + return S2.keyToLatLng(key); +}; + S2.S2Cell.latLngToKey = S2.latLngToKey = S2.latLngToQuadkey = function (lat, lng, level) { + if (isNaN(level) || level < 1 || level > 30) { + throw new Error("'level' is not a number between 1 and 30 (but it should be)"); + } // TODO // // S2.idToLatLng(id) diff --git a/tests/hilbertToCell.js b/tests/hilbert-to-cell.js similarity index 86% rename from tests/hilbertToCell.js rename to tests/hilbert-to-cell.js index 6798d89..bc6aa4d 100644 --- a/tests/hilbertToCell.js +++ b/tests/hilbert-to-cell.js @@ -1,10 +1,8 @@ +'use strict'; + var S2 = require('../src/s2geometry.js').S2; - - - -for(var level = 1; level <= 20; level++) -{ +for(var level = 1; level <= 20; level++) { var success = 0; var total = 0; for (var x = -180.0; x < 180; x += 0.5) { @@ -15,7 +13,7 @@ for(var level = 1; level <= 20; level++) var quadKey = cell.toHilbertQuadkey(); var cell2 = S2.S2Cell.FromHilbertQuadKey(quadKey); - if(cell.face != cell2.face || + if(cell.face != cell2.face || cell.ij[0] != cell2.ij[0] || cell.ij[1] != cell2.ij[1] || cell.level != cell2.level) @@ -23,7 +21,7 @@ for(var level = 1; level <= 20; level++) /*console.log({ cell: cell, cell2: cell2})*/ - + } else { @@ -34,10 +32,5 @@ for(var level = 1; level <= 20; level++) } } - console.log("level:" + level + "\t total:" + total + "\t success:" + success) + console.log("level:" + level + "\t total:" + total + "\t success:" + success); } - - - - - diff --git a/tests/key-id-to-latlng.js b/tests/key-id-to-latlng.js new file mode 100644 index 0000000..b509a6e --- /dev/null +++ b/tests/key-id-to-latlng.js @@ -0,0 +1,48 @@ +'use strict'; + +var S2 = require('../src/s2geometry.js').S2; +var x, y; +var count = 0; + +function refCheck() { + var refKey = '4/032212303102210'; + var latlng = { + 'lat': 40.2574448 + , 'lng': -111.7089464 + }; + + var key = S2.latLngToKey(latlng.lat, latlng.lng, 15); + if (key !== refKey) { + throw new Error("reference doesn't match"); + } + + var latlng1 = S2.keyToLatLng('4/032212303102210'); + var key1 = S2.latLngToKey(latlng1.lat, latlng1.lng, 15); + if (key1 !== refKey) { + throw new Error("reference 1 doesn't match"); + } + + var latlng2 = S2.idToLatLng('9749618446378729472'); + var key2 = S2.latLngToKey(latlng2.lat, latlng2.lng, 15); + if (key2 !== refKey) { + throw new Error("reference 2 doesn't match"); + } +} + +function checkReal(lat, lng) { + var key = S2.latLngToKey(lat, lng, 15); + var latlng = S2.keyToLatLng(key); + var key2 = S2.latLngToKey(latlng.lat, latlng.lng, 15); + if (key !== key2) { + throw new Error("keys do not match", latlng, key, key2); + } +} + +for (x = -180; x <= 180; x += (0 + Math.random())) { + for (y = -180; y <= 180; y += (0 + Math.random())) { + count += 1; + checkReal(x, y); + } +} + +console.log('PASS:', count, 'random locations without any key mismatches');