diff --git a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/LoopLineMerger.java b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/LoopLineMerger.java index 47301c04e3..a76048401d 100644 --- a/planetiler-core/src/main/java/com/onthegomap/planetiler/util/LoopLineMerger.java +++ b/planetiler-core/src/main/java/com/onthegomap/planetiler/util/LoopLineMerger.java @@ -56,7 +56,7 @@ private void add(LineString lineString) { } - public static Coordinate roundCoordinate(Coordinate cooridnate) { + protected static Coordinate roundCoordinate(Coordinate cooridnate) { Coordinate result = new Coordinate(cooridnate); double multiplier = 16.0; @@ -67,7 +67,7 @@ public static Coordinate roundCoordinate(Coordinate cooridnate) { return result; } - public static List split(LineString lineString) { + protected static List split(LineString lineString) { List segments = new ArrayList<>(); Coordinate[] coordinates = lineString.getCoordinates(); @@ -82,7 +82,7 @@ public static List split(LineString lineString) { return segments; } - public static LineString concat(LineString A, LineString B) { + protected static LineString concat(LineString A, LineString B) { List coordinates = new ArrayList<>(); List coordsA = List.of(A.getCoordinates()); @@ -175,7 +175,7 @@ private void removeLoops(double loopMinLength) { } } - private List> findAllPaths(Point start, Point end, double maxLength) { + protected List> findAllPaths(Point start, Point end, double maxLength) { List> allPaths = new ArrayList<>(); Queue> queue = new LinkedList<>(); @@ -245,7 +245,7 @@ private static double getLength(List lines) { return result; } - public static boolean hasPointAppearingMoreThanTwice(List lineStrings) { + protected static boolean hasPointAppearingMoreThanTwice(List lineStrings) { HashMap pointCountMap = new HashMap<>(); for (LineString line : lineStrings) { Point startPoint = line.getStartPoint(); @@ -320,50 +320,50 @@ public List getMergedLineStrings(double minLength, double loopMinLen return result; } -} - -class Node { - private Point point; - private List edges; - - public Node(Point point) { - this.point = point; - this.edges = new ArrayList<>(); - } - - public Point getPoint() { - return point; - } - public void setPoint(Point point) { - this.point = point; - } - - public List getEdges() { - return edges; - } - - public void addEdge(LineString edge) { - if (!edges.contains(edge) && !edges.contains(edge.reverse())) { - edges.add(edge); + class Node { + private Point point; + private List edges; + + public Node(Point point) { + this.point = point; + this.edges = new ArrayList<>(); } - } - - public void removeEdge(LineString edge) { - if (edges.contains(edge)) { - edges.remove(edge); - } else if (edges.contains(edge.reverse())) { - edges.remove(edge.reverse()); - } else { - // nothing to do + + public Point getPoint() { + return point; } - } - - @Override - public String toString() { - return "Node{" + - "point=" + point + - ", edges=" + edges + - '}'; - } + + public void setPoint(Point point) { + this.point = point; + } + + public List getEdges() { + return edges; + } + + public void addEdge(LineString edge) { + if (!edges.contains(edge) && !edges.contains(edge.reverse())) { + edges.add(edge); + } + } + + public void removeEdge(LineString edge) { + if (edges.contains(edge)) { + edges.remove(edge); + } else if (edges.contains(edge.reverse())) { + edges.remove(edge.reverse()); + } else { + // nothing to do + } + } + + @Override + public String toString() { + return "Node{" + + "point=" + point + + ", edges=" + edges + + '}'; + } + } } diff --git a/planetiler-core/src/test/java/com/onthegomap/planetiler/util/LoopLineMergerTest.java b/planetiler-core/src/test/java/com/onthegomap/planetiler/util/LoopLineMergerTest.java index 22cd184bcd..8b89cf93b1 100644 --- a/planetiler-core/src/test/java/com/onthegomap/planetiler/util/LoopLineMergerTest.java +++ b/planetiler-core/src/test/java/com/onthegomap/planetiler/util/LoopLineMergerTest.java @@ -1,5 +1,6 @@ package com.onthegomap.planetiler.util; import static com.onthegomap.planetiler.TestUtils.newLineString; +import static com.onthegomap.planetiler.TestUtils.newPoint; import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.List; @@ -240,5 +241,75 @@ void testMerge() { merger.getMergedLineStrings(15, -1) ); } + + @Test + void testHasPointAppearingMoreThanTwice() { + + // can revisit starting node once + assertEquals( + false, + LoopLineMerger.hasPointAppearingMoreThanTwice( + List.of( + newLineString(10, 0, 20, 0), + newLineString(20, 0, 20, 10), + newLineString(20, 10, 10, 0) + ) + ) + ); + + // cannot revisit starting node and continue on + assertEquals( + true, + LoopLineMerger.hasPointAppearingMoreThanTwice( + List.of( + newLineString(10, 0, 20, 0), + newLineString(20, 0, 20, 10), + newLineString(20, 10, 10, 0), + newLineString(10, 0, 10, 10) + ) + ) + ); + } + + @Test + void testFindAllPaths() { + // finds all paths and orders them by length + var merger = new LoopLineMerger(); + /** 10 20 30 + * 10 o-----o + * |\ | + * | \ | + * 20 o--o--o + */ + merger.add(newLineString(10, 10, 30, 10)); + merger.add(newLineString(10, 10, 10, 20)); + merger.add(newLineString(10, 10, 20, 20)); + merger.add(newLineString(10, 20, 20, 20)); + merger.add(newLineString(20, 20, 30, 20)); + merger.add(newLineString(30, 20, 30, 10)); + + var allPaths = merger.findAllPaths(newPoint(10, 10), newPoint(20, 20), 1000); + + assertEquals(3, allPaths.size()); + assertEquals( + List.of(newLineString(10, 10, 20, 20)), + allPaths.get(0) + ); + assertEquals( + List.of( + newLineString(10, 10, 10, 20), + newLineString(10, 20, 20, 20) + ), + allPaths.get(1) + ); + assertEquals( + List.of( + newLineString(10, 10, 30, 10), + newLineString(30, 10, 30, 20), + newLineString(30, 20, 20, 20) + ), + allPaths.get(2) + ); + } }