Esempio n. 1
0
  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);
  }
Esempio n. 2
0
 /**
  * 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();
   }
 }
Esempio n. 3
0
  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);
  }