From 3a2a2e452d4df6ab5975f59b10418ddaa243d8c5 Mon Sep 17 00:00:00 2001 From: Jon Atkins Date: Mon, 20 Jan 2014 08:24:01 +0000 Subject: [PATCH] more s2geometry code we have enough now to calculate the cell containing a lat/lng, and to calculate the lat/lng for a cell center/boundary not certain the hibbert curve stuff is right yet... --- external/s2geometry.js | 201 +++++++++++++++++++++++++++++++++++------ 1 file changed, 174 insertions(+), 27 deletions(-) diff --git a/external/s2geometry.js b/external/s2geometry.js index 78f106f8..d7fc661d 100644 --- a/external/s2geometry.js +++ b/external/s2geometry.js @@ -10,18 +10,24 @@ // to convert a lat,lng into a cell id: // - convert lat,lng to x,y,z // - convert x,y,z into face,u,v -// - u,v scaled to s,t (i,j?) with quadratic formula -// - s,t (i,j?) converted to a position along a Hubbert space-filling curve +// - u,v scaled to s,t with quadratic formula +// - s,t converted to integer i,j offsets +// - i,j converted to a position along a Hubbert space-filling curve // - combine face,position to get the cell id - +//NOTE: compared to the google S2 geometry library, we vary from their code in the following ways +// - cell IDs: they combine face and the hilbert curve position into a single 64 bit number. this gives efficient space +// and speed. javascript doesn't have appropriate data types, and speed is not cricical, so we use +// as [face,[bitpair,bitpair,...]] instead +// - i,j: they always use 30 bits, adjusting as needed. we use 0 to (1< temp[2]) { return 0; } else { - return 1; + return 2; } } else { if (temp[1] > temp[2]) { @@ -67,25 +82,10 @@ var faceXYZToUV = function(face,xyz) { return [u,v]; } -var singleSTtoUV = function(st) { - - if (st >= 0.5) { - return (1/3.0) * (4*st*st - 1); - } else { - return (1/3.0) * (1 - (4*(1-st)*(1-st))); - } -} - -var singleUVtoST = function(uv) { - if (uv >= 0) { - return 0.5 * Math.sqrt (1 + 3*uv); - } else { - return 1 - 0.5 * Math.sqrt (1 - 3*uv); - } -} -S2.XYZToFaceUV = function(xyz) { + +var XYZToFaceUV = function(xyz) { var face = largestAbsComponent(xyz); if (xyz[face] < 0) { @@ -97,15 +97,162 @@ S2.XYZToFaceUV = function(xyz) { return [face, uv]; }; -S2.UVToST = function(uv) { - return [singleUVToST(uv[0]), singleUVToST(uv[1])]; +var FaceUVToXYZ = function(face,uv) { + var u = uv[0]; + var v = uv[1]; + + switch (face) { + case 0: return [ 1, u, v]; + case 1: return [-u, 1, v]; + case 2: return [-u,-v, 1]; + case 3: return [-1,-v,-u]; + case 4: return [ v,-1,-u]; + case 5: return [ v, u,-1]; + default: throw {error: 'Invalid face'}; + } }; -var singleSTtoIJ = function(st) { - var ij = Math.floor(st * kMaxSize); - return Math.max(0, Math.min(kMaxSize-1, ij)); +var STToUV = function(st) { + var singleSTtoUV = function(st) { + if (st >= 0.5) { + return (1/3.0) * (4*st*st - 1); + } else { + return (1/3.0) * (1 - (4*(1-st)*(1-st))); + } + } + + return [singleSTtoUV(st[0]), singleSTtoUV(st[1])]; }; + +var UVToST = function(uv) { + var singleUVtoST = function(uv) { + if (uv >= 0) { + return 0.5 * Math.sqrt (1 + 3*uv); + } else { + return 1 - 0.5 * Math.sqrt (1 - 3*uv); + } + } + + return [singleUVtoST(uv[0]), singleUVtoST(uv[1])]; +}; + + +var STToIJ = function(st,order) { + var maxSize = (1<=0; i--) { + + var mask = 1<