Update rtree to use new extent structure
This commit is contained in:
+40
-40
@@ -84,10 +84,10 @@ ol.structs.RTree.recalculateExtent_ = function(node) {
|
|||||||
ol.extent.empty(extent);
|
ol.extent.empty(extent);
|
||||||
} else {
|
} else {
|
||||||
var firstNodeExtent = node.nodes[0].extent;
|
var firstNodeExtent = node.nodes[0].extent;
|
||||||
extent[0] = firstNodeExtent[0];
|
extent[0][0] = firstNodeExtent[0][0];
|
||||||
extent[1] = firstNodeExtent[1];
|
extent[1][0] = firstNodeExtent[1][0];
|
||||||
extent[2] = firstNodeExtent[2];
|
extent[0][1] = firstNodeExtent[0][1];
|
||||||
extent[3] = firstNodeExtent[3];
|
extent[1][1] = firstNodeExtent[1][1];
|
||||||
var i;
|
var i;
|
||||||
for (i = 1; i < n; ++i) {
|
for (i = 1; i < n; ++i) {
|
||||||
ol.extent.extend(extent, node.nodes[i].extent);
|
ol.extent.extend(extent, node.nodes[i].extent);
|
||||||
@@ -151,19 +151,19 @@ ol.structs.RTree.prototype.chooseLeafSubtree_ = function(rect, root) {
|
|||||||
}
|
}
|
||||||
// Area of new enlarged rectangle
|
// Area of new enlarged rectangle
|
||||||
var oldLRatio = ol.structs.RTree.squarifiedRatio_(
|
var oldLRatio = ol.structs.RTree.squarifiedRatio_(
|
||||||
lTree.extent[1] - lTree.extent[0],
|
lTree.extent[1][0] - lTree.extent[0][0],
|
||||||
lTree.extent[3] - lTree.extent[2],
|
lTree.extent[1][1] - lTree.extent[0][1],
|
||||||
lTree.nodes.length + 1);
|
lTree.nodes.length + 1);
|
||||||
|
|
||||||
// Enlarge rectangle to fit new rectangle
|
// Enlarge rectangle to fit new rectangle
|
||||||
var nw = (lTree.extent[1] > rect.extent[1] ?
|
var nw = (lTree.extent[1][0] > rect.extent[1][0] ?
|
||||||
lTree.extent[1] : rect.extent[1]) -
|
lTree.extent[1][0] : rect.extent[1][0]) -
|
||||||
(lTree.extent[0] < rect.extent[0] ?
|
(lTree.extent[0][0] < rect.extent[0][0] ?
|
||||||
lTree.extent[0] : rect.extent[0]);
|
lTree.extent[0][0] : rect.extent[0][0]);
|
||||||
var nh = (lTree.extent[3] > rect.extent[3] ?
|
var nh = (lTree.extent[1][1] > rect.extent[1][1] ?
|
||||||
lTree.extent[3] : rect.extent[3]) -
|
lTree.extent[1][1] : rect.extent[1][1]) -
|
||||||
(lTree.extent[2] < rect.extent[2] ?
|
(lTree.extent[0][1] < rect.extent[0][1] ?
|
||||||
lTree.extent[2] : rect.extent[2]);
|
lTree.extent[0][1] : rect.extent[0][1]);
|
||||||
|
|
||||||
// Area of new enlarged rectangle
|
// Area of new enlarged rectangle
|
||||||
var lRatio = ol.structs.RTree.squarifiedRatio_(
|
var lRatio = ol.structs.RTree.squarifiedRatio_(
|
||||||
@@ -210,7 +210,7 @@ ol.structs.RTree.prototype.insertSubtree_ = function(node, root) {
|
|||||||
// Initial insertion is special because we resize the Tree and we don't
|
// Initial insertion is special because we resize the Tree and we don't
|
||||||
// care about any overflow (seriously, how can the first object overflow?)
|
// care about any overflow (seriously, how can the first object overflow?)
|
||||||
if (root.nodes.length === 0) {
|
if (root.nodes.length === 0) {
|
||||||
root.extent = node.extent.concat();
|
root.extent = ol.extent.clone(node.extent);
|
||||||
root.nodes.push(node);
|
root.nodes.push(node);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -253,7 +253,7 @@ ol.structs.RTree.prototype.insertSubtree_ = function(node, root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bc.nodes.length <= this.maxWidth_) { // Start Resizeing Up the Tree
|
if (bc.nodes.length <= this.maxWidth_) { // Start Resizeing Up the Tree
|
||||||
workingObject = {extent: bc.extent.concat()};
|
workingObject = {extent: ol.extent.clone(bc.extent)};
|
||||||
} else { // Otherwise Split this Node
|
} else { // Otherwise Split this Node
|
||||||
// linearSplit_() returns an array containing two new nodes
|
// linearSplit_() returns an array containing two new nodes
|
||||||
// formed from the split of the previous node's overflow
|
// formed from the split of the previous node's overflow
|
||||||
@@ -269,7 +269,7 @@ ol.structs.RTree.prototype.insertSubtree_ = function(node, root) {
|
|||||||
} else { // Otherwise Do Resize
|
} else { // Otherwise Do Resize
|
||||||
//Just keep applying the new bounding rectangle to the parents..
|
//Just keep applying the new bounding rectangle to the parents..
|
||||||
ol.extent.extend(bc.extent, workingObject.extent);
|
ol.extent.extend(bc.extent, workingObject.extent);
|
||||||
workingObject = ({extent: bc.extent.concat()});
|
workingObject = ({extent: ol.extent.clone(bc.extent)});
|
||||||
}
|
}
|
||||||
} while (treeStack.length > 0);
|
} while (treeStack.length > 0);
|
||||||
};
|
};
|
||||||
@@ -308,21 +308,21 @@ ol.structs.RTree.prototype.pickLinear_ = function(nodes) {
|
|||||||
|
|
||||||
for (var i = nodes.length - 2; i >= 0; --i) {
|
for (var i = nodes.length - 2; i >= 0; --i) {
|
||||||
var l = nodes[i];
|
var l = nodes[i];
|
||||||
if (l.extent[0] > nodes[highestLowX].extent[0]) {
|
if (l.extent[0][0] > nodes[highestLowX].extent[0][0]) {
|
||||||
highestLowX = i;
|
highestLowX = i;
|
||||||
} else if (l.extent[1] < nodes[lowestHighX].extent[2]) {
|
} else if (l.extent[1][0] < nodes[lowestHighX].extent[0][1]) {
|
||||||
lowestHighX = i;
|
lowestHighX = i;
|
||||||
}
|
}
|
||||||
if (l.extent[2] > nodes[highestLowY].extent[2]) {
|
if (l.extent[0][1] > nodes[highestLowY].extent[0][1]) {
|
||||||
highestLowY = i;
|
highestLowY = i;
|
||||||
} else if (l.extent[3] < nodes[lowestHighY].extent[3]) {
|
} else if (l.extent[1][1] < nodes[lowestHighY].extent[1][1]) {
|
||||||
lowestHighY = i;
|
lowestHighY = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var dx = Math.abs(nodes[lowestHighX].extent[1] -
|
var dx = Math.abs(nodes[lowestHighX].extent[1][0] -
|
||||||
nodes[highestLowX].extent[0]);
|
nodes[highestLowX].extent[0][0]);
|
||||||
var dy = Math.abs(nodes[lowestHighY].extent[3] -
|
var dy = Math.abs(nodes[lowestHighY].extent[1][1] -
|
||||||
nodes[highestLowY].extent[2]);
|
nodes[highestLowY].extent[0][1]);
|
||||||
if (dx > dy) {
|
if (dx > dy) {
|
||||||
if (lowestHighX > highestLowX) {
|
if (lowestHighX > highestLowX) {
|
||||||
t1 = nodes.splice(lowestHighX, 1)[0];
|
t1 = nodes.splice(lowestHighX, 1)[0];
|
||||||
@@ -342,9 +342,9 @@ ol.structs.RTree.prototype.pickLinear_ = function(nodes) {
|
|||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
/** @type {ol.structs.RTreeNode} */
|
/** @type {ol.structs.RTreeNode} */
|
||||||
({extent: t1.extent.concat(), nodes: [t1]}),
|
({extent: ol.extent.clone(t1.extent), nodes: [t1]}),
|
||||||
/** @type {ol.structs.RTreeNode} */
|
/** @type {ol.structs.RTreeNode} */
|
||||||
({extent: t2.extent.concat(), nodes: [t2]})
|
({extent: ol.extent.clone(t2.extent), nodes: [t2]})
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -359,10 +359,10 @@ ol.structs.RTree.prototype.pickLinear_ = function(nodes) {
|
|||||||
*/
|
*/
|
||||||
ol.structs.RTree.prototype.pickNext_ = function(nodes, a, b) {
|
ol.structs.RTree.prototype.pickNext_ = function(nodes, a, b) {
|
||||||
// Area of new enlarged rectangle
|
// Area of new enlarged rectangle
|
||||||
var areaA = ol.structs.RTree.squarifiedRatio_(a.extent[1] - a.extent[0],
|
var areaA = ol.structs.RTree.squarifiedRatio_(a.extent[1][0] - a.extent[0][0],
|
||||||
a.extent[3] - a.extent[2], a.nodes.length + 1);
|
a.extent[1][1] - a.extent[0][1], a.nodes.length + 1);
|
||||||
var areaB = ol.structs.RTree.squarifiedRatio_(b.extent[1] - b.extent[0],
|
var areaB = ol.structs.RTree.squarifiedRatio_(b.extent[1][0] - b.extent[0][0],
|
||||||
b.extent[3] - b.extent[2], b.nodes.length + 1);
|
b.extent[1][1] - b.extent[0][1], b.nodes.length + 1);
|
||||||
var highAreaDelta;
|
var highAreaDelta;
|
||||||
var highAreaNode;
|
var highAreaNode;
|
||||||
var lowestGrowthGroup;
|
var lowestGrowthGroup;
|
||||||
@@ -371,20 +371,20 @@ ol.structs.RTree.prototype.pickNext_ = function(nodes, a, b) {
|
|||||||
var l = nodes[i];
|
var l = nodes[i];
|
||||||
|
|
||||||
var newAreaA = [
|
var newAreaA = [
|
||||||
a.extent[0] < l.extent[0] ? a.extent[0] : l.extent[0],
|
a.extent[0][0] < l.extent[0][0] ? a.extent[0][0] : l.extent[0][0],
|
||||||
a.extent[1] > l.extent[1] ? a.extent[1] : l.extent[1],
|
a.extent[1][0] > l.extent[1][0] ? a.extent[1][0] : l.extent[1][0],
|
||||||
a.extent[2] < l.extent[2] ? a.extent[2] : l.extent[2],
|
a.extent[0][1] < l.extent[0][1] ? a.extent[0][1] : l.extent[0][1],
|
||||||
a.extent[3] > l.extent[3] ? a.extent[3] : l.extent[3]
|
a.extent[1][1] > l.extent[1][1] ? a.extent[1][1] : l.extent[1][1]
|
||||||
];
|
];
|
||||||
var changeNewAreaA = Math.abs(ol.structs.RTree.squarifiedRatio_(
|
var changeNewAreaA = Math.abs(ol.structs.RTree.squarifiedRatio_(
|
||||||
newAreaA[1] - newAreaA[0],
|
newAreaA[1] - newAreaA[0],
|
||||||
newAreaA[3] - newAreaA[2], a.nodes.length + 2) - areaA);
|
newAreaA[3] - newAreaA[2], a.nodes.length + 2) - areaA);
|
||||||
|
|
||||||
var newAreaB = [
|
var newAreaB = [
|
||||||
b.extent[0] < l.extent[0] ? b.extent[0] : l.extent[0],
|
b.extent[0][0] < l.extent[0][0] ? b.extent[0][0] : l.extent[0][0],
|
||||||
b.extent[1] > l.extent[1] ? b.extent[1] : l.extent[1],
|
b.extent[1][0] > l.extent[1][0] ? b.extent[1][0] : l.extent[1][0],
|
||||||
b.extent[2] < l.extent[2] ? b.extent[2] : l.extent[2],
|
b.extent[0][1] < l.extent[0][1] ? b.extent[0][1] : l.extent[0][1],
|
||||||
b.extent[3] > l.extent[3] ? b.extent[3] : l.extent[3]
|
b.extent[1][1] > l.extent[1][1] ? b.extent[1][1] : l.extent[1][1]
|
||||||
];
|
];
|
||||||
var changeNewAreaB = Math.abs(ol.structs.RTree.squarifiedRatio_(
|
var changeNewAreaB = Math.abs(ol.structs.RTree.squarifiedRatio_(
|
||||||
newAreaB[1] - newAreaB[0], newAreaB[3] - newAreaB[2],
|
newAreaB[1] - newAreaB[0], newAreaB[3] - newAreaB[2],
|
||||||
@@ -466,7 +466,7 @@ ol.structs.RTree.prototype.removeSubtree_ = function(rect, obj, root) {
|
|||||||
|
|
||||||
/** @type {ol.structs.RTreeNode} */
|
/** @type {ol.structs.RTreeNode} */
|
||||||
var workingObject = /** @type {ol.structs.RTreeNode} */
|
var workingObject = /** @type {ol.structs.RTreeNode} */
|
||||||
({extent: rect.extent.concat(), target: obj});
|
({extent: ol.extent.clone(rect.extent), target: obj});
|
||||||
|
|
||||||
countStack.push(root.nodes.length);
|
countStack.push(root.nodes.length);
|
||||||
hitStack.push(root);
|
hitStack.push(root);
|
||||||
|
|||||||
@@ -9,29 +9,25 @@ describe('ol.structs.RTree', function() {
|
|||||||
it('can insert 1k objects', function() {
|
it('can insert 1k objects', function() {
|
||||||
var i = 1000;
|
var i = 1000;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
var bounds = new Array(4);
|
var min = [Math.random() * 10000, Math.random() * 10000];
|
||||||
bounds[0] = Math.random() * 10000;
|
var max = [min[0] + Math.random() * 500, min[1] + Math.random() * 500];
|
||||||
bounds[1] = bounds[0] + Math.random() * 500;
|
var bounds = [min, max];
|
||||||
bounds[2] = Math.random() * 10000;
|
|
||||||
bounds[3] = bounds[2] + Math.random() * 500;
|
|
||||||
rTree.insert(bounds, 'JUST A TEST OBJECT!_' + i);
|
rTree.insert(bounds, 'JUST A TEST OBJECT!_' + i);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
expect(goog.object.getCount(rTree.search([0, 10600, 0, 10600])))
|
expect(goog.object.getCount(rTree.search([[0, 0], [10600, 10600]])))
|
||||||
.to.be(1000);
|
.to.be(1000);
|
||||||
});
|
});
|
||||||
it('can insert 1k more objects', function() {
|
it('can insert 1k more objects', function() {
|
||||||
var i = 1000;
|
var i = 1000;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
var bounds = new Array(4);
|
var min = [Math.random() * 10000, Math.random() * 10000];
|
||||||
bounds[0] = Math.random() * 10000;
|
var max = [min[0] + Math.random() * 500, min[1] + Math.random() * 500];
|
||||||
bounds[1] = bounds[0] + Math.random() * 500;
|
var bounds = [min, max];
|
||||||
bounds[2] = Math.random() * 10000;
|
|
||||||
bounds[3] = bounds[2] + Math.random() * 500;
|
|
||||||
rTree.insert(bounds, 'JUST A TEST OBJECT!_' + i);
|
rTree.insert(bounds, 'JUST A TEST OBJECT!_' + i);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
expect(goog.object.getCount(rTree.search([0, 10600, 0, 10600])))
|
expect(goog.object.getCount(rTree.search([[0, 0], [10600, 10600]])))
|
||||||
.to.be(2000);
|
.to.be(2000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -41,11 +37,10 @@ describe('ol.structs.RTree', function() {
|
|||||||
var i = 1000;
|
var i = 1000;
|
||||||
var len = 0;
|
var len = 0;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
var bounds = new Array(4);
|
var min = [-(Math.random() * 10000 + 501),
|
||||||
bounds[0] = -(Math.random() * 10000 + 501);
|
-(Math.random() * 10000 + 501)];
|
||||||
bounds[1] = bounds[0] + Math.random() * 500;
|
var max = [min[0] + Math.random() * 500, min[1] + Math.random() * 500];
|
||||||
bounds[2] = -(Math.random() * 10000 + 501);
|
var bounds = [min, max];
|
||||||
bounds[3] = bounds[2] + Math.random() * 500;
|
|
||||||
len += rTree.search(bounds).length;
|
len += rTree.search(bounds).length;
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@@ -55,11 +50,9 @@ describe('ol.structs.RTree', function() {
|
|||||||
var i = 1000;
|
var i = 1000;
|
||||||
var len = 0;
|
var len = 0;
|
||||||
while (i > 0) {
|
while (i > 0) {
|
||||||
var bounds = new Array(4);
|
var min = [Math.random() * 10000, Math.random() * 10000];
|
||||||
bounds[0] = Math.random() * 10000;
|
var max = [min[0] + Math.random() * 500, min[1] + Math.random() * 500];
|
||||||
bounds[1] = bounds[0] + Math.random() * 500;
|
var bounds = [min, max];
|
||||||
bounds[2] = Math.random() * 10000;
|
|
||||||
bounds[3] = bounds[2] + Math.random() * 500;
|
|
||||||
len += rTree.search(bounds).length;
|
len += rTree.search(bounds).length;
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
@@ -70,12 +63,12 @@ describe('ol.structs.RTree', function() {
|
|||||||
describe('deletion', function() {
|
describe('deletion', function() {
|
||||||
var len = 0;
|
var len = 0;
|
||||||
it('can delete half the RTree', function() {
|
it('can delete half the RTree', function() {
|
||||||
var bounds = [5000, 10500, 0, 10500];
|
var bounds = [[5000, 0], [10500, 10500]];
|
||||||
len += rTree.remove(bounds).length;
|
len += rTree.remove(bounds).length;
|
||||||
expect(len).to.not.be(0);
|
expect(len).to.not.be(0);
|
||||||
});
|
});
|
||||||
it('can delete the other half of the RTree', function() {
|
it('can delete the other half of the RTree', function() {
|
||||||
var bounds = [0, 5000, 0, 10500];
|
var bounds = [[0, 0], [5000, 10500]];
|
||||||
len += rTree.remove(bounds).length;
|
len += rTree.remove(bounds).length;
|
||||||
expect(len).to.be(2000);
|
expect(len).to.be(2000);
|
||||||
});
|
});
|
||||||
@@ -84,42 +77,42 @@ describe('ol.structs.RTree', function() {
|
|||||||
describe('result plausibility and structure', function() {
|
describe('result plausibility and structure', function() {
|
||||||
|
|
||||||
it('filters by rectangle', function() {
|
it('filters by rectangle', function() {
|
||||||
rTree.insert([0, 1, 0, 1], 1);
|
rTree.insert([[0, 0], [1, 1]], 1);
|
||||||
rTree.insert([1, 4, 1, 4], 2);
|
rTree.insert([[1, 1], [4, 4]], 2);
|
||||||
rTree.insert([2, 3, 2, 3], 3);
|
rTree.insert([[2, 2], [3, 3]], 3);
|
||||||
rTree.insert([-5, -4, -5, -4], 4);
|
rTree.insert([[-5, -5], [-4, -4]], 4);
|
||||||
rTree.insert([-4, -1, -4, -1], 5);
|
rTree.insert([[-4, -4], [-1, -1]], 5);
|
||||||
rTree.insert([-3, -2, -3, -2], 6);
|
rTree.insert([[-3, -3], [-2, -2]], 6);
|
||||||
|
|
||||||
var result;
|
var result;
|
||||||
result = goog.object.getValues(rTree.search([2, 3, 2, 3]));
|
result = goog.object.getValues(rTree.search([[2, 2], [3, 3]]));
|
||||||
expect(result).to.contain(2);
|
expect(result).to.contain(2);
|
||||||
expect(result).to.contain(3);
|
expect(result).to.contain(3);
|
||||||
expect(result.length).to.be(2);
|
expect(result.length).to.be(2);
|
||||||
result = goog.object.getValues(rTree.search([-1, 2, -1, 2]));
|
result = goog.object.getValues(rTree.search([[-1, -1], [2, 2]]));
|
||||||
expect(result).to.contain(1);
|
expect(result).to.contain(1);
|
||||||
expect(result).to.contain(2);
|
expect(result).to.contain(2);
|
||||||
expect(result).to.contain(3);
|
expect(result).to.contain(3);
|
||||||
expect(result).to.contain(5);
|
expect(result).to.contain(5);
|
||||||
expect(result.length).to.be(4);
|
expect(result.length).to.be(4);
|
||||||
expect(goog.object.getCount(rTree.search([5, 6, 5, 6]))).to.be(0);
|
expect(goog.object.getCount(rTree.search([[5, 5], [6, 6]]))).to.be(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('filters by type', function() {
|
it('filters by type', function() {
|
||||||
rTree.insert([2, 3, 2, 3], 7, 'type1');
|
rTree.insert([[2, 2], [3, 3]], 7, 'type1');
|
||||||
|
|
||||||
var result;
|
var result;
|
||||||
result = rTree.search([1, 4, 2, 4], 'type1');
|
result = rTree.search([[1, 2], [4, 4]], 'type1');
|
||||||
expect(result).to.contain(7);
|
expect(result).to.contain(7);
|
||||||
expect(result.length).to.be(1);
|
expect(result.length).to.be(1);
|
||||||
result = rTree.search([1, 4, 2, 4]);
|
result = rTree.search([[1, 2], [4, 4]]);
|
||||||
expect(result.length).to.be(3);
|
expect(result.length).to.be(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can return objects instead of arrays', function() {
|
it('can return objects instead of arrays', function() {
|
||||||
var obj = {foo: 'bar'};
|
var obj = {foo: 'bar'};
|
||||||
rTree.insert([5, 5, 5, 5], obj);
|
rTree.insert([[5, 5], [5, 5]], obj);
|
||||||
var result = rTree.searchReturningObject([4, 6, 4, 6]);
|
var result = rTree.searchReturningObject([[4, 4], [6, 6]]);
|
||||||
expect(result[goog.getUid(obj)]).to.equal(obj);
|
expect(result[goog.getUid(obj)]).to.equal(obj);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user