[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:
parent
a98809ccd5
commit
7987a459eb
@ -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) {
|
||||
var faceId = window.plugin.regions.FACE_NAMES.indexOf(match[1]);
|
||||
var id1 = parseInt(match[2]);
|
||||
@ -136,63 +161,34 @@ window.plugin.regions.getSearchResult = function(match) {
|
||||
var regionI = id1-1;
|
||||
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
|
||||
// as in the name-construction above, for odd numbered faces, the I and J need swapping
|
||||
var cell = (faceId == 1 || faceId == 3 || faceId == 5) ?
|
||||
S2.S2Cell.FromFaceIJ(faceId, [regionJ,regionI], 4) :
|
||||
S2.S2Cell.FromFaceIJ(faceId, [regionI,regionJ], 4) ;
|
||||
var title = window.plugin.regions.FACE_NAMES[faceId] + zeroPad(id1,2) + '-' + window.plugin.regions.CODE_WORDS[codeWordId];
|
||||
if(id2 === undefined) {
|
||||
result.description = 'Regional score cells (cluster of 16 cells)';
|
||||
result.icon = 'data:image/svg+xml;base64,'+btoa('@@INCLUDESTRING:images/icon-cell.svg@@'.replace(/orange/, 'gold'));
|
||||
level = 4;
|
||||
} else {
|
||||
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 layer = L.geodesicPolygon(corners, { fill: false, color: 'red', clickable: false });
|
||||
|
||||
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
|
||||
};
|
||||
var xy = window.plugin.regions.d2xy(4, id2);
|
||||
regionI = (regionI << 2) + xy[0];
|
||||
regionJ = (regionJ << 2) + xy[1];
|
||||
}
|
||||
|
||||
for(var i=0; i<4; i++) {
|
||||
for(var j=0; j<4; j++) {
|
||||
|
||||
var cell = S2.S2Cell.FromFaceIJ(faceId, [regionI*4+i,regionJ*4+j], 6);
|
||||
|
||||
var facequads = cell.getFaceAndQuads();
|
||||
var number = facequads[1][4]*4+facequads[1][5];
|
||||
|
||||
if (number == id2) {
|
||||
// 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 cell = (faceId % 2 == 1)
|
||||
? S2.S2Cell.FromFaceIJ(faceId, [regionJ,regionI], level)
|
||||
: S2.S2Cell.FromFaceIJ(faceId, [regionI,regionJ], 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);
|
||||
result.title = window.plugin.regions.regionName(cell);
|
||||
result.layer = L.geodesicPolygon(corners, { fill: false, color: 'red', clickable: false });
|
||||
result.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!');
|
||||
return result;
|
||||
}
|
||||
|
||||
window.plugin.regions.update = function() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user