Search in sources :

Example 1 with CoordinatesDistanceComparator

use of com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator in project com.revolsys.open by revolsys.

the class LineStringGraph method splitEdge.

@Override
public <V extends Point> List<Edge<LineSegment>> splitEdge(final Edge<LineSegment> edge, final Collection<V> nodes) {
    final List<Edge<LineSegment>> newEdges = new ArrayList<>();
    if (!edge.isRemoved()) {
        final Node<LineSegment> fromNode = edge.getFromNode();
        final Node<LineSegment> toNode = edge.getToNode();
        final CoordinatesDistanceComparator comparator = new CoordinatesDistanceComparator(fromNode.getX(), toNode.getY());
        final Set<Point> newPoints = new TreeSet<>(comparator);
        for (final Point point : nodes) {
            newPoints.add(point);
        }
        newPoints.add(toNode);
        final List<Integer> index = edge.getProperty(INDEX);
        int i = 0;
        Point previousPoint = fromNode;
        for (final Point point : newPoints) {
            final LineSegment lineSegment = new LineSegmentDoubleGF(previousPoint, point);
            final Edge<LineSegment> newEdge = addEdge(lineSegment, previousPoint, point);
            final List<Integer> newIndecies = new ArrayList<>(index);
            newIndecies.add(i++);
            newEdge.setProperty(INDEX, newIndecies);
            newEdges.add(newEdge);
            previousPoint = point;
        }
        remove(edge);
    }
    return newEdges;
}
Also used : CoordinatesDistanceComparator(com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator) ArrayList(java.util.ArrayList) Point(com.revolsys.geometry.model.Point) Point(com.revolsys.geometry.model.Point) LineSegmentDoubleGF(com.revolsys.geometry.model.segment.LineSegmentDoubleGF) TreeSet(java.util.TreeSet) Edge(com.revolsys.geometry.graph.Edge) LineSegment(com.revolsys.geometry.model.segment.LineSegment) PointOnLineSegment(com.revolsys.geometry.model.coordinates.filter.PointOnLineSegment)

Example 2 with CoordinatesDistanceComparator

use of com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator in project com.revolsys.open by revolsys.

the class LineSegmentUtil method getIntersection.

/**
 * Get the intersection between line (segment) 1 and line (segment) 2. The
 * result will be either and empty collection, a single coordinates value for
 * a crosses intersection or a pair of coordinates for a linear intersection.
 * The results will be rounded according to the precision model. Any z-value
 * interpolation will be calculated using the z-values from line (segment) 1.
 * For linear intersections the order of the points will be the same as the
 * orientation of line1.
 *
 * @param geometryFactory
 * @param line1Start
 * @param line1End
 * @param line2Start
 * @param line2End
 * @return
 */
public static LineString getIntersection(final GeometryFactory geometryFactory, Point line1Start, Point line1End, Point line2Start, Point line2End) {
    line1Start = line1Start.convertGeometry(geometryFactory);
    line1End = line1End.convertGeometry(geometryFactory);
    line2Start = line2Start.convertGeometry(geometryFactory);
    line2End = line2End.convertGeometry(geometryFactory);
    if (RectangleUtil.intersects(line1Start, line1End, line2Start, line2End)) {
        final Set<Point> intersections = new TreeSet<>(new CoordinatesDistanceComparator(line1Start.getX(), line1Start.getY()));
        if (LineSegmentUtil.isPointOnLine(geometryFactory, line2Start, line2End, line1Start)) {
            intersections.add(line1Start);
        }
        if (LineSegmentUtil.isPointOnLine(geometryFactory, line2Start, line2End, line1End)) {
            intersections.add(line1End);
        }
        if (LineSegmentUtil.isPointOnLine(geometryFactory, line1Start, line1End, line2Start)) {
            final Point intersection = getElevation(geometryFactory, line1Start, line1End, line2Start);
            intersections.add(intersection);
        }
        if (LineSegmentUtil.isPointOnLine(geometryFactory, line1Start, line1End, line2End)) {
            final Point intersection = getElevation(geometryFactory, line1Start, line1End, line2End);
            intersections.add(intersection);
        }
        if (intersections.isEmpty()) {
            final double line1x1 = line1Start.getX();
            final double line1y1 = line1Start.getY();
            final double line1x2 = line1End.getX();
            final double line1y2 = line1End.getY();
            final double line2x1 = line2Start.getX();
            final double line2y1 = line2Start.getY();
            final double line2x2 = line2End.getX();
            final double line2y2 = line2End.getY();
            final int Pq1 = CoordinatesListUtil.orientationIndex(line1x1, line1y1, line1x2, line1y2, line2x1, line2y1);
            final int Pq2 = CoordinatesListUtil.orientationIndex(line1x1, line1y1, line1x2, line1y2, line2x2, line2y2);
            if (!(Pq1 > 0 && Pq2 > 0 || Pq1 < 0 && Pq2 < 0)) {
                final int Qp1 = CoordinatesListUtil.orientationIndex(line2x1, line2y1, line2x2, line2y2, line1x1, line1y1);
                final int Qp2 = CoordinatesListUtil.orientationIndex(line2x1, line2y1, line2x2, line2y2, line1x2, line1y2);
                if (!(Qp1 > 0 && Qp2 > 0 || Qp1 < 0 && Qp2 < 0)) {
                    final double detLine1StartLine1End = LineSegmentUtil.det(line1x1, line1y1, line1x2, line1y2);
                    final double detLine2StartLine2End = LineSegmentUtil.det(line2x1, line2y1, line2x2, line2y2);
                    final double x = LineSegmentUtil.det(detLine1StartLine1End, line1x1 - line1x2, detLine2StartLine2End, line2x1 - line2x2) / LineSegmentUtil.det(line1x1 - line1x2, line1y1 - line1y2, line2x1 - line2x2, line2y1 - line2y2);
                    final double y = LineSegmentUtil.det(detLine1StartLine1End, line1y1 - line1y2, detLine2StartLine2End, line2y1 - line2y2) / LineSegmentUtil.det(line1x1 - line1x2, line1y1 - line1y2, line2x1 - line2x2, line2y1 - line2y2);
                    Point intersection = geometryFactory.point(x, y);
                    intersection = getElevation(geometryFactory, line1Start, line1End, intersection);
                    final LineStringDouble points = new LineStringDouble(geometryFactory.getAxisCount(), intersection);
                    return points;
                }
            }
        } else {
            return geometryFactory.lineString(intersections);
        }
    }
    return geometryFactory.lineString();
}
Also used : CoordinatesDistanceComparator(com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator) TreeSet(java.util.TreeSet) Point(com.revolsys.geometry.model.Point) Point(com.revolsys.geometry.model.Point) LineStringDouble(com.revolsys.geometry.model.impl.LineStringDouble)

Example 3 with CoordinatesDistanceComparator

use of com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator in project com.revolsys.open by revolsys.

the class Graph method splitEdge.

public <V extends Point> List<Edge<T>> splitEdge(final Edge<T> edge, final Collection<V> splitPoints, final double maxDistance) {
    final Collection<V> nodes = new ArrayList<>(splitPoints);
    if (edge.isRemoved()) {
        return Collections.emptyList();
    } else {
        final LineString line = edge.getLineString();
        final LineString points = line;
        final Set<Integer> splitVertices = new TreeSet<>();
        final Set<Integer> splitIndexes = new TreeSet<>();
        for (final Iterator<V> nodeIter = nodes.iterator(); nodeIter.hasNext(); ) {
            final Point node = nodeIter.next();
            final double distance = points.distanceVertex(0, node);
            if (distance < maxDistance) {
                nodeIter.remove();
            }
        }
        final Map<Point, Double> nodeDistanceMap = new HashMap<>();
        final Map<Point, Integer> nodeSegment = new HashMap<>();
        for (int i = 1; i < points.getVertexCount() && !nodes.isEmpty(); i++) {
            for (final Iterator<V> nodeIter = nodes.iterator(); nodeIter.hasNext(); ) {
                final Point node = nodeIter.next();
                final double nodeDistance = points.distanceVertex(i, node);
                if (nodeDistance < maxDistance) {
                    if (i < points.getVertexCount() - 1) {
                        splitVertices.add(i);
                        splitIndexes.add(i);
                    }
                    nodeDistanceMap.remove(node);
                    nodeSegment.remove(node);
                    nodeIter.remove();
                } else {
                    final int segmentIndex = i - 1;
                    final double x = node.getX();
                    final double y = node.getY();
                    final double x1 = points.getX(segmentIndex);
                    final double y1 = points.getY(segmentIndex);
                    final double x2 = points.getX(i);
                    final double y2 = points.getY(i);
                    final double segmentDistance = LineSegmentUtil.distanceLinePoint(x1, y1, x2, y2, x, y);
                    if (segmentDistance == 0) {
                        nodeDistanceMap.put(node, segmentDistance);
                        nodeSegment.put(node, segmentIndex);
                        nodeIter.remove();
                    } else {
                        final double projectionFactor = LineSegmentUtil.projectionFactor(x1, y1, x2, y2, x, y);
                        if (projectionFactor >= 0.0 && projectionFactor <= 1.0) {
                            final Double closestDistance = nodeDistanceMap.get(node);
                            if (closestDistance == null) {
                                nodeSegment.put(node, segmentIndex);
                                nodeDistanceMap.put(node, segmentDistance);
                            } else if (closestDistance.compareTo(segmentDistance) > 0) {
                                nodeSegment.put(node, segmentIndex);
                                nodeDistanceMap.put(node, segmentDistance);
                            }
                        }
                    }
                }
            }
        }
        final T object = edge.getObject();
        final GeometryFactory geometryFactory = line.getGeometryFactory();
        final Map<Integer, Set<Point>> segmentSplitNodes = new TreeMap<>();
        for (final Entry<Point, Integer> entry : nodeSegment.entrySet()) {
            final Point node = entry.getKey();
            final Integer index = entry.getValue();
            Set<Point> splitNodes = segmentSplitNodes.get(index);
            if (splitNodes == null) {
                final double x = points.getX(index);
                final double y = points.getY(index);
                splitNodes = new TreeSet<>(new CoordinatesDistanceComparator(x, y));
                segmentSplitNodes.put(index, splitNodes);
                splitIndexes.add(index);
            }
            splitNodes.add(node);
            nodes.remove(node);
        }
        if (nodes.isEmpty()) {
            final List<LineString> newLines = new ArrayList<>();
            int startIndex = 0;
            Point startPoint = null;
            for (final Integer index : splitIndexes) {
                if (splitVertices.contains(index)) {
                    final LineString newPoints = points.subLine(startPoint, startIndex, index - startIndex + 1, null);
                    newLines.add(newPoints);
                    startPoint = null;
                    startIndex = index;
                }
                final Set<Point> splitNodes = segmentSplitNodes.get(index);
                if (splitNodes != null) {
                    for (final Point splitPoint : splitNodes) {
                        final Node<T> node = getNode(splitPoint);
                        final String typePath = edge.getTypeName();
                        Point point = splitPoint;
                        double splitPointZ = splitPoint.getZ();
                        if (splitPointZ == 0 || Double.isNaN(splitPointZ)) {
                            if (splitPoint instanceof Node<?>) {
                                final Node<?> splitNode = (Node<?>) splitPoint;
                                point = splitNode.get3dCoordinates(typePath);
                                splitPointZ = point.getZ();
                            }
                            if (splitPointZ == 0 || Double.isNaN(splitPointZ)) {
                                point = node.get3dCoordinates(typePath);
                            }
                            if (splitPointZ == 0 || Double.isNaN(splitPointZ)) {
                                final Point p1 = points.getPoint(index);
                                final Point p2 = points.getPoint(index + 1);
                                final double z = LineSegmentUtil.getElevation(p1, p2, point);
                                point = new PointDoubleXYZ(point.getX(), point.getY(), z);
                            }
                        }
                        final LineString newPoints;
                        if (startIndex > index) {
                            newPoints = new LineStringDouble(points.getAxisCount(), startPoint, point);
                        } else {
                            newPoints = points.subLine(startPoint, startIndex, index - startIndex + 1, point);
                        }
                        newLines.add(newPoints);
                        startPoint = point;
                        startIndex = index + 1;
                    }
                }
            }
            final LineString newPoints = points.subLine(startPoint, startIndex, points.getVertexCount(), null);
            newLines.add(newPoints);
            if (newLines.size() > 1) {
                final List<Edge<T>> newEdges = new ArrayList<>();
                for (final LineString edgePoints : newLines) {
                    final Edge<T> newEdge = newEdge(geometryFactory, object, edgePoints);
                    newEdges.add(newEdge);
                }
                edge.remove();
                return newEdges;
            } else {
                return Collections.singletonList(edge);
            }
        } else {
            return Collections.singletonList(edge);
        }
    }
}
Also used : GeometryFactory(com.revolsys.geometry.model.GeometryFactory) Set(java.util.Set) TreeSet(java.util.TreeSet) IntHashMap(com.revolsys.collection.map.IntHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) LineString(com.revolsys.geometry.model.LineString) PointDoubleXYZ(com.revolsys.geometry.model.impl.PointDoubleXYZ) TreeSet(java.util.TreeSet) CoordinatesDistanceComparator(com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator) Point(com.revolsys.geometry.model.Point) BPlusTreeMap(com.revolsys.collection.bplus.BPlusTreeMap) TreeMap(java.util.TreeMap) LineStringDouble(com.revolsys.geometry.model.impl.LineStringDouble) Point(com.revolsys.geometry.model.Point) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LineString(com.revolsys.geometry.model.LineString) LineStringDouble(com.revolsys.geometry.model.impl.LineStringDouble)

Aggregations

Point (com.revolsys.geometry.model.Point)3 CoordinatesDistanceComparator (com.revolsys.geometry.model.coordinates.comparator.CoordinatesDistanceComparator)3 TreeSet (java.util.TreeSet)3 LineStringDouble (com.revolsys.geometry.model.impl.LineStringDouble)2 ArrayList (java.util.ArrayList)2 BPlusTreeMap (com.revolsys.collection.bplus.BPlusTreeMap)1 IntHashMap (com.revolsys.collection.map.IntHashMap)1 Edge (com.revolsys.geometry.graph.Edge)1 GeometryFactory (com.revolsys.geometry.model.GeometryFactory)1 LineString (com.revolsys.geometry.model.LineString)1 PointOnLineSegment (com.revolsys.geometry.model.coordinates.filter.PointOnLineSegment)1 PointDoubleXYZ (com.revolsys.geometry.model.impl.PointDoubleXYZ)1 LineSegment (com.revolsys.geometry.model.segment.LineSegment)1 LineSegmentDoubleGF (com.revolsys.geometry.model.segment.LineSegmentDoubleGF)1 HashMap (java.util.HashMap)1 Set (java.util.Set)1 TreeMap (java.util.TreeMap)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1