optimizeTree(tree, node.getSubNode(i), level + 1, reader, index);
}
// prune empty subnodes
for (int i = 0; i < node.getNumSubNodes();) {
Node child = node.getSubNode(i);
if(child != null && child.getNumShapeIds() == 0 && child.getNumSubNodes() == 0) {
// empty child, we don't need it, clean it up
node.removeSubNode(child);
} else {
i++;
}
}
// handle degenerate chains, we pop up the nodes to the top by keeping
// their shape ids _and_ their bounds (as it's the only area that has something)
if(node.getNumSubNodes() == 1 && node.getNumShapeIds() == 0) {
Node subnode = node.getSubNode(0);
node.clearSubNodes();
node.setShapesId(subnode);
node.setBounds(subnode.getBounds());
for (int i = 0; i < subnode.getNumSubNodes(); i++) {
node.addSubNode(subnode.getSubNode(i));
}
} else {
// limit this node area to the effective child area
Envelope bounds = new Envelope();
if(node.getNumShapeIds() > 0) {
int[] shapeIds = node.getShapesId();
for (int i = 0; i < shapeIds.length; i++) {
final int shapeId = shapeIds[i];
int offset = index.getOffsetInBytes(shapeId);
reader.goTo(offset);
Record rec = reader.nextRecord();
Envelope env = new Envelope(rec.minX, rec.maxX, rec.minY, rec.maxY);
bounds.expandToInclude(env);
}
}
if(node.getNumSubNodes() > 0) {
for (int i = 0; i < node.getNumSubNodes(); i++) {
bounds.expandToInclude(node.getSubNode(i).getBounds());
}
}
node.setBounds(bounds);
// can we shrink?
int count = node.getNumShapeIds();
for (int i = 0; i < node.getNumSubNodes(); i++) {
Node child = node.getSubNode(i);
if(child.getNumSubNodes() > 0) {
count = Integer.MAX_VALUE;
break;
} else {
count += child.getNumShapeIds();
}
}
if(count < leafSize) {
for (int i = 0; i < node.getNumSubNodes(); i++) {
Node child = node.getSubNode(i);
int[] shapesId = child.getShapesId();
for (int j = 0; j < child.getNumShapeIds(); j++) {
node.addShapeId(shapesId[j]);
}
}
node.clearSubNodes();
}