package com.revolsys.elevation.tin;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Predicate;
import com.revolsys.collection.list.Lists;
import com.revolsys.geometry.index.SpatialIndex;
import com.revolsys.geometry.index.rtree.RTree;
import com.revolsys.geometry.model.BoundingBox;
import com.revolsys.geometry.model.GeometryFactory;
import com.revolsys.geometry.model.Point;
import com.revolsys.geometry.model.Triangle;
import com.revolsys.spring.resource.Resource;
public class TriangulatedIrregularNetworkImpl implements TriangulatedIrregularNetwork {
private final BoundingBox boundingBox;
private final GeometryFactory geometryFactory;
private final RTree<Triangle> triangleIndex = new RTree<>();
private Resource resource;
private final Set<Point> nodes = new LinkedHashSet<>();
private List<Triangle> triangles = new ArrayList<>();
public TriangulatedIrregularNetworkImpl(final BoundingBox boundingBox,
final Iterable<? extends Triangle> triangles) {
this.boundingBox = boundingBox;
this.geometryFactory = boundingBox.getGeometryFactory();
this.triangles = Lists.toArray(triangles);
for (final Triangle triangle : this.triangles) {
for (int i = 0; i < 3; i++) {
this.nodes.add(triangle.getPoint(i));
}
this.triangleIndex.insertItem(triangle.getBoundingBox(), triangle);
}
}
@Override
public void forEachTriangle(final BoundingBox boundingBox,
final Consumer<? super Triangle> action) {
final SpatialIndex<Triangle> index = getTriangleIndex();
if (index != null) {
index.forEach(boundingBox, action);
}
}
@Override
public void forEachTriangle(final BoundingBox boundingBox,
final Predicate<? super Triangle> filter, final Consumer<? super Triangle> action) {
final SpatialIndex<Triangle> index = getTriangleIndex();
if (index != null) {
index.forEach(boundingBox, filter, action);
}
}
@Override
public void forEachTriangle(final Consumer<? super Triangle> action) {
for (final Triangle triangle : this.triangles) {
action.accept(triangle);
}
}
@Override
public void forEachTriangle(final Predicate<? super Triangle> filter,
final Consumer<? super Triangle> action) {
if (filter == null) {
forEachTriangle(action);
} else {
for (final Triangle triangle : this.triangles) {
if (filter.test(triangle)) {
action.accept(triangle);
}
}
}
}
@Override
public void forEachVertex(final Consumer<Point> action) {
this.nodes.forEach(action);
}
@Override
public BoundingBox getBoundingBox() {
return this.boundingBox;
}
@Override
public GeometryFactory getGeometryFactory() {
return this.geometryFactory;
}
@Override
public Resource getResource() {
return this.resource;
}
@Override
public int getTriangleCount() {
return this.triangles.size();
}
public SpatialIndex<Triangle> getTriangleIndex() {
return this.triangleIndex;
}
@Override
public int getVertexCount() {
return this.nodes.size();
}
}