use of com.revolsys.geometry.graph.Node in project com.revolsys.open by revolsys.
the class CoordinatesListUtil method intersection.
public static List<LineString> intersection(final GeometryFactory geometryFactory, final LineString points1, final LineString points2, final double maxDistance) {
final LineStringGraph graph1 = new LineStringGraph(points1);
graph1.setPrecisionModel(geometryFactory);
final LineStringGraph graph2 = new LineStringGraph(points2);
graph2.setPrecisionModel(geometryFactory);
final Map<Point, Point> movedNodes = new HashMap<>();
graph1.forEachNode((node) -> movePointsWithinTolerance(movedNodes, graph2, maxDistance, node));
graph2.forEachNode((node) -> movePointsWithinTolerance(movedNodes, graph1, maxDistance, node));
final Map<Edge<LineSegment>, List<Node<LineSegment>>> pointsOnEdge1 = graph1.getPointsOnEdges(graph2, maxDistance);
final Map<Edge<LineSegment>, List<Node<LineSegment>>> pointsOnEdge2 = graph2.getPointsOnEdges(graph1, maxDistance);
graph1.splitEdges(pointsOnEdge1);
graph2.splitEdges(pointsOnEdge2);
Point startPoint = points1.getPoint(0);
if (movedNodes.containsKey(startPoint)) {
startPoint = movedNodes.get(startPoint);
}
Point endPoint = points1.getPoint(points1.getVertexCount() - 1);
if (movedNodes.containsKey(endPoint)) {
endPoint = movedNodes.get(endPoint);
}
final List<LineString> intersections = new ArrayList<>();
final List<Point> currentCoordinates = new ArrayList<>();
Node<LineSegment> previousNode = graph1.getNode(startPoint);
do {
final List<Edge<LineSegment>> outEdges = previousNode.getOutEdges();
if (outEdges.isEmpty()) {
previousNode = null;
} else if (outEdges.size() > 1) {
throw new IllegalArgumentException("Cannot handle overlaps\n" + points1 + "\n " + points2);
} else {
final Edge<LineSegment> edge = outEdges.get(0);
final LineSegment line = edge.getObject();
final Node<LineSegment> nextNode = edge.getToNode();
if (graph2.hasEdgeBetween(previousNode, nextNode)) {
if (currentCoordinates.size() == 0) {
currentCoordinates.add(line.getPoint(0));
}
currentCoordinates.add(line.getPoint(1));
} else {
if (currentCoordinates.size() > 0) {
final LineString points = new LineStringDouble(points1.getAxisCount(), currentCoordinates);
intersections.add(points);
currentCoordinates.clear();
}
}
previousNode = nextNode;
}
} while (previousNode != null && !endPoint.equals(2, startPoint));
if (currentCoordinates.size() > 0) {
final LineString points = new LineStringDouble(points1.getAxisCount(), currentCoordinates);
intersections.add(points);
}
return intersections;
}
use of com.revolsys.geometry.graph.Node in project com.revolsys.open by revolsys.
the class LineMatchGraph method integrateLine.
/**
* Integrate the line, splitting any edges which the nodes from this line are
* on the other edges.
*
* @param line
* @param index
*/
private void integrateLine(final LineString line, final int index) {
final Set<Edge<LineSegmentMatch>> edgesToProcess = getEdgesWithoutMatch(line, index);
if (!edgesToProcess.isEmpty()) {
for (final Edge<LineSegmentMatch> edge : edgesToProcess) {
if (!edge.isRemoved()) {
final LineSegmentMatch lineSegmentMatch = edge.getObject();
final LineSegment segment = lineSegmentMatch.getSegment();
if (!lineSegmentMatch.hasMatches(index)) {
final List<Edge<LineSegmentMatch>> matchEdges = BoundingBoxIntersectsEdgeVisitor.getEdges(this, edge, this.tolerance);
if (!matchEdges.isEmpty()) {
final boolean allowSplit = edge.getLength() >= 2 * this.tolerance;
final Set<Node<LineSegmentMatch>> splitNodes = new TreeSet<>(new NodeDistanceComparator<>(edge.getFromNode()));
final Node<LineSegmentMatch> lineStart = edge.getFromNode();
final Node<LineSegmentMatch> lineEnd = edge.getToNode();
for (final ListIterator<Edge<LineSegmentMatch>> iterator = matchEdges.listIterator(); iterator.hasNext(); ) {
final Edge<LineSegmentMatch> matchEdge = iterator.next();
iterator.remove();
final LineSegmentMatch matchLineSegmentMatch = matchEdge.getObject();
if (!matchLineSegmentMatch.hasSegment(index) && matchLineSegmentMatch.hasOtherSegment(index)) {
final Node<LineSegmentMatch> line2Start = matchEdge.getFromNode();
final Node<LineSegmentMatch> line2End = matchEdge.getToNode();
final Set<Node<LineSegmentMatch>> matchSplitNodes = new TreeSet<>(new NodeDistanceComparator<>(line2Start));
final LineSegment matchSegment = matchLineSegmentMatch.getSegment();
if (matchEdge.getLength() >= 2 * this.tolerance) {
if (matchSegment.isPointOnLineMiddle(lineStart, this.tolerance)) {
matchSplitNodes.add(lineStart);
}
if (matchSegment.isPointOnLineMiddle(lineEnd, this.tolerance)) {
matchSplitNodes.add(lineEnd);
}
}
if (!matchSplitNodes.isEmpty()) {
final List<Edge<LineSegmentMatch>> splitEdges = splitEdge(matchEdge, matchSplitNodes);
for (final Edge<LineSegmentMatch> splitEdge : splitEdges) {
iterator.add(splitEdge);
}
} else if (allowSplit) {
if (segment.isPointOnLineMiddle(line2Start, this.tolerance)) {
splitNodes.add(line2Start);
}
if (segment.isPointOnLineMiddle(line2End, this.tolerance)) {
splitNodes.add(line2End);
}
}
}
}
if (!splitNodes.isEmpty() && allowSplit) {
splitEdge(edge, splitNodes);
}
}
}
}
}
}
}
use of com.revolsys.geometry.graph.Node in project com.revolsys.open by revolsys.
the class CoordinatesListUtil method movePointsWithinTolerance.
/**
* Only move the node if there is one of them
*
* @param graph2
* @param maxDistance
* @param node1
* @return
*/
public static <T> boolean movePointsWithinTolerance(final Map<Point, Point> movedNodes, final Graph<T> graph2, final double maxDistance, final Node<T> node1) {
final Graph<T> graph1 = node1.getGraph();
final List<Node<T>> nodes2 = graph2.getNodes(node1, maxDistance);
if (nodes2.size() == 1) {
final Node<T> node2 = nodes2.get(0);
if (graph1.findNode(node2) == null) {
final GeometryFactory precisionModel = graph1.getPrecisionModel();
final Point midPoint = LineSegmentUtil.midPoint(precisionModel, node1, node2);
if (!node1.equals(2, midPoint)) {
if (movedNodes != null) {
movedNodes.put(node1.newPoint2D(), midPoint);
}
node1.moveNode(midPoint);
}
if (!node2.equals(2, midPoint)) {
if (movedNodes != null) {
movedNodes.put(node2.newPoint2D(), midPoint);
}
node2.moveNode(midPoint);
}
}
}
return true;
}
use of com.revolsys.geometry.graph.Node in project com.revolsys.open by revolsys.
the class NodeProperties method getField.
@SuppressWarnings("unchecked")
private static <T, V> V getField(final Node<T> node, final String name, final Function<Node<T>, V> function) {
final String fieldName = NodeProperties.class.getName() + "." + name;
if (!node.hasProperty(fieldName)) {
final FunctionObjectPropertyProxy<Node<T>, V> proxy = new FunctionObjectPropertyProxy<>(function);
node.setProperty(fieldName, proxy);
}
final V value = (V) node.getProperty(fieldName);
return value;
}
use of com.revolsys.geometry.graph.Node in project com.revolsys.open by revolsys.
the class GeometryGraph method getGeometry.
/**
* Only currently works for lines and points.
*
* @return
*/
public Geometry getGeometry() {
removeDuplicateLineEdges();
final EdgeAttributeValueComparator<LineSegment> comparator = new EdgeAttributeValueComparator<>("geometryIndex", "partIndex", "segmentIndex");
final List<Geometry> geometries = new ArrayList<>(this.points);
final GeometryFactory geometryFactory = getGeometryFactory();
final List<Point> points = new ArrayList<>();
final Consumer<Edge<LineSegment>> action = new Consumer<Edge<LineSegment>>() {
private Node<LineSegment> previousNode = null;
@Override
public void accept(final Edge<LineSegment> edge) {
final LineSegment lineSegment = edge.getObject();
if (lineSegment.getLength() > 0) {
final Node<LineSegment> fromNode = edge.getFromNode();
final Node<LineSegment> toNode = edge.getToNode();
if (this.previousNode == null) {
points.add(lineSegment.getPoint(0));
points.add(lineSegment.getPoint(1));
} else if (fromNode == this.previousNode) {
if (edge.getLength() > 0) {
points.add(toNode);
}
} else {
if (points.size() > 1) {
final LineString line = geometryFactory.lineString(points);
geometries.add(line);
}
points.clear();
;
points.add(lineSegment.getPoint(0));
points.add(lineSegment.getPoint(1));
}
if (points.size() > 1) {
final int toDegree = toNode.getDegree();
if (toDegree != 2) {
final LineString line = geometryFactory.lineString(points);
geometries.add(line);
points.clear();
;
points.add(toNode);
}
}
this.previousNode = toNode;
}
}
};
forEachEdge(comparator, action);
if (points.size() > 1) {
final LineString line = geometryFactory.lineString(points);
geometries.add(line);
}
return geometryFactory.geometry(geometries);
}
Aggregations