private List<List<Coordinate>> nodeLines(List<LineString> input) {
    Map<Coordinate, Integer> nodeCounts = new HashMap<>();
    List<List<Coordinate>> coords = new ArrayList<>(input.size());
    for (var line : input) {
      var coordinateSequence = line.getCoordinateSequence();
      List<Coordinate> snapped = new ArrayList<>();
      Coordinate last = null;
      for (int i = 0; i < coordinateSequence.size(); i++) {
        Coordinate current = new CoordinateXY(coordinateSequence.getX(i), coordinateSequence.getY(i));
        precisionModel.makePrecise(current);
        if (last == null || !last.equals(current)) {
          snapped.add(current);
          nodeCounts.merge(current, 1, Integer::sum);
        }
        last = current;
      }
      if (snapped.size() >= 2) {
        coords.add(snapped);
      }
    }

    List<List<Coordinate>> result = new ArrayList<>(input.size());
    for (var coordinateSequence : coords) {
      int start = 0;
      for (int i = 0; i < coordinateSequence.size(); i++) {
        Coordinate coordinate = coordinateSequence.get(i);
        if (i > 0 && i < coordinateSequence.size() - 1 && nodeCounts.get(coordinate) > 1) {
          result.add(coordinateSequence.subList(start, i + 1));
          start = i;
        }
      }
      if (start < coordinateSequence.size()) {
        var sublist = start == 0 ? coordinateSequence : coordinateSequence.subList(start, coordinateSequence.size());
        result.add(sublist);
      }
    }
    return result;
  }
Processes the added geometries and returns the merged linestrings.
<p>
Can be called more than once.
planetiler-core/src/main/java/com/onthegomap/planetiler/util/LoopLineMerger.java