package com.revolsys.geometry.graph.visitor;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import com.revolsys.geometry.graph.Edge;
import com.revolsys.geometry.graph.Graph;
import com.revolsys.geometry.graph.Node;
import com.revolsys.geometry.index.IdObjectIndex;
import com.revolsys.geometry.model.BoundingBox;
import com.revolsys.geometry.model.LineString;
import com.revolsys.geometry.model.Point;
import com.revolsys.geometry.util.LineStringUtil;
import com.revolsys.visitor.CreateListVisitor;
import com.revolsys.visitor.DelegatingVisitor;
public class NodeOnEdgeVisitor<T> extends DelegatingVisitor<Edge<T>> {
public static <T> List<Edge<T>> getEdges(final Graph<T> graph, final Node<T> node,
final double maxDistance) {
final CreateListVisitor<Edge<T>> results = new CreateListVisitor<>();
final Point point = node;
BoundingBox boundingBox = point.getBoundingBox();
boundingBox = boundingBox.expand(maxDistance);
final IdObjectIndex<Edge<T>> index = graph.getEdgeIndex();
final NodeOnEdgeVisitor<T> visitor = new NodeOnEdgeVisitor<>(node, boundingBox, maxDistance,
results);
index.forEach(boundingBox, visitor);
final List<Edge<T>> edges = results.getList();
Collections.sort(edges);
return edges;
}
private final BoundingBox boundingBox;
private final double maxDistance;
private final Node<T> node;
private final Point point;
public NodeOnEdgeVisitor(final Node<T> node, final BoundingBox boundingBox,
final double maxDistance, final Consumer<Edge<T>> matchVisitor) {
super(matchVisitor);
this.node = node;
this.boundingBox = boundingBox;
this.maxDistance = maxDistance;
this.point = node;
}
@Override
public void accept(final Edge<T> edge) {
if (!edge.hasNode(this.node)) {
final LineString line = edge.getLine();
if (line.getBoundingBox().intersects(this.boundingBox)) {
if (LineStringUtil.isPointOnLine(line, this.point, this.maxDistance)) {
super.accept(edge);
}
}
}
}
}