Search in sources :

Example 6 with Node

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;
}
Also used : HashMap(java.util.HashMap) LineStringGraph(com.revolsys.geometry.graph.linestring.LineStringGraph) Node(com.revolsys.geometry.graph.Node) ArrayList(java.util.ArrayList) Point(com.revolsys.geometry.model.Point) LineString(com.revolsys.geometry.model.LineString) ArrayList(java.util.ArrayList) List(java.util.List) Edge(com.revolsys.geometry.graph.Edge) LineSegment(com.revolsys.geometry.model.segment.LineSegment) LineStringDouble(com.revolsys.geometry.model.impl.LineStringDouble)

Example 7 with Node

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);
                        }
                    }
                }
            }
        }
    }
}
Also used : Node(com.revolsys.geometry.graph.Node) TreeSet(java.util.TreeSet) Edge(com.revolsys.geometry.graph.Edge) LineSegment(com.revolsys.geometry.model.segment.LineSegment)

Example 8 with Node

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;
}
Also used : GeometryFactory(com.revolsys.geometry.model.GeometryFactory) Node(com.revolsys.geometry.graph.Node) Point(com.revolsys.geometry.model.Point)

Example 9 with Node

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;
}
Also used : Node(com.revolsys.geometry.graph.Node) LineString(com.revolsys.geometry.model.LineString)

Example 10 with Node

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);
}
Also used : EdgeAttributeValueComparator(com.revolsys.geometry.graph.comparator.EdgeAttributeValueComparator) GeometryFactory(com.revolsys.geometry.model.GeometryFactory) Node(com.revolsys.geometry.graph.Node) ArrayList(java.util.ArrayList) Point(com.revolsys.geometry.model.Point) Point(com.revolsys.geometry.model.Point) Geometry(com.revolsys.geometry.model.Geometry) Consumer(java.util.function.Consumer) LineString(com.revolsys.geometry.model.LineString) Edge(com.revolsys.geometry.graph.Edge) LineSegment(com.revolsys.geometry.model.segment.LineSegment)

Aggregations

Node (com.revolsys.geometry.graph.Node)13 Edge (com.revolsys.geometry.graph.Edge)8 LineString (com.revolsys.geometry.model.LineString)8 LineSegment (com.revolsys.geometry.model.segment.LineSegment)7 Point (com.revolsys.geometry.model.Point)6 ArrayList (java.util.ArrayList)6 List (java.util.List)4 GeometryFactory (com.revolsys.geometry.model.GeometryFactory)3 EdgeAttributeValueComparator (com.revolsys.geometry.graph.comparator.EdgeAttributeValueComparator)2 BoundingBox (com.revolsys.geometry.model.BoundingBox)2 Geometry (com.revolsys.geometry.model.Geometry)2 PointOnLineSegment (com.revolsys.geometry.model.coordinates.filter.PointOnLineSegment)2 CreateListVisitor (com.revolsys.visitor.CreateListVisitor)2 HashMap (java.util.HashMap)2 Consumer (java.util.function.Consumer)2 DataType (com.revolsys.datatype.DataType)1 RecordGraph (com.revolsys.geometry.graph.RecordGraph)1 NodeDistanceComparator (com.revolsys.geometry.graph.comparator.NodeDistanceComparator)1 NodeCoordinatesFilter (com.revolsys.geometry.graph.filter.NodeCoordinatesFilter)1 LineStringGraph (com.revolsys.geometry.graph.linestring.LineStringGraph)1