Search in sources :

Example 11 with Node

use of com.revolsys.geometry.graph.Node 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);
                    }
                }
            }
        }
    }
}
Also used : Node(com.revolsys.geometry.graph.Node) ArrayList(java.util.ArrayList) LineString(com.revolsys.geometry.model.LineString) Edge(com.revolsys.geometry.graph.Edge)

Example 12 with Node

use of com.revolsys.geometry.graph.Node 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;
}
Also used : NodeCoordinatesFilter(com.revolsys.geometry.graph.filter.NodeCoordinatesFilter) HashMap(java.util.HashMap) Node(com.revolsys.geometry.graph.Node) PointOnLineSegment(com.revolsys.geometry.model.coordinates.filter.PointOnLineSegment) NodeDistanceComparator(com.revolsys.geometry.graph.comparator.NodeDistanceComparator) ArrayList(java.util.ArrayList) List(java.util.List) Edge(com.revolsys.geometry.graph.Edge) LineSegment(com.revolsys.geometry.model.segment.LineSegment) PointOnLineSegment(com.revolsys.geometry.model.coordinates.filter.PointOnLineSegment)

Example 13 with Node

use of com.revolsys.geometry.graph.Node in project com.revolsys.open by revolsys.

the class MergeRecordsDialog method run.

public void run() {
    try {
        final List<LayerRecord> originalRecords = this.layer.getMergeableSelectedRecords();
        String errorMessage = "";
        final DataType geometryType = this.layer.getGeometryType();
        this.mergedRecords = new HashMap<>();
        if (originalRecords.size() < 2) {
            errorMessage = " at least two records must be selected to merge.";
        } else if (!DataTypes.LINE_STRING.equals(geometryType) && !DataTypes.MULTI_LINE_STRING.equals(geometryType)) {
            errorMessage = "Merging " + geometryType + " not currently supported";
        } else {
            final RecordGraph graph = new RecordGraph();
            for (final LayerRecord originalRecord : originalRecords) {
                Geometry geometry = originalRecord.getGeometry();
                if (geometry != null && !geometry.isEmpty()) {
                    geometry = this.layer.getGeometryFactory().geometry(LineString.class, geometry);
                    if (geometry instanceof LineString) {
                        final Record mergeableRecord = new ArrayRecord(originalRecord);
                        mergeableRecord.setGeometryValue(geometry);
                        this.mergeableToOiginalRecordMap.put(mergeableRecord, originalRecord);
                        graph.addEdge(mergeableRecord);
                    }
                }
            }
            for (final Node<Record> node : graph.nodes()) {
                if (node != null) {
                    final List<Edge<Record>> edges = node.getEdges();
                    if (edges.size() == 2) {
                        final Edge<Record> edge1 = edges.get(0);
                        final Record record1 = edge1.getObject();
                        final Edge<Record> edge2 = edges.get(1);
                        final Record record2 = edge2.getObject();
                        if (record1 != record2) {
                            final Record mergedRecord = this.layer.getMergedRecord(node, record1, record2);
                            graph.addEdge(mergedRecord);
                            edge1.remove();
                            edge2.remove();
                            final Set<LayerRecord> sourceRecords = new LinkedHashSet<>();
                            // TODO verify orientation to ensure they are in the correct
                            // order
                            // and see if they are reversed
                            CollectionUtil.addIfNotNull(sourceRecords, this.mergeableToOiginalRecordMap.get(record1));
                            CollectionUtil.addAllIfNotNull(sourceRecords, this.mergedRecords.remove(record1));
                            CollectionUtil.addIfNotNull(sourceRecords, this.mergeableToOiginalRecordMap.get(record2));
                            CollectionUtil.addAllIfNotNull(sourceRecords, this.mergedRecords.remove(record2));
                            this.mergedRecords.put(mergedRecord, sourceRecords);
                            replaceRecord(mergedRecord, record1);
                            replaceRecord(mergedRecord, record2);
                        }
                    }
                }
            }
        }
        final String message = errorMessage;
        Invoke.later(() -> setMergedRecords(message, this.mergedRecords));
    } catch (final Throwable e) {
        Logs.error(this, "Error " + this, e);
    }
}
Also used : RecordGraph(com.revolsys.geometry.graph.RecordGraph) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) Set(java.util.Set) ArrayRecord(com.revolsys.record.ArrayRecord) Node(com.revolsys.geometry.graph.Node) LineString(com.revolsys.geometry.model.LineString) Geometry(com.revolsys.geometry.model.Geometry) LineString(com.revolsys.geometry.model.LineString) DataType(com.revolsys.datatype.DataType) Record(com.revolsys.record.Record) ArrayRecord(com.revolsys.record.ArrayRecord) LayerRecord(com.revolsys.swing.map.layer.record.LayerRecord) List(java.util.List) LayerRecord(com.revolsys.swing.map.layer.record.LayerRecord) Edge(com.revolsys.geometry.graph.Edge)

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