package technology.tabula;
import gnu.trove.procedure.TIntProcedure;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.sf.jsi.SpatialIndex;
import net.sf.jsi.rtree.RTree;
class RectangleSpatialIndex<T extends Rectangle> {
class SaveToListProcedure implements TIntProcedure {
private List<Integer> ids = new ArrayList<Integer>();
public boolean execute(int id) {
ids.add(id);
return true;
};
private List<Integer> getIds() {
return ids;
}
};
private final SpatialIndex si;
private final List<T> rectangles;
private Rectangle bounds = null;
public RectangleSpatialIndex() {
si = new RTree();
si.init(null);
rectangles = new ArrayList<T>();
}
public void add(T te) {
rectangles.add(te);
if (bounds == null) {
bounds = new Rectangle();
bounds.setRect(te);
}
else {
bounds.merge(te);
}
si.add(rectangleToSpatialIndexRectangle(te), rectangles.size() - 1);
}
public List<T> contains(Rectangle r) {
SaveToListProcedure proc = new SaveToListProcedure();
si.contains(rectangleToSpatialIndexRectangle(r), proc);
ArrayList<T> rv = new ArrayList<T>();
for (int i : proc.getIds()) {
rv.add(rectangles.get(i));
}
Utils.sort(rv);
return rv;
}
public List<T> intersects(Rectangle r) {
SaveToListProcedure proc = new SaveToListProcedure();
si.intersects(rectangleToSpatialIndexRectangle(r), proc);
ArrayList<T> rv = new ArrayList<T>();
for (int i : proc.getIds()) {
rv.add(rectangles.get(i));
}
Utils.sort(rv);
return rv;
}
private net.sf.jsi.Rectangle rectangleToSpatialIndexRectangle(Rectangle r) {
return new net.sf.jsi.Rectangle((float) r.getX(),
(float) r.getY(),
(float) (r.getX() + r.getWidth()),
(float) (r.getY() + r.getHeight()));
}
/**
* Minimum bounding box of all the Rectangles contained on this RectangleSpatialIndex
*
* @return a Rectangle
*/
public Rectangle getBounds() {
return bounds;
}
}