@Test public void testMultiGet10Relations() throws OsmTransferException { MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader(); ArrayList<Relation> relations = new ArrayList<>(ds.getRelations()); for (int i = 0; i < 10; i++) { reader.append(relations.get(i)); } DataSet out = reader.parseOsm(NullProgressMonitor.INSTANCE); assertEquals(10, out.getRelations().size()); for (Relation r1 : out.getRelations()) { Relation r2 = (Relation) ds.getPrimitiveById(r1); assertNotNull(r2); assertEquals(r2.getMembersCount(), r1.getMembersCount()); assertEquals(r2.get("name"), r2.get("name")); } assertTrue(reader.getMissingPrimitives().isEmpty()); }
static List<Double> loadLengths(Relation r, String key, double lengthBound) { final List<Double> result = new ArrayList<Double>(); if (r != null && r.get(key) != null) { for (String s : Constants.SPLIT_PATTERN.split(r.get(key))) { // TODO what should the exact input be (there should probably be // a unit (m)) final Double length = Double.parseDouble(s.trim()); if (length > lengthBound) { result.add(length); } } } return result; }
@Override public void visit(Relation r) { getAndCheckAssociatedStreets(r); if (r.hasTag("type", ASSOCIATED_STREET)) { // Used to count occurences of each house number in order to find duplicates Map<String, List<OsmPrimitive>> map = new HashMap<String, List<OsmPrimitive>>(); // Used to detect different street names String relationName = r.get("name"); Set<OsmPrimitive> wrongStreetNames = new HashSet<OsmPrimitive>(); // Used to check distance Set<OsmPrimitive> houses = new HashSet<OsmPrimitive>(); Set<Way> street = new HashSet<Way>(); for (RelationMember m : r.getMembers()) { String role = m.getRole(); OsmPrimitive p = m.getMember(); if (role.equals("house")) { houses.add(p); String number = p.get(ADDR_HOUSE_NUMBER); if (number != null) { number = number.trim().toUpperCase(); List<OsmPrimitive> list = map.get(number); if (list == null) { map.put(number, list = new ArrayList<OsmPrimitive>()); } list.add(p); } } else if (role.equals("street")) { if (p instanceof Way) { street.add((Way) p); } if (relationName != null && p.hasKey("name") && !relationName.equals(p.get("name"))) { if (wrongStreetNames.isEmpty()) { wrongStreetNames.add(r); } wrongStreetNames.add(p); } } } // Report duplicate house numbers String description_en = marktr("House number ''{0}'' duplicated"); for (String key : map.keySet()) { List<OsmPrimitive> list = map.get(key); if (list.size() > 1) { errors.add( new AddressError( DUPLICATE_HOUSE_NUMBER, list, tr("Duplicate house numbers"), tr(description_en, key), description_en)); } } // Report wrong street names if (!wrongStreetNames.isEmpty()) { errors.add( new AddressError( MULTIPLE_STREET_NAMES, wrongStreetNames, tr("Multiple street names in relation"))); } // Report addresses too far away if (!street.isEmpty()) { for (OsmPrimitive house : houses) { if (house.isUsable()) { checkDistance(house, street); } } } } }
protected static Relation lookupRelation(DataSet ds, int i) { for (Relation r : ds.getRelations()) { if (("relation-" + i).equals(r.get("name"))) return r; } return null; }
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); }