public static Route create(List<Way> ws, Node end) { final List<Segment> segments = new ArrayList<Segment>(ws.size()); for (Way w : ws) { if (!w.isFirstLastNode(end)) { throw new IllegalArgumentException("Ways must be ordered."); } final Node start = Utils.getOppositeEnd(w, end); segments.add(0, new Segment(start, w, end)); end = start; } return new Route(segments); }
/** * Determines if ways can be joined into a polygon. * * @param ways The ways collection to check * @return true if all ways can be joined into a polygon */ protected static boolean checkWaysArePolygon(Collection<Way> ways) { // For each way, nodes strictly between first and last should't be reference by an other way for (Way way : ways) { for (Node node : way.getNodes()) { if (way.isFirstLastNode(node)) continue; for (Way wayOther : ways) { if (way == wayOther) continue; if (node.getReferrers().contains(wayOther)) return false; } } } // Test if ways can be joined Way currentWay = null; Node startNode = null, endNode = null; int used = 0; while (true) { Way nextWay = null; for (Way w : ways) { if (w.isClosed()) return ways.size() == 1; if (w == currentWay) continue; if (currentWay == null) { nextWay = w; startNode = w.firstNode(); endNode = w.lastNode(); break; } if (w.firstNode() == endNode) { nextWay = w; endNode = w.lastNode(); break; } if (w.lastNode() == endNode) { nextWay = w; endNode = w.firstNode(); break; } } if (nextWay == null) return false; used += 1; currentWay = nextWay; if (endNode == startNode) return used == ways.size(); } }
static SplitWayResult doSplitWay( OsmDataLayer layer, Way way, Way wayToKeep, List<Way> newWays, List<OsmPrimitive> newSelection) { Collection<Command> commandList = new ArrayList<>(newWays.size()); Collection<String> nowarnroles = Main.pref.getCollection( "way.split.roles.nowarn", Arrays.asList( "outer", "inner", "forward", "backward", "north", "south", "east", "west")); // Change the original way final Way changedWay = new Way(way); changedWay.setNodes(wayToKeep.getNodes()); commandList.add(new ChangeCommand(way, changedWay)); if (!newSelection.contains(way)) { newSelection.add(way); } newWays.remove(wayToKeep); for (Way wayToAdd : newWays) { commandList.add(new AddCommand(layer, wayToAdd)); newSelection.add(wayToAdd); } boolean warnmerole = false; boolean warnme = false; // now copy all relations to new way also for (Relation r : OsmPrimitive.getFilteredList(way.getReferrers(), Relation.class)) { if (!r.isUsable()) { continue; } Relation c = null; String type = r.get("type"); if (type == null) { type = ""; } int i_c = 0, i_r = 0; List<RelationMember> relationMembers = r.getMembers(); for (RelationMember rm : relationMembers) { if (rm.isWay() && rm.getMember() == way) { boolean insert = true; if ("restriction".equals(type)) { /* this code assumes the restriction is correct. No real error checking done */ String role = rm.getRole(); if ("from".equals(role) || "to".equals(role)) { OsmPrimitive via = null; for (RelationMember rmv : r.getMembers()) { if ("via".equals(rmv.getRole())) { via = rmv.getMember(); } } List<Node> nodes = new ArrayList<>(); if (via != null) { if (via instanceof Node) { nodes.add((Node) via); } else if (via instanceof Way) { nodes.add(((Way) via).lastNode()); nodes.add(((Way) via).firstNode()); } } Way res = null; for (Node n : nodes) { if (changedWay.isFirstLastNode(n)) { res = way; } } if (res == null) { for (Way wayToAdd : newWays) { for (Node n : nodes) { if (wayToAdd.isFirstLastNode(n)) { res = wayToAdd; } } } if (res != null) { if (c == null) { c = new Relation(r); } c.addMember(new RelationMember(role, res)); c.removeMembersFor(way); insert = false; } } else { insert = false; } } else if (!"via".equals(role)) { warnme = true; } } else if (!("route".equals(type)) && !("multipolygon".equals(type))) { warnme = true; } if (c == null) { c = new Relation(r); } if (insert) { if (rm.hasRole() && !nowarnroles.contains(rm.getRole())) { warnmerole = true; } Boolean backwards = null; int k = 1; while (i_r - k >= 0 || i_r + k < relationMembers.size()) { if ((i_r - k >= 0) && relationMembers.get(i_r - k).isWay()) { Way w = relationMembers.get(i_r - k).getWay(); if ((w.lastNode() == way.firstNode()) || w.firstNode() == way.firstNode()) { backwards = Boolean.FALSE; } else if ((w.firstNode() == way.lastNode()) || w.lastNode() == way.lastNode()) { backwards = Boolean.TRUE; } break; } if ((i_r + k < relationMembers.size()) && relationMembers.get(i_r + k).isWay()) { Way w = relationMembers.get(i_r + k).getWay(); if ((w.lastNode() == way.firstNode()) || w.firstNode() == way.firstNode()) { backwards = Boolean.TRUE; } else if ((w.firstNode() == way.lastNode()) || w.lastNode() == way.lastNode()) { backwards = Boolean.FALSE; } break; } k++; } int j = i_c; for (Way wayToAdd : newWays) { RelationMember em = new RelationMember(rm.getRole(), wayToAdd); j++; if ((backwards != null) && backwards) { c.addMember(i_c, em); } else { c.addMember(j, em); } } i_c = j; } } i_c++; i_r++; } if (c != null) { commandList.add(new ChangeCommand(layer, r, c)); } } if (warnmerole) { new Notification( tr( "A role based relation membership was copied to all new ways.<br>You should verify this and correct it when necessary.")) .setIcon(JOptionPane.WARNING_MESSAGE) .show(); } else if (warnme) { new Notification( tr( "A relation membership was copied to all new ways.<br>You should verify this and correct it when necessary.")) .setIcon(JOptionPane.WARNING_MESSAGE) .show(); } return new SplitWayResult( new SequenceCommand( /* for correct i18n of plural forms - see #9110 */ trn( "Split way {0} into {1} part", "Split way {0} into {1} parts", newWays.size(), way.getDisplayName(DefaultNameFormatter.getInstance()), newWays.size()), commandList), newSelection, way, newWays); }