package com.revolsys.geometry.index.quadtree;
import java.util.Collection;
import java.util.function.Consumer;
import java.util.function.Predicate;
import com.revolsys.geometry.index.AbstractPointSpatialIndex;
import com.revolsys.geometry.index.IdObjectIndex;
import com.revolsys.geometry.index.PointSpatialIndex;
import com.revolsys.geometry.model.BoundingBox;
import com.revolsys.geometry.model.BoundingBoxProxy;
import com.revolsys.geometry.model.Point;
public abstract class AbstractIdObjectPointQuadTree<T> extends AbstractPointSpatialIndex<T>
implements IdObjectIndex<T> {
private final PointSpatialIndex<Integer> index = new PointQuadTree<>();
public void add(final Collection<Integer> ids) {
for (final Integer id : ids) {
final T object = getObject(id);
add(object);
}
}
@Override
public T add(final T object) {
final Point point = getCoordinates(object);
put(point, object);
return object;
}
@Override
public void forEach(final BoundingBoxProxy boundingBoxProxy, final Consumer<? super T> action) {
final BoundingBox boundingBox = boundingBoxProxy.getBoundingBox();
this.index.forEach(boundingBox, (id) -> {
final T object = getObject(id);
final BoundingBox e = getBoundingBox(object);
if (e.intersects(boundingBox)) {
action.accept(object);
}
});
}
@Override
public void forEach(final BoundingBoxProxy boundingBoxProxy, final Predicate<? super T> filter,
final Consumer<? super T> action) {
final BoundingBox boundingBox = boundingBoxProxy.getBoundingBox();
this.index.forEach(boundingBox, (id) -> {
final T object = getObject(id);
final BoundingBox e = getBoundingBox(object);
if (e.intersects(boundingBox) && filter.test(object)) {
action.accept(object);
}
});
}
@Override
public void forEach(final Consumer<? super T> action) {
this.index.forEach((id) -> {
final T object = getObject(id);
action.accept(object);
});
}
public abstract Point getCoordinates(T object);
@Override
public void put(final Point point, final T object) {
final int id = getId(object);
this.index.put(point, id);
}
@Override
public boolean remove(final Point point, final T object) {
final int id = getId(object);
return this.index.remove(point, id);
}
@Override
public boolean remove(final T object) {
final Point point = getCoordinates(object);
return remove(point, object);
}
public void removeAll(final Collection<T> objects) {
for (final T object : objects) {
remove(object);
}
}
}