[regions] instead of trying all cells, calculate x/y from distance according to the Hilbert curve

also, refactoring to reduce duplicate code for level 4/6 cells
This commit is contained in:
fkloft 2015-02-23 13:13:03 +01:00
parent a98809ccd5
commit 7987a459eb

View File

@ -120,6 +120,31 @@ window.plugin.regions.search = function(query) {
}); });
} }
// rot and d2xy from Wikipedia
window.plugin.regions.rot = function(n, x, y, rx, ry) {
if(ry == 0) {
if(rx == 1) {
x = n-1 - x;
y = n-1 - y;
}
return [y, x];
}
return [x, y];
}
window.plugin.regions.d2xy = function(n, d) {
var rx, ry, s, t = d, xy = [0, 0];
for(s=1; s<n; s*=2) {
rx = 1 & (t/2);
ry = 1 & (t ^ rx);
xy = window.plugin.regions.rot(s, xy[0], xy[1], rx, ry);
xy[0] += s * rx;
xy[1] += s * ry;
t /= 4;
}
return xy;
}
window.plugin.regions.getSearchResult = function(match) { window.plugin.regions.getSearchResult = function(match) {
var faceId = window.plugin.regions.FACE_NAMES.indexOf(match[1]); var faceId = window.plugin.regions.FACE_NAMES.indexOf(match[1]);
var id1 = parseInt(match[2]); var id1 = parseInt(match[2]);
@ -136,63 +161,34 @@ window.plugin.regions.getSearchResult = function(match) {
var regionI = id1-1; var regionI = id1-1;
var regionJ = codeWordId; var regionJ = codeWordId;
// the final 2 bits of I and J are tricky - easiest way is to try all 16 cells given the 4 bits of I/J we have so far... var result = {}, level;
if(id2 === undefined) { // level 4 cell if(id2 === undefined) {
// as in the name-construction above, for odd numbered faces, the I and J need swapping result.description = 'Regional score cells (cluster of 16 cells)';
var cell = (faceId == 1 || faceId == 3 || faceId == 5) ? result.icon = 'data:image/svg+xml;base64,'+btoa('@@INCLUDESTRING:images/icon-cell.svg@@'.replace(/orange/, 'gold'));
S2.S2Cell.FromFaceIJ(faceId, [regionJ,regionI], 4) : level = 4;
S2.S2Cell.FromFaceIJ(faceId, [regionI,regionJ], 4) ; } else {
var title = window.plugin.regions.FACE_NAMES[faceId] + zeroPad(id1,2) + '-' + window.plugin.regions.CODE_WORDS[codeWordId]; result.description = 'Regional score cell';
result.icon = 'data:image/svg+xml;base64,'+btoa('@@INCLUDESTRING:images/icon-cell.svg@@');
level = 6;
var corners = cell.getCornerLatLngs(); var xy = window.plugin.regions.d2xy(4, id2);
var layer = L.geodesicPolygon(corners, { fill: false, color: 'red', clickable: false }); regionI = (regionI << 2) + xy[0];
regionJ = (regionJ << 2) + xy[1];
var bounds = L.latLngBounds(corners);
return {
title: title,
description: 'Regional score cells (cluster of 16 cells)',
icon: 'data:image/svg+xml;base64,'+btoa('@@INCLUDESTRING:images/icon-cell.svg@@'.replace(/orange/, 'gold')),
bounds: bounds,
layer: layer
};
} }
for(var i=0; i<4; i++) { // as in the name-construction above, for odd numbered faces, the I and J need swapping
for(var j=0; j<4; j++) { var cell = (faceId % 2 == 1)
? S2.S2Cell.FromFaceIJ(faceId, [regionJ,regionI], level)
: S2.S2Cell.FromFaceIJ(faceId, [regionI,regionJ], level);
var cell = S2.S2Cell.FromFaceIJ(faceId, [regionI*4+i,regionJ*4+j], 6); var corners = cell.getCornerLatLngs();
var facequads = cell.getFaceAndQuads(); result.title = window.plugin.regions.regionName(cell);
var number = facequads[1][4]*4+facequads[1][5]; result.layer = L.geodesicPolygon(corners, { fill: false, color: 'red', clickable: false });
result.bounds = L.latLngBounds(corners);
if (number == id2) { return result;
// we have a match!
// as in the name-construction above, for odd numbered faces, the I and J need swapping
if (cell.face == 1 || cell.face == 3 || cell.face == 5) {
cell = S2.S2Cell.FromFaceIJ ( cell.face, [cell.ij[1], cell.ij[0]], cell.level );
}
var title = window.plugin.regions.FACE_NAMES[faceId]+zeroPad(id1,2)+'-'+window.plugin.regions.CODE_WORDS[codeWordId]+'-'+zeroPad(id2,2);
var corners = cell.getCornerLatLngs();
var layer = L.geodesicPolygon(corners, { fill: false, color: 'red', clickable: false });
var bounds = L.latLngBounds(corners);
return {
title: title,
description: 'Regional score cell',
icon: 'data:image/svg+xml;base64,'+btoa('@@INCLUDESTRING:images/icon-cell.svg@@'),
bounds: bounds,
layer: layer
};
}
}
}
console.error('thought we had a region cell search match - but failed to find it!');
} }
window.plugin.regions.update = function() { window.plugin.regions.update = function() {