use of com.revolsys.geometry.graph.Edge in project com.revolsys.open by revolsys.
the class LineMerger method mergeDegree2FromEnds.
private void mergeDegree2FromEnds() {
final List<Node<LineString>> endNodes = this.graph.getNodes(node -> node.getDegree() != 2);
for (final Node<LineString> node : endNodes) {
if (!node.isRemoved()) {
for (final Edge<LineString> edge : Lists.toArray(node.getEdges())) {
if (!edge.isRemoved()) {
final List<LineString> lines = new ArrayList<>();
final List<Boolean> lineForwards = new ArrayList<>();
double forwardsLength = 0;
double reverseLength = 0;
Edge<LineString> previousEdge = null;
Node<LineString> currentNode = node;
Edge<LineString> currentEdge = edge;
do {
final LineString line = currentEdge.getLineString();
final double length = line.getLength();
final boolean forwards = currentEdge.getEnd(currentNode).isFrom();
if (forwards) {
forwardsLength += length;
} else {
reverseLength += length;
}
lines.add(line);
lineForwards.add(forwards);
currentNode = currentEdge.getOppositeNode(currentNode);
previousEdge = currentEdge;
currentEdge = currentNode.getNextEdge(previousEdge);
} while (currentNode.getDegree() == 2);
if (lines.size() > 1) {
LineString mergedLine = null;
final boolean mergeForwards = forwardsLength >= reverseLength;
int i = 0;
for (LineString line : lines) {
final boolean forwards = lineForwards.get(i);
if (forwards != mergeForwards) {
line = line.reverse();
}
if (mergedLine == null) {
mergedLine = line;
} else {
mergedLine = mergedLine.merge(line);
}
i++;
}
this.graph.addEdge(mergedLine);
this.graph.removeEdges(lines);
}
}
}
}
}
if (this.allowLoops) {
final List<Node<LineString>> psudeoNodes = this.graph.getNodes(node -> node.getDegree() == 2);
for (final Node<LineString> node : psudeoNodes) {
if (!node.isRemoved()) {
final List<Edge<LineString>> edges = node.getEdges();
if (edges.size() == 2) {
final Edge<LineString> edge1 = edges.get(0);
final Edge<LineString> edge2 = edges.get(1);
if (edge1 != edge2) {
final LineString line1 = edge1.getLineString();
final LineString line2 = edge2.getLineString();
final LineString mergedLine = line1.merge(line2);
this.graph.addEdge(mergedLine);
this.graph.remove(edge1);
this.graph.remove(edge2);
}
}
}
}
}
}
use of com.revolsys.geometry.graph.Edge in project com.revolsys.open by revolsys.
the class EdgeLessThanDistance method getEdges.
public static List<Edge<LineSegment>> getEdges(final Graph<LineSegment> graph, final LineSegment lineSegment, final double maxDistance) {
final CreateListVisitor<Edge<LineSegment>> results = new CreateListVisitor<>();
BoundingBox envelope = lineSegment.getBoundingBox();
envelope = envelope.expand(maxDistance);
final IdObjectIndex<Edge<LineSegment>> edgeIndex = graph.getEdgeIndex();
edgeIndex.forEach(envelope, new EdgeLessThanDistance(lineSegment, maxDistance, results));
return results.getList();
}
use of com.revolsys.geometry.graph.Edge in project com.revolsys.open by revolsys.
the class LineStringGraph method getPointsOnEdges.
public Map<Edge<LineSegment>, List<Node<LineSegment>>> getPointsOnEdges(final Graph<LineSegment> graph1, final double tolerance) {
final Map<Edge<LineSegment>, List<Node<LineSegment>>> pointsOnEdge1 = new HashMap<>();
for (final Edge<LineSegment> edge : getEdges()) {
final Node<LineSegment> fromNode = edge.getFromNode();
final Node<LineSegment> toNode = edge.getToNode();
final LineSegment lineSegment = edge.getObject();
final PointOnLineSegment coordinatesFilter = new PointOnLineSegment(lineSegment, tolerance);
final NodeCoordinatesFilter<LineSegment> nodeFilter = new NodeCoordinatesFilter<>(coordinatesFilter);
final NodeDistanceComparator<LineSegment> comparator = new NodeDistanceComparator<>(fromNode);
final List<Node<LineSegment>> nodes = graph1.getNodes(nodeFilter, comparator);
for (final Iterator<Node<LineSegment>> iterator = nodes.iterator(); iterator.hasNext(); ) {
final Node<LineSegment> node = iterator.next();
if (node.equals(2, fromNode)) {
iterator.remove();
} else if (node.equals(2, toNode)) {
iterator.remove();
}
}
if (!nodes.isEmpty()) {
pointsOnEdge1.put(edge, nodes);
}
}
return pointsOnEdge1;
}
use of com.revolsys.geometry.graph.Edge in project com.revolsys.open by revolsys.
the class LineStringGraph method splitCrossingEdges.
public void splitCrossingEdges() {
final Comparator<Edge<LineSegment>> comparator = new EdgeAttributeValueComparator<>(INDEX);
forEachEdge(comparator, (edge) -> {
final LineSegment line1 = edge.getObject();
final Predicate<LineSegment> lineFilter = new CrossingLineSegmentFilter(line1);
final Predicate<Edge<LineSegment>> filter = new EdgeObjectFilter<>(lineFilter);
final List<Edge<LineSegment>> edges = getEdges(line1, filter);
if (!edges.isEmpty()) {
final List<Point> points = new ArrayList<>();
for (final Edge<LineSegment> edge2 : edges) {
final LineSegment line2 = edge2.getObject();
final Geometry intersections = line1.getIntersection(line2);
if (intersections instanceof Point) {
final Point intersection = (Point) intersections;
points.add(intersection);
edge2.split(intersection);
}
}
if (!points.isEmpty()) {
edge.splitEdge(points);
}
}
});
}
use of com.revolsys.geometry.graph.Edge in project com.revolsys.open by revolsys.
the class LineStringGraph method hasTouchingEdges.
public boolean hasTouchingEdges(final Node<LineSegment> node) {
final GeometryFactory precisionModel = getPrecisionModel();
final List<Edge<LineSegment>> edges = getEdges(node, precisionModel.getScaleXY());
for (final Edge<LineSegment> edge : edges) {
final Point lineStart = edge.getFromNode();
final Point lineEnd = edge.getToNode();
if (LineSegmentUtil.isPointOnLineMiddle(precisionModel, lineStart, lineEnd, node)) {
return true;
}
}
return false;
}
Aggregations