Compare commits
	
		
			34 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 7a10f5b562 | ||
|  | e7ecb48449 | ||
|  | 441c693bad | ||
|  | e67bb19828 | ||
|  | df6d38b5ad | ||
|  | 3a962c1956 | ||
|  | 5495dd0a53 | ||
|  | d28f0a6d3f | ||
|  | a4e97ba0a9 | ||
|  | 0cc25036e5 | ||
|  | a11cd4e920 | ||
|  | 42a9eaf1fc | ||
|  | 4e631500ea | ||
|  | 8aa84ebf93 | ||
|  | 9fdcc00739 | ||
|  | 7180db1be6 | ||
|  | c6ee1ee508 | ||
|  | 4249d3bfa6 | ||
|  | 60d01395ef | ||
|  | 2e7b12e212 | ||
|  | 1a9c95e2c6 | ||
|  | b3f5bbd27f | ||
|  | f96e16c6bf | ||
|  | d1f19ef616 | ||
|  | 191e83fe40 | ||
|  | 4c4154a288 | ||
|  | be9112f2ad | ||
|  | bb664af25b | ||
|  | 98fa79b6bd | ||
|  | d5524f7b74 | ||
|  | afe681240b | ||
|  | 197e07a605 | ||
|  | 60186d007f | ||
|  | b7f7c6df1c | 
							
								
								
									
										153
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								README.md
									
									
									
									
									
								
							| @ -1,10 +1,86 @@ | |||||||
| s2-geometry (JavaScript/ES5.1) | s2-geometry (JavaScript/ES5.1) | ||||||
| ====================== | ====================== | ||||||
| 
 | 
 | ||||||
|  | | Sponsored by [ppl](https://ppl.family) | ||||||
|  | 
 | ||||||
| A pure JavaScript/ES5.1 port of Google/Niantic's S2 Geometry library (as used by **Ingress**, **Pokemon GO**) | A pure JavaScript/ES5.1 port of Google/Niantic's S2 Geometry library (as used by **Ingress**, **Pokemon GO**) | ||||||
| 
 | 
 | ||||||
| Currently contains basic support for S2Cell | Currently contains basic support for S2Cell | ||||||
| 
 | 
 | ||||||
|  | <table> | ||||||
|  | <tr> | ||||||
|  | <td></td> | ||||||
|  | <td> | ||||||
|  | Face 2 | ||||||
|  | <br> | ||||||
|  | Orientation A | ||||||
|  | 
 | ||||||
|  | <a href="http://i.imgur.com/SODO4bT.jpg" target="_face2"><img src="http://i.imgur.com/SODO4bTt.jpg" title="Face 2" alt="Face 2"></a> | ||||||
|  | 
 | ||||||
|  | <br> | ||||||
|  | The North Pole<br>(and Canada / Europe) | ||||||
|  | </td> | ||||||
|  | <td></td> | ||||||
|  | </tr> | ||||||
|  | <tr> | ||||||
|  | <td> | ||||||
|  | Face 0 | ||||||
|  | <br> | ||||||
|  | Orientation A | ||||||
|  | 
 | ||||||
|  | <a href="http://i.imgur.com/dLI5Zd1.jpg" target="_face0"><img src="http://i.imgur.com/dLI5Zd1t.jpg" title="Face 0" alt="Face 0"></a> | ||||||
|  | 
 | ||||||
|  | <br> | ||||||
|  | Africa | ||||||
|  | </td> | ||||||
|  | <td> | ||||||
|  | Face 1 | ||||||
|  | <br> | ||||||
|  | Orientation D | ||||||
|  | 
 | ||||||
|  | <a href="http://i.imgur.com/duTLDTV.jpg" target="_face1"><img src="http://i.imgur.com/duTLDTVt.jpg" title="Face 1" alt="Face 1"></a> | ||||||
|  | 
 | ||||||
|  | <br> | ||||||
|  | Asia | ||||||
|  | </td> | ||||||
|  | <td> | ||||||
|  | Face 3 | ||||||
|  | <br> | ||||||
|  | Orientation D | ||||||
|  | 
 | ||||||
|  | <a href="http://i.imgur.com/6Ho35Tc.jpg" target="_face3"><img src="http://i.imgur.com/6Ho35Tct.jpg" title="Face 3" alt="Face 3"></a> | ||||||
|  | 
 | ||||||
|  | <br> | ||||||
|  | Nothing<br>(and Australia) | ||||||
|  | </td> | ||||||
|  | <td> | ||||||
|  | Face 4 | ||||||
|  | <br> | ||||||
|  | Orientation A | ||||||
|  | 
 | ||||||
|  | <a href="http://i.imgur.com/3IBAfqj.jpg" target="_face4"><img src="http://i.imgur.com/3IBAfqjt.jpg" title="Face 4" alt="Face 4"></a> | ||||||
|  | 
 | ||||||
|  | <br> | ||||||
|  | The Americas<br>(and Provo, UT) | ||||||
|  | </td> | ||||||
|  | </tr> | ||||||
|  | <tr> | ||||||
|  | <td></td> | ||||||
|  | <td></td> | ||||||
|  | <td></td> | ||||||
|  | <td> | ||||||
|  | Face 5 | ||||||
|  | <br> | ||||||
|  | Orientation D | ||||||
|  | 
 | ||||||
|  | <a href="http://i.imgur.com/HZCBvgy.jpg" target="_face5"><img src="http://i.imgur.com/HZCBvgyt.jpg" title="Face 5" alt="Face 5"></a> | ||||||
|  | 
 | ||||||
|  | <br> | ||||||
|  | Antarctica | ||||||
|  | </td> | ||||||
|  | </tr> | ||||||
|  | </table> | ||||||
|  | 
 | ||||||
| Where is this being used? | Where is this being used? | ||||||
| --------------------- | --------------------- | ||||||
| 
 | 
 | ||||||
| @ -16,15 +92,57 @@ Simple Examples | |||||||
| --------------- | --------------- | ||||||
| 
 | 
 | ||||||
| ```javascript | ```javascript | ||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var S2 = require('s2-geometry').S2; | ||||||
|  | 
 | ||||||
|  | var lat = 40.2574448; | ||||||
|  | var lng = -111.7089464; | ||||||
| var level = 15; | var level = 15; | ||||||
| var latlng = { lat: 40.2574448, lng: -111.7089464 }; |  | ||||||
| var cell = S2.S2Cell.FromLatLng(latlng, level); |  | ||||||
| 
 | 
 | ||||||
| cell.getNeighbors();  // [ cellLeft, cellDown, cellRight, cellUp ] |  | ||||||
| 
 | 
 | ||||||
| cell.getLatLng();     // { lat: 40.2574448, lng: -111.7089464 } |  | ||||||
| 
 | 
 | ||||||
| var key = cell.toHilbertQuadkey(); | // | ||||||
|  | // Convert from Lat / Lng | ||||||
|  | // | ||||||
|  | var key = S2.latLngToKey(lat, lng, level); | ||||||
|  | // '4/032212303102210' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // Convert between Hilbert Curve Quadtree Key and S2 Cell Id | ||||||
|  | // | ||||||
|  | var id = S2.keyToId(key); | ||||||
|  | // '9749618446378729472' | ||||||
|  | 
 | ||||||
|  | var key = S2.idToKey(id); | ||||||
|  | // '9749618446378729472' | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // Convert between Quadkey and Id | ||||||
|  | // | ||||||
|  | var latlng = S2.keyToLatLng(key); | ||||||
|  | var latlng = S2.idToLatLng(id); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // Neighbors | ||||||
|  | // | ||||||
|  | var neighbors = S2.latLngToNeighborKeys(lat, lng, level); | ||||||
|  | // [ keyLeft, keyDown, keyRight, keyUp ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | // Previous, Next, and Step | ||||||
|  | // | ||||||
|  | var nextKey = S2.nextKey(key); | ||||||
|  | var prevKey = S2.prevKey(key); | ||||||
|  | 
 | ||||||
|  | var backTenKeys = S2.stepKey(key, -10); | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Previous and Next | Previous and Next | ||||||
| @ -37,14 +155,16 @@ You can get the previous and next S2CellId from any given Key: | |||||||
| 3. Convert the Key to an Id (uint64 string) | 3. Convert the Key to an Id (uint64 string) | ||||||
| 
 | 
 | ||||||
| ```javascript | ```javascript | ||||||
| var key = S2.latLngToKey(40.2574448, -111.7089464);   // '4/032212303102210' | var key = S2.latLngToKey(40.2574448, -111.7089464, 15);   // '4/032212303102210' | ||||||
| var id = S2.toId(key);                                // '9749618446378729472' | var id = S2.keyToId(key);                                 // '9749618446378729472' | ||||||
| 
 | 
 | ||||||
| var nextKey = S2.nextKey(key); | var nextKey = S2.nextKey(key); | ||||||
| var nextId = S2.toId(nextKey); | var nextId = S2.keyToId(nextKey); | ||||||
| 
 | 
 | ||||||
| var prevKey = S2.prevKey(key); | var prevKey = S2.prevKey(key); | ||||||
| var prevId = S2.toId(prevKey); | var prevId = S2.keyToId(prevKey); | ||||||
|  | 
 | ||||||
|  | var backTenKeys = S2.stepKey(key, -10); | ||||||
| 
 | 
 | ||||||
| // See it | // See it | ||||||
| console.log(prevKey);                                 // '4/032212303102203' | console.log(prevKey);                                 // '4/032212303102203' | ||||||
| @ -53,7 +173,7 @@ console.log(nextKey);                                 // '4/032212303102211' | |||||||
| console.log(nextId); | console.log(nextId); | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| convert Cell Id to Quadkey | convert Cell Id to Hilbert Curve Quad Tree | ||||||
| ------------------ | ------------------ | ||||||
| 
 | 
 | ||||||
| Convert from base 10 (decimal) `S2 Cell Id` to base 4 `quadkey` (aka hilbert curve quadtree id) | Convert from base 10 (decimal) `S2 Cell Id` to base 4 `quadkey` (aka hilbert curve quadtree id) | ||||||
| @ -69,7 +189,7 @@ var face = parts[0];                  // 4 | |||||||
| var position = parts[1];              // '032212303102210'; | var position = parts[1];              // '032212303102210'; | ||||||
| var level = '032212303102210'.length; // 15 | var level = '032212303102210'.length; // 15 | ||||||
| 
 | 
 | ||||||
| var cellId = S2.fromFacePosLevel(face, position, level); | var cellId = S2.facePosLevelToId(face, position, level); | ||||||
| 
 | 
 | ||||||
| console.log(cellId); | console.log(cellId); | ||||||
| ``` | ``` | ||||||
| @ -83,7 +203,16 @@ Example '9749618446378729472' becomes '4/032212303102210' | |||||||
| 
 | 
 | ||||||
| var cellId = '9749618446378729472'; | var cellId = '9749618446378729472'; | ||||||
| 
 | 
 | ||||||
| var hilbertQuadkey = S2.toHilbertQuadkey(cellId); | var hilbertQuadkey = S2.idToKey(cellId); | ||||||
| 
 | 
 | ||||||
| console.log(hilbertQuadkey); | console.log(hilbertQuadkey); | ||||||
| ``` | ``` | ||||||
|  | 
 | ||||||
|  | Convert Key and Id to LatLng | ||||||
|  | --------------------- | ||||||
|  | 
 | ||||||
|  | ```javascript | ||||||
|  | var latlng = S2.keyToLatLng('4/032212303102210'); | ||||||
|  | 
 | ||||||
|  | var latlng = S2.idToLatLng('9749618446378729472'); | ||||||
|  | ``` | ||||||
|  | |||||||
| @ -34,5 +34,6 @@ | |||||||
|     "bower_components", |     "bower_components", | ||||||
|     "test", |     "test", | ||||||
|     "tests" |     "tests" | ||||||
|   ] |   ], | ||||||
|  |   "version": "1.2.9" | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								package.json
									
									
									
									
									
								
							| @ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "s2-geometry", |   "name": "s2-geometry", | ||||||
|   "version": "1.2.5", |   "version": "1.2.10", | ||||||
|   "description": "A pure JavaScript/ES5.1 port of Google/Niantic's S2 Geometry library (used by Ingress, Pokemon GO)", |   "description": "A pure JavaScript/ES5.1 port of Google/Niantic's S2 Geometry library (used by Ingress, Pokemon GO)", | ||||||
|   "main": "src/s2geometry.js", |   "main": "src/s2geometry.js", | ||||||
|   "scripts": { |   "scripts": { | ||||||
| @ -8,7 +8,7 @@ | |||||||
|   }, |   }, | ||||||
|   "repository": { |   "repository": { | ||||||
|     "type": "git", |     "type": "git", | ||||||
|     "url": "git+https://github.com/Daplie/s2-geometry.js.git" |     "url": "git+https://git.coolaj86.com/coolaj86/s2-geometry.js.git" | ||||||
|   }, |   }, | ||||||
|   "keywords": [ |   "keywords": [ | ||||||
|     "s2", |     "s2", | ||||||
| @ -27,12 +27,12 @@ | |||||||
|     "lat", |     "lat", | ||||||
|     "lng" |     "lng" | ||||||
|   ], |   ], | ||||||
|   "author": "AJ ONeal <aj@daplie.com> (https://coolaj86.com/)", |   "author": "AJ ONeal <coolaj86@gmail.com> (https://coolaj86.com/)", | ||||||
|   "license": "ISC", |   "license": "(MIT or Apache-2 or ISC)", | ||||||
|   "bugs": { |   "bugs": { | ||||||
|     "url": "https://github.com/Daplie/s2-geometry.js/issues" |     "url": "https://git.coolaj86.com/coolaj86/s2-geometry.js/issues" | ||||||
|   }, |   }, | ||||||
|   "homepage": "https://github.com/Daplie/s2-geometry.js#readme", |   "homepage": "https://git.coolaj86.com/coolaj86/s2-geometry.js#readme", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "long": "^3.2.0" |     "long": "^3.2.0" | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -22,10 +22,29 @@ | |||||||
| // - i,j: they always use 30 bits, adjusting as needed. we use 0 to (1<<level)-1 instead
 | // - i,j: they always use 30 bits, adjusting as needed. we use 0 to (1<<level)-1 instead
 | ||||||
| //        (so GetSizeIJ for a cell is always 1)
 | //        (so GetSizeIJ for a cell is always 1)
 | ||||||
| 
 | 
 | ||||||
| (function(exports) { | (function (exports) { | ||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| var S2 = exports.S2 = {}; | var S2 = exports.S2 = { L: {} }; | ||||||
|  | 
 | ||||||
|  | S2.L.LatLng = function (/*Number*/ rawLat, /*Number*/ rawLng, /*Boolean*/ noWrap) { | ||||||
|  |   var lat = parseFloat(rawLat, 10); | ||||||
|  |   var lng = parseFloat(rawLng, 10); | ||||||
|  | 
 | ||||||
|  |   if (isNaN(lat) || isNaN(lng)) { | ||||||
|  |     throw new Error('Invalid LatLng object: (' + rawLat + ', ' + rawLng + ')'); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if (noWrap !== true) { | ||||||
|  |     lat = Math.max(Math.min(lat, 90), -90);                 // clamp latitude into -90..90
 | ||||||
|  |     lng = (lng + 180) % 360 + ((lng < -180 || lng === 180) ? 180 : -180);   // wrap longtitude into -180..180
 | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return { lat: lat, lng: lng }; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | S2.L.LatLng.DEG_TO_RAD = Math.PI / 180; | ||||||
|  | S2.L.LatLng.RAD_TO_DEG = 180 / Math.PI; | ||||||
| 
 | 
 | ||||||
| /* | /* | ||||||
| S2.LatLngToXYZ = function(latLng) { | S2.LatLngToXYZ = function(latLng) { | ||||||
| @ -181,12 +200,36 @@ 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
 | // hilbert space-filling curve
 | ||||||
| // based on http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves
 | // 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
 | // note: rather then calculating the final integer hilbert position, we just return the list of quads
 | ||||||
| // this ensures no precision issues whth large orders (S3 cell IDs use up to 30), and is more
 | // this ensures no precision issues whth large orders (S3 cell IDs use up to 30), and is more
 | ||||||
| // convenient for pulling out the individual bits as needed later
 | // convenient for pulling out the individual bits as needed later
 | ||||||
| var pointToHilbertQuadList = function(x,y,order,sq) { | var pointToHilbertQuadList = function(x,y,order,face) { | ||||||
|   var hilbertMap = { |   var hilbertMap = { | ||||||
|     'a': [ [0,'d'], [1,'a'], [3,'b'], [2,'a'] ], |     'a': [ [0,'d'], [1,'a'], [3,'b'], [2,'a'] ], | ||||||
|     'b': [ [2,'b'], [1,'b'], [3,'a'], [0,'c'] ], |     'b': [ [2,'b'], [1,'b'], [3,'a'], [0,'c'] ], | ||||||
| @ -194,7 +237,10 @@ var pointToHilbertQuadList = function(x,y,order,sq) { | |||||||
|     'd': [ [0,'a'], [3,'c'], [1,'d'], [2,'d'] ] |     'd': [ [0,'a'], [3,'c'], [1,'d'], [2,'d'] ] | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   var currentSquare=sq||'a'; |   if ('number' !== typeof face) { | ||||||
|  |     console.warn(new Error("called pointToHilbertQuadList without face value, defaulting to '0'").stack); | ||||||
|  |   } | ||||||
|  |   var currentSquare = (face % 2) ? 'd' : 'a'; | ||||||
|   var positions = []; |   var positions = []; | ||||||
| 
 | 
 | ||||||
|   for (var i=order-1; i>=0; i--) { |   for (var i=order-1; i>=0; i--) { | ||||||
| @ -218,9 +264,59 @@ var pointToHilbertQuadList = function(x,y,order,sq) { | |||||||
| 
 | 
 | ||||||
| S2.S2Cell = function(){}; | 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 | ||||||
|  |   }; | ||||||
|  |   var i; | ||||||
|  |   var level; | ||||||
|  |   var bit; | ||||||
|  |   var rx, ry; | ||||||
|  |   var val; | ||||||
|  | 
 | ||||||
|  | 	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') { | ||||||
|  | 			rx = 1; | ||||||
|  | 			ry = 1; | ||||||
|  | 		} | ||||||
|  | 		else if (bit === '3') { | ||||||
|  | 			rx = 1; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		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
 | //static method to construct
 | ||||||
| S2.S2Cell.FromLatLng = function(latLng, level) { | S2.S2Cell.FromLatLng = function(latLng, level) { | ||||||
|   if (!latLng.lat || !latLng.lng) { |   if ((!latLng.lat && latLng.lat !== 0) || (!latLng.lng && latLng.lng !== 0)) { | ||||||
|     throw new Error("Pass { lat: lat, lng: lng } to S2.S2Cell.FromLatLng"); |     throw new Error("Pass { lat: lat, lng: lng } to S2.S2Cell.FromLatLng"); | ||||||
|   } |   } | ||||||
|   var xyz = S2.LatLngToXYZ(latLng); |   var xyz = S2.LatLngToXYZ(latLng); | ||||||
| @ -232,6 +328,7 @@ S2.S2Cell.FromLatLng = function(latLng, level) { | |||||||
| 
 | 
 | ||||||
|   return S2.S2Cell.FromFaceIJ (faceuv[0], ij, level); |   return S2.S2Cell.FromFaceIJ (faceuv[0], ij, level); | ||||||
| }; | }; | ||||||
|  | 
 | ||||||
| /* | /* | ||||||
| S2.faceIjLevelToXyz = function (face, ij, level) { | S2.faceIjLevelToXyz = function (face, ij, level) { | ||||||
|   var st = S2.IJToST(ij, level, [0.5, 0.5]); |   var st = S2.IJToST(ij, level, [0.5, 0.5]); | ||||||
| @ -286,36 +383,21 @@ S2.S2Cell.prototype.getCornerLatLngs = function() { | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| S2.S2Cell.prototype.getFaceAndQuads = function () { | S2.S2Cell.prototype.getFaceAndQuads = function () { | ||||||
|   var sq; |   var quads = pointToHilbertQuadList(this.ij[0], this.ij[1], this.level, this.face); | ||||||
| 
 |  | ||||||
|   switch(this.face) { |  | ||||||
|     case 0: |  | ||||||
|       /* fallthru */ |  | ||||||
|     case 2: |  | ||||||
|       /* fallthru */ |  | ||||||
|     case 4: |  | ||||||
|       sq = 'a'; |  | ||||||
|       break; |  | ||||||
| 
 |  | ||||||
|     case 1: |  | ||||||
|       /* fallthru */ |  | ||||||
|     case 3: |  | ||||||
|       /* fallthru */ |  | ||||||
|     case 5: |  | ||||||
|       sq = 'd'; |  | ||||||
|       break; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   var quads = pointToHilbertQuadList(this.ij[0], this.ij[1], this.level, sq); |  | ||||||
| 
 | 
 | ||||||
|   return [this.face,quads]; |   return [this.face,quads]; | ||||||
| }; | }; | ||||||
| S2.S2Cell.prototype.toHilbertQuadkey = function () { | S2.S2Cell.prototype.toHilbertQuadkey = function () { | ||||||
|   var quads = pointToHilbertQuadList(this.ij[0], this.ij[1], this.level); |   var quads = pointToHilbertQuadList(this.ij[0], this.ij[1], this.level, this.face); | ||||||
| 
 | 
 | ||||||
|   return this.face.toString(10) + '/' + quads.join(''); |   return this.face.toString(10) + '/' + quads.join(''); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | S2.latLngToNeighborKeys = S2.S2Cell.latLngToNeighborKeys = function (lat, lng, level) { | ||||||
|  |   return S2.S2Cell.FromLatLng({ lat: lat, lng: lng }, level).getNeighbors().map(function (cell) { | ||||||
|  |     return cell.toHilbertQuadkey(); | ||||||
|  |   }); | ||||||
|  | }; | ||||||
| S2.S2Cell.prototype.getNeighbors = function() { | S2.S2Cell.prototype.getNeighbors = function() { | ||||||
| 
 | 
 | ||||||
|   var fromFaceIJWrap = function(face,ij,level) { |   var fromFaceIJWrap = function(face,ij,level) { | ||||||
| @ -362,7 +444,7 @@ S2.FACE_BITS = 3; | |||||||
| S2.MAX_LEVEL = 30; | S2.MAX_LEVEL = 30; | ||||||
| S2.POS_BITS = (2 * S2.MAX_LEVEL) + 1; // 61 (60 bits of data, 1 bit lsb marker)
 | S2.POS_BITS = (2 * S2.MAX_LEVEL) + 1; // 61 (60 bits of data, 1 bit lsb marker)
 | ||||||
| 
 | 
 | ||||||
| S2.fromFacePosLevel = function (faceN, posS, levelN) { | S2.facePosLevelToId = S2.S2Cell.facePosLevelToId = S2.fromFacePosLevel = function (faceN, posS, levelN) { | ||||||
|   var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long'); |   var Long = exports.dcodeIO && exports.dcodeIO.Long || require('long'); | ||||||
|   var faceB; |   var faceB; | ||||||
|   var posB; |   var posB; | ||||||
| @ -398,13 +480,19 @@ S2.fromFacePosLevel = function (faceN, posS, levelN) { | |||||||
|   return Long.fromString(bin, true, 2).toString(10); |   return Long.fromString(bin, true, 2).toString(10); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| S2.toId = S2.toCellId = S2.fromKey = function (key) { | S2.keyToId = S2.S2Cell.keyToId | ||||||
|  | = S2.toId = S2.toCellId = S2.fromKey | ||||||
|  | = function (key) { | ||||||
|   var parts = key.split('/'); |   var parts = key.split('/'); | ||||||
| 
 | 
 | ||||||
|   return S2.fromFacePosLevel(parts[0], parts[1], parts[1].length); |   return S2.fromFacePosLevel(parts[0], parts[1], parts[1].length); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| S2.toKey = S2.fromId = S2.fromCellId = S2.toHilbertQuadkey = function (idS) { | S2.idToKey = S2.S2Cell.idToKey | ||||||
|  | = S2.S2Cell.toKey = S2.toKey | ||||||
|  | = S2.fromId = S2.fromCellId | ||||||
|  | = S2.S2Cell.toHilbertQuadkey  = 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); | ||||||
| 
 | 
 | ||||||
| @ -431,7 +519,21 @@ S2.toKey = S2.fromId = S2.fromCellId = S2.toHilbertQuadkey = function (idS) { | |||||||
|   return faceS + '/' + posS; |   return faceS + '/' + posS; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| S2.latLngToKey = S2.latLngToQuadkey = function (lat, lng, level) { | 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
 |   // TODO
 | ||||||
|   //
 |   //
 | ||||||
|   // S2.idToLatLng(id)
 |   // S2.idToLatLng(id)
 | ||||||
| @ -481,45 +583,12 @@ S2.stepKey = function (key, num) { | |||||||
|   return faceS + '/' + otherS; |   return faceS + '/' + otherS; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| S2.prevKey = function (key) { | S2.S2Cell.prevKey = S2.prevKey = function (key) { | ||||||
|   return S2.stepKey(key, -1); |   return S2.stepKey(key, -1); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| S2.nextKey = function (key) { | S2.S2Cell.nextKey = S2.nextKey = function (key) { | ||||||
|   return S2.stepKey(key, 1); |   return S2.stepKey(key, 1); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| })('undefined' !== typeof window ? window : module.exports); | })('undefined' !== typeof module ? module.exports : window); | ||||||
| 
 |  | ||||||
| (function (exports) { |  | ||||||
| 'use strict'; |  | ||||||
| 
 |  | ||||||
|   // Adapted from Leafletjs https://searchcode.com/codesearch/view/42525008/
 |  | ||||||
| 
 |  | ||||||
|   var L = {}; |  | ||||||
|   var S2 = exports.S2; |  | ||||||
| 
 |  | ||||||
|   if (!exports.L) { |  | ||||||
|     exports.L = L; |  | ||||||
|   } |  | ||||||
|   S2.L = L; |  | ||||||
| 
 |  | ||||||
|   L.LatLng = function (/*Number*/ rawLat, /*Number*/ rawLng, /*Boolean*/ noWrap) { |  | ||||||
|     var lat = parseFloat(rawLat, 10); |  | ||||||
|     var lng = parseFloat(rawLng, 10); |  | ||||||
| 
 |  | ||||||
|     if (isNaN(lat) || isNaN(lng)) { |  | ||||||
|       throw new Error('Invalid LatLng object: (' + rawLat + ', ' + rawLng + ')'); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (noWrap !== true) { |  | ||||||
|       lat = Math.max(Math.min(lat, 90), -90);                 // clamp latitude into -90..90
 |  | ||||||
|       lng = (lng + 180) % 360 + ((lng < -180 || lng === 180) ? 180 : -180);   // wrap longtitude into -180..180
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return { lat: lat, lng: lng }; |  | ||||||
|   }; |  | ||||||
| 
 |  | ||||||
|   L.LatLng.DEG_TO_RAD = Math.PI / 180; |  | ||||||
|   L.LatLng.RAD_TO_DEG = 180 / Math.PI; |  | ||||||
| })('undefined' !== typeof window ? window : module.exports); |  | ||||||
|  | |||||||
| @ -17,17 +17,36 @@ var tests = [ | |||||||
| , [ -124.61538461538463, -69.23076923076924 ]   // face 5
 | , [ -124.61538461538463, -69.23076923076924 ]   // face 5
 | ||||||
| ]; | ]; | ||||||
| 
 | 
 | ||||||
| tests.forEach(function (pair, i) { | var tests = [ | ||||||
|  |   [ -3.9832738, 12.6825449,   'The Congo          (Africa)' ] | ||||||
|  | , [ 19.0827696, 72.7407752,   'Mumbai, India      (Asia)' ] | ||||||
|  | , [ 68.5207533, -74.9563282,  'Greenland          (North Pole)' ] | ||||||
|  | , [ -1.573289, -158.957890,   'The Pacific Ocean  (nowhere)' ] | ||||||
|  | , [ 40.2573137, -111.7091177, 'Provo, UT, USA     (Americas)' ] | ||||||
|  | , [ -46.362972,-73.7431064,   'Antarctica         (South Pole)' ] | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | var bugReports = [ | ||||||
|  |   // https://github.com/jonatkins/s2-geometry-javascript/issues/12
 | ||||||
|  |   [ -6.120097, 106.846511, '@Skeec' ] | ||||||
|  |   // https://github.com/coolaj86/s2-geometry-javascript/issues/8#issuecomment-237204759
 | ||||||
|  | , [ -33.87347601637759, 151.1954084522501 ] | ||||||
|  |   // https://github.com/Daplie/s2-geometry.js/issues/1
 | ||||||
|  | , [ 45.74528835847731, 12.5516625, '@vekexasia' ] | ||||||
|  | ]; | ||||||
|  | 
 | ||||||
|  | tests.concat(bugReports).forEach(function (pair, i) { | ||||||
|   var lat = pair[0]; |   var lat = pair[0]; | ||||||
|   var lng = pair[1]; |   var lng = pair[1]; | ||||||
|  |   var comment = pair[2] && ('(' + pair[2] + ')') || ''; | ||||||
| 
 | 
 | ||||||
|   console.log(''); |   console.log(''); | ||||||
|   console.log(''); |   console.log(''); | ||||||
|   console.log('FACE', i); |  | ||||||
| 
 | 
 | ||||||
|   console.log(''); |   if (i < 6) { | ||||||
|   console.log('Lat/Lng'); |     console.log('FACE', i); | ||||||
|   console.log('=', lat + ',' + lng); |   } | ||||||
|  |   console.log('Lat/Lng', '=', lat + ',' + lng, comment); | ||||||
| 
 | 
 | ||||||
|   //
 |   //
 | ||||||
|   // Lat / Lng to XYZ
 |   // Lat / Lng to XYZ
 | ||||||
| @ -54,8 +73,7 @@ tests.forEach(function (pair, i) { | |||||||
|   var nKey = nCell.toString(); |   var nKey = nCell.toString(); | ||||||
|   var jQuad = jCell.getFaceAndQuads(); |   var jQuad = jCell.getFaceAndQuads(); | ||||||
|   var jKey = jQuad[0] + '/' + jQuad[1].join(''); |   var jKey = jQuad[0] + '/' + jQuad[1].join(''); | ||||||
|   console.log(''); |  | ||||||
|   console.log('Quadkey'); |   console.log('Quadkey'); | ||||||
|   console.log('=', nKey); |   console.log('=', nKey); | ||||||
|   console.log('j', jKey); |   console.log('j', jKey, "(" + jS2.toId(jKey) + ")"); | ||||||
| }); | }); | ||||||
|  | |||||||
							
								
								
									
										32
									
								
								tests/exhaustive.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								tests/exhaustive.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var jS2 = require('../src/s2geometry.js').S2; | ||||||
|  | var nS2 = require('s2geometry-node'); | ||||||
|  | 
 | ||||||
|  | var x, y; | ||||||
|  | 
 | ||||||
|  | function checkReal(lat, lng) { | ||||||
|  |   var nS2LatLng = new nS2.S2LatLng(lat, lng).toPoint(); | ||||||
|  |   var nCell = new nS2.S2CellId(nS2LatLng).parent(15); | ||||||
|  |   var jCell = jS2.S2Cell.FromLatLng({ lat: lat, lng: lng }, 15); | ||||||
|  |   var nKey = nCell.toString(); | ||||||
|  |   var jQuad = jCell.getFaceAndQuads(); | ||||||
|  |   var jKey = jQuad[0] + '/' + jQuad[1].join(''); | ||||||
|  | 
 | ||||||
|  |   if (nKey !== jKey) { | ||||||
|  |     console.log(''); | ||||||
|  |     console.log('Quadkey'); | ||||||
|  |     console.log('=', nKey); | ||||||
|  |     console.log('j', jKey); | ||||||
|  |     throw new Error("values didn't match expected"); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | console.log('Exhaustive check of about 518,400 random lat,lng coordinates of the earth (about every 0.5°)'); | ||||||
|  | console.log('(this will take several seconds)'); | ||||||
|  | for (x = -180; x <= 180; x += (0 + Math.random())) { | ||||||
|  |   for (y = -180; y <= 180; y += (0 + Math.random())) { | ||||||
|  |     checkReal(x, y); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | console.log('PASS'); | ||||||
							
								
								
									
										2053
									
								
								tests/generated-locations.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2053
									
								
								tests/generated-locations.json
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										36
									
								
								tests/hilbert-to-cell.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								tests/hilbert-to-cell.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | 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); | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								tests/js-vs-go.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								tests/js-vs-go.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var tests = require('./generated-locations.json'); | ||||||
|  | var jS2 = require('../src/s2geometry.js').S2; | ||||||
|  | 
 | ||||||
|  | function checkReal(loc) { | ||||||
|  |   var jCell = jS2.S2Cell.FromLatLng({ lat: loc.lat, lng: loc.lng }, 15); | ||||||
|  |   var jQuad = jCell.getFaceAndQuads(); | ||||||
|  |   var jKey = jQuad[0] + '/' + jQuad[1].join(''); | ||||||
|  | 
 | ||||||
|  |   if (loc.quadkey !== jKey) { | ||||||
|  |     loc.badFace = jCell.face; | ||||||
|  |     loc.badI = jCell.ij[0]; | ||||||
|  |     loc.badJ = jCell.ij[1]; | ||||||
|  |     loc.badQuad = jKey; | ||||||
|  |     loc.badId = jS2.toId(jKey); | ||||||
|  |     console.log(JSON.stringify(loc, null, '  ') + ','); | ||||||
|  |     console.log(''); | ||||||
|  |     console.log('Lat/Lng:', loc.lat, loc.lng); | ||||||
|  |     console.log(''); | ||||||
|  |     console.log('I, J:'); | ||||||
|  |     console.log('=', loc.i, loc.j); | ||||||
|  |     console.log('j', jCell.ij.join(', ')); | ||||||
|  |     console.log(''); | ||||||
|  |     console.log('Quadkey'); | ||||||
|  |     console.log('=', loc.quadkey); | ||||||
|  |     console.log('j', jKey); | ||||||
|  |     throw new Error("values didn't match expected"); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | tests.forEach(checkReal); | ||||||
|  | console.log('PASS'); | ||||||
							
								
								
									
										48
									
								
								tests/key-id-to-latlng.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								tests/key-id-to-latlng.js
									
									
									
									
									
										Normal file
									
								
							| @ -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'); | ||||||
| @ -1,4 +1,4 @@ | |||||||
| var S2 = require('s2geometry-node'); | var s2n = require('s2geometry-node'); | ||||||
| 
 | 
 | ||||||
| // Provo, UT (Center St)
 | // Provo, UT (Center St)
 | ||||||
| //var lat = 40.2574448;
 | //var lat = 40.2574448;
 | ||||||
| @ -16,8 +16,8 @@ var S2 = require('s2geometry-node'); | |||||||
| var lat = -43.5261282; | var lat = -43.5261282; | ||||||
| var lng = 172.6561085; | var lng = 172.6561085; | ||||||
| 
 | 
 | ||||||
| var s2latlng = new S2.S2LatLng(lat, lng); | var s2nlatlng = new s2n.S2LatLng(lat, lng); | ||||||
| var cellId = new S2.S2CellId(s2latlng).parent(15); | var cellId = new s2n.S2CellId(s2nlatlng).parent(15); | ||||||
| var cell; | var cell; | ||||||
| 
 | 
 | ||||||
| var walk = []; | var walk = []; | ||||||
| @ -47,6 +47,6 @@ walk.forEach(function (parts) { | |||||||
|   var i = parts[0]; |   var i = parts[0]; | ||||||
|   var cellId = parts[1]; |   var cellId = parts[1]; | ||||||
| 
 | 
 | ||||||
|   cell = new S2.S2Cell(cellId); |   cell = new s2n.S2Cell(cellId); | ||||||
|   console.log(i, cell.face(), cellId.id(), cellId.toString(), cellId.toLatLng().toString(), cellId.level()); |   console.log(i, cell.face(), cellId.id(), cellId.toString(), cellId.toLatLng().toString(), cellId.level()); | ||||||
| }); | }); | ||||||
|  | |||||||
							
								
								
									
										51
									
								
								tests/simple.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								tests/simple.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | |||||||
|  | 'use strict'; | ||||||
|  | 
 | ||||||
|  | var S2 = require('../src/s2geometry.js').S2; | ||||||
|  | 
 | ||||||
|  | var lat = 40.2574448; | ||||||
|  | var lng = -111.7089464; | ||||||
|  | var level = 15; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // Convert from Lat / Lng
 | ||||||
|  | //
 | ||||||
|  | var key = S2.latLngToKey(lat, lng, level); | ||||||
|  | console.log(key); | ||||||
|  | // '4/032212303102210'
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // Convert between Hilbert Curve Quadtree Key and S2 Cell Id
 | ||||||
|  | //
 | ||||||
|  | var id = S2.keyToId(key); | ||||||
|  | console.log(id); | ||||||
|  | // '9749618446378729472'
 | ||||||
|  | 
 | ||||||
|  | var key = S2.idToKey(id); | ||||||
|  | console.log(key); | ||||||
|  | // '9749618446378729472'
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // Neighbors
 | ||||||
|  | //
 | ||||||
|  | var neighbors = S2.latLngToNeighborKeys(lat, lng, level); | ||||||
|  | console.log(neighbors); | ||||||
|  | // [ keyLeft, keyDown, keyRight, keyUp ]
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | //
 | ||||||
|  | // Previous, Next, and Step
 | ||||||
|  | //
 | ||||||
|  | var nextKey = S2.nextKey(key); | ||||||
|  | console.log(nextKey); | ||||||
|  | var prevKey = S2.prevKey(key); | ||||||
|  | console.log(prevKey); | ||||||
|  | 
 | ||||||
|  | var backTenKeys = S2.stepKey(key, -10); | ||||||
|  | console.log(backTenKeys); | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user