for (int i = 0; i < numShapesId; 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);
tree.insert(node, shapeId, env, extraLevels);
}
}
// pack the arrays to use less memory (the optimization often makes the tree grow)
node.pack();
// recurse
for (int i = 0; i < node.getNumSubNodes(); i++) {
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) {