/** * populates the model with the relation members in relation my and their * * @param my my relation. Must not be null. * @param their their relation. Must not be null. * @throws IllegalArgumentException if my is null * @throws IllegalArgumentException if their is null */ public void populate(Relation my, Relation their) { this.myDataset = my.getDataSet(); CheckParameterUtil.ensureParameterNotNull(my, "my"); CheckParameterUtil.ensureParameterNotNull(their, "their"); getMergedEntries().clear(); getMyEntries().clear(); getTheirEntries().clear(); for (RelationMember n : my.getMembers()) { getMyEntries().add(n); } for (RelationMember n : their.getMembers()) { getTheirEntries().add(n); } if (myAndTheirEntriesEqual()) { for (RelationMember m : getMyEntries()) { getMergedEntries().add(cloneEntryForMergedList(m)); } setFrozen(true); } else { setFrozen(false); } fireModelDataChanged(); }
/** * Removes a given OsmPrimitive from all relations * * @param osm Element to remove from all relations * @return List of relations with roles the primitives was part of */ private List<RelationRole> removeFromAllRelations(OsmPrimitive osm) { List<RelationRole> result = new ArrayList<RelationRole>(); for (Relation r : Main.main.getCurrentDataSet().getRelations()) { if (r.isDeleted()) { continue; } for (RelationMember rm : r.getMembers()) { if (rm.getMember() != osm) { continue; } Relation newRel = new Relation(r); List<RelationMember> members = newRel.getMembers(); members.remove(rm); newRel.setMembers(members); cmds.add(new ChangeCommand(r, newRel)); RelationRole saverel = new RelationRole(r, rm.getRole()); if (!result.contains(saverel)) { result.add(saverel); } break; } } commitCommands(marktr("Removed Element from Relations")); return result; }
@Override public void mouseClicked(MouseEvent e) { if (Main.main.getCurrentDataSet() == null) return; Way way = Main.map.mapView.getNearestWay(e.getPoint(), OsmPrimitive.isUsablePredicate); Collection<Relation> selectedRelations = Main.main.getCurrentDataSet().getSelectedRelations(); if (way != null) { if (selectedRelations.isEmpty()) { JOptionPane.showMessageDialog(Main.parent, tr("No relation is selected")); } for (OsmPrimitive rel : selectedRelations) { Relation r = (Relation) rel; RelationMember foundMember = null; for (RelationMember member : r.getMembers()) { if (member.getMember() == way) { foundMember = member; break; } } if (foundMember != null) { Main.main.undoRedo.add(new RemoveRelationMemberCommand(r, new RelationMember("", way))); } else { Relation newRelation = new Relation(r); newRelation.addMember(new RelationMember("", way)); Main.main.undoRedo.add(new ChangeCommand(r, newRelation)); } } } }
void addRelationMembers(Relation r) { add(trn("{0} Member: ", "{0} Members: ", r.getMembersCount(), r.getMembersCount())); for (RelationMember m : r.getMembers()) { s.append(INDENT).append(INDENT); addHeadline(m.getMember()); s.append(tr(" as \"{0}\"", m.getRole())); s.append(NL); } }
@Override public void visit(Relation r) { if (!r.isUsable() || r.hasIncompleteMembers()) return; List<RelationMember> rMembers = r.getMembers(); Map<String, String> rkeys = r.getKeys(); for (String key : ignoreKeys) rkeys.remove(key); RelationPair rKey = new RelationPair(rMembers, rkeys); relations.put(rKey, r); relations_nokeys.put(rMembers, r); }
private boolean hasOnlyIncompleteMembers( Relation r, Collection<OsmPrimitive> toPurge, Collection<? extends OsmPrimitive> moreToPurge) { for (RelationMember m : r.getMembers()) { if (!m.getMember().isIncomplete() && !toPurge.contains(m.getMember()) && !moreToPurge.contains(m.getMember())) return false; } return true; }
@Override protected boolean accept(Relation relation) { boolean complete = true; for (org.openstreetmap.josm.data.osm.RelationMember member : relation.getMembers()) { if (member.getMember() == null || member.getMember().isDeleted() || member.getMember().isIncomplete()) { complete = false; } } return complete && super.accept(relation); }
/** * Adds the previously removed relations again to the outer way. If there are multiple * multipolygon relations where the joined areas were in "outer" role a new relation is created * instead with all members of both. This function depends on multigon relations to be valid * already, it won't fix them. * * @param rels List of relations with roles the (original) ways were part of * @param outer The newly created outer area/way * @param ownMultipol elements to directly add as outer * @param relationsToDelete set of relations to delete. */ private void fixRelations( List<RelationRole> rels, Way outer, RelationRole ownMultipol, Set<Relation> relationsToDelete) { List<RelationRole> multiouters = new ArrayList<RelationRole>(); if (ownMultipol != null) { multiouters.add(ownMultipol); } for (RelationRole r : rels) { if (r.rel.isMultipolygon() && r.role.equalsIgnoreCase("outer")) { multiouters.add(r); continue; } // Add it back! Relation newRel = new Relation(r.rel); newRel.addMember(new RelationMember(r.role, outer)); cmds.add(new ChangeCommand(r.rel, newRel)); } Relation newRel; switch (multiouters.size()) { case 0: return; case 1: // Found only one to be part of a multipolygon relation, so just add it back as well newRel = new Relation(multiouters.get(0).rel); newRel.addMember(new RelationMember(multiouters.get(0).role, outer)); cmds.add(new ChangeCommand(multiouters.get(0).rel, newRel)); return; default: // Create a new relation with all previous members and (Way)outer as outer. newRel = new Relation(); for (RelationRole r : multiouters) { // Add members for (RelationMember rm : r.rel.getMembers()) if (!newRel.getMembers().contains(rm)) { newRel.addMember(rm); } // Add tags for (String key : r.rel.keySet()) { newRel.put(key, r.rel.get(key)); } // Delete old relation relationsToDelete.add(r.rel); } newRel.addMember(new RelationMember("outer", outer)); cmds.add(new AddCommand(newRel)); } }
public void build(Collection<Relation> relations) { this.relations = new HashSet<Relation>(); for (Relation relation : relations) { if (!relation.isNewOrUndeleted()) { continue; } this.relations.add(relation); for (RelationMember m : relation.getMembers()) { if (m.isRelation() && m.getMember().isNewOrUndeleted()) { addDependency(relation, (Relation) m.getMember()); } } } }
protected Set<Long> getNodeIdsInRelation(Relation r) { HashSet<Long> ret = new HashSet<Long>(); if (r == null) return ret; for (RelationMember m : r.getMembers()) { if (m.isNode()) { ret.add(m.getMember().getId()); } else if (m.isWay()) { ret.addAll(getNodeIdsInWay(m.getWay())); } else if (m.isRelation()) { ret.addAll(getNodeIdsInRelation(m.getRelation())); } } return ret; }
public static String generateRelationMemberSigtext(TrustRelation trust, String memID) { Relation r = (Relation) trust.getOsmPrimitive(); List<RelationMember> members = r.getMembers(); RelationMember member = null; for (RelationMember m : members) { if (TrustOsmPrimitive.createUniqueObjectIdentifier(m.getMember()).equals(memID)) { member = m; break; } } if (member == null) return ""; String sigtext = "RelID=" + r.getUniqueId() + "\n"; sigtext += TrustOsmPrimitive.createUniqueObjectIdentifier(member.getMember()) + "," + member.getRole(); return sigtext; }
@Override public void startTest(ProgressMonitor monitor) { super.startTest(monitor); multipolygonways = new LinkedList<Way>(); for (Relation r : Main.main.getCurrentDataSet().getRelations()) { if (r.isUsable() && r.isMultipolygon()) { for (RelationMember m : r.getMembers()) { if (m.getMember() != null && m.getMember() instanceof Way && m.getMember().isUsable() && !m.getMember().isTagged()) { multipolygonways.add((Way) m.getMember()); } } } } }
/** * Replies the subset of relations in <code>relations</code> which are not referring to any new * relation * * @param relations a list of relations * @return the subset of relations in <code>relations</code> which are not referring to any new * relation */ protected List<Relation> filterRelationsNotReferringToNewRelations( Collection<Relation> relations) { List<Relation> ret = new LinkedList<Relation>(); for (Relation relation : relations) { boolean refersToNewRelation = false; for (RelationMember m : relation.getMembers()) { if (m.isRelation() && m.getMember().isNewOrUndeleted()) { refersToNewRelation = true; break; } } if (!refersToNewRelation) { ret.add(relation); } } return ret; }
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); }
/** * Fix the error by removing all but one instance of duplicate relations * * @param testError The error to fix, must be of type {@link #DUPLICATE_RELATION} */ @Override public Command fixError(TestError testError) { if (testError.getCode() == SAME_RELATION) return null; Collection<? extends OsmPrimitive> sel = testError.getPrimitives(); HashSet<Relation> rel_fix = new HashSet<Relation>(); for (OsmPrimitive osm : sel) if (osm instanceof Relation && !osm.isDeleted()) { rel_fix.add((Relation) osm); } if (rel_fix.size() < 2) return null; long idToKeep = 0; Relation relationToKeep = rel_fix.iterator().next(); // Only one relation will be kept - the one with lowest positive ID, if such exist // or one "at random" if no such exists. Rest of the relations will be deleted for (Relation w : rel_fix) { if (!w.isNew()) { if (idToKeep == 0 || w.getId() < idToKeep) { idToKeep = w.getId(); relationToKeep = w; } } } // Find the relation that is member of one or more relations. (If any) Relation relationWithRelations = null; List<Relation> rel_ref = null; for (Relation w : rel_fix) { List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class); if (!rel.isEmpty()) { if (relationWithRelations != null) throw new AssertionError( "Cannot fix duplicate relations: More than one relation is member of another relation."); relationWithRelations = w; rel_ref = rel; } } Collection<Command> commands = new LinkedList<Command>(); // Fix relations. if (relationWithRelations != null && relationToKeep != relationWithRelations) { for (Relation rel : rel_ref) { Relation newRel = new Relation(rel); for (int i = 0; i < newRel.getMembers().size(); ++i) { RelationMember m = newRel.getMember(i); if (relationWithRelations.equals(m.getMember())) { newRel.setMember(i, new RelationMember(m.getRole(), relationToKeep)); } } commands.add(new ChangeCommand(rel, newRel)); } } // Delete all relations in the list rel_fix.remove(relationToKeep); commands.add(new DeleteCommand(rel_fix)); return new SequenceCommand(tr("Delete duplicate relations"), commands); }
/** * This method analyzes multipolygon relationships of given ways and collects addition inner ways * to consider. * * @param selectedWays the selected ways * @return list of polygons, or null if too complex relation encountered. */ private List<Multipolygon> collectMultipolygons(List<Way> selectedWays) { List<Multipolygon> result = new ArrayList<Multipolygon>(); // prepare the lists, to minimize memory allocation. List<Way> outerWays = new ArrayList<Way>(); List<Way> innerWays = new ArrayList<Way>(); Set<Way> processedOuterWays = new LinkedHashSet<Way>(); Set<Way> processedInnerWays = new LinkedHashSet<Way>(); for (Relation r : OsmPrimitive.getParentRelations(selectedWays)) { if (r.isDeleted() || !r.isMultipolygon()) { continue; } boolean hasKnownOuter = false; outerWays.clear(); innerWays.clear(); for (RelationMember rm : r.getMembers()) { if (rm.getRole().equalsIgnoreCase("outer")) { outerWays.add(rm.getWay()); hasKnownOuter |= selectedWays.contains(rm.getWay()); } else if (rm.getRole().equalsIgnoreCase("inner")) { innerWays.add(rm.getWay()); } } if (!hasKnownOuter) { continue; } if (outerWays.size() > 1) { new Notification( tr("Sorry. Cannot handle multipolygon relations with multiple outer ways.")) .setIcon(JOptionPane.INFORMATION_MESSAGE) .show(); return null; } Way outerWay = outerWays.get(0); // retain only selected inner ways innerWays.retainAll(selectedWays); if (processedOuterWays.contains(outerWay)) { new Notification( tr("Sorry. Cannot handle way that is outer in multiple multipolygon relations.")) .setIcon(JOptionPane.INFORMATION_MESSAGE) .show(); return null; } if (processedInnerWays.contains(outerWay)) { new Notification( tr( "Sorry. Cannot handle way that is both inner and outer in multipolygon relations.")) .setIcon(JOptionPane.INFORMATION_MESSAGE) .show(); return null; } for (Way way : innerWays) { if (processedOuterWays.contains(way)) { new Notification( tr( "Sorry. Cannot handle way that is both inner and outer in multipolygon relations.")) .setIcon(JOptionPane.INFORMATION_MESSAGE) .show(); return null; } if (processedInnerWays.contains(way)) { new Notification( tr("Sorry. Cannot handle way that is inner in multiple multipolygon relations.")) .setIcon(JOptionPane.INFORMATION_MESSAGE) .show(); return null; } } processedOuterWays.add(outerWay); processedInnerWays.addAll(innerWays); Multipolygon pol = new Multipolygon(outerWay); pol.innerWays.addAll(innerWays); result.add(pol); } // add remaining ways, not in relations for (Way way : selectedWays) { if (processedOuterWays.contains(way) || processedInnerWays.contains(way)) { continue; } result.add(new Multipolygon(way)); } return result; }
/** Fix the error by removing all but one instance of duplicate ways */ @Override public Command fixError(TestError testError) { Collection<? extends OsmPrimitive> sel = testError.getPrimitives(); HashSet<Way> ways = new HashSet<Way>(); for (OsmPrimitive osm : sel) { if (osm instanceof Way) { ways.add((Way) osm); } } if (ways.size() < 2) return null; long idToKeep = 0; Way wayToKeep = ways.iterator().next(); // Only one way will be kept - the one with lowest positive ID, if such exist // or one "at random" if no such exists. Rest of the ways will be deleted for (Way w : ways) { if (!w.isNew()) { if (idToKeep == 0 || w.getId() < idToKeep) { idToKeep = w.getId(); wayToKeep = w; } } } // Find the way that is member of one or more relations. (If any) Way wayWithRelations = null; List<Relation> relations = null; for (Way w : ways) { List<Relation> rel = OsmPrimitive.getFilteredList(w.getReferrers(), Relation.class); if (!rel.isEmpty()) { if (wayWithRelations != null) throw new AssertionError( "Cannot fix duplicate Ways: More than one way is relation member."); wayWithRelations = w; relations = rel; } } Collection<Command> commands = new LinkedList<Command>(); // Fix relations. if (wayWithRelations != null && wayToKeep != wayWithRelations) { for (Relation rel : relations) { Relation newRel = new Relation(rel); for (int i = 0; i < newRel.getMembers().size(); ++i) { RelationMember m = newRel.getMember(i); if (wayWithRelations.equals(m.getMember())) { newRel.setMember(i, new RelationMember(m.getRole(), wayToKeep)); } } commands.add(new ChangeCommand(rel, newRel)); } } // Delete all ways in the list // Note: nodes are not deleted, these can be detected and deleted at next pass ways.remove(wayToKeep); commands.add(new DeleteCommand(ways)); return new SequenceCommand(tr("Delete duplicate ways"), commands); }
private DataSet parse(InputStream in, ProgressMonitor instance) throws JAXBException { root = unmarshal(ChouettePTNetworkType.class, in); Relation network = createNetwork(root.getPTNetwork()); // Parsing Stop areas for (StopArea sa : root.getChouetteArea().getStopArea()) { if (sa.getStopAreaExtension().getAreaType().equals(ChouetteAreaType.COMMERCIAL_STOP_POINT)) { Relation stopArea = createStopArea(sa); stopArea.put("name", sa.getName()); for (String childId : sa.getContains()) { if (childId.contains("StopArea")) { StopArea child = findStopArea(childId); if (child == null) { Main.warn("Cannot find StopArea: " + childId); } else { if (child .getStopAreaExtension() .getAreaType() .equals(ChouetteAreaType.BOARDING_POSITION)) { for (String grandchildId : child.getContains()) { if (grandchildId.contains("StopPoint")) { StopPoint grandchild = findStopPoint(grandchildId); if (grandchild == null) { Main.warn("Cannot find StopPoint: " + grandchildId); } else { if (grandchild.getLongLatType().equals(LongLatTypeType.WGS_84)) { Node platform = createPlatform(grandchild); stopArea.addMember(new RelationMember(OSM_PLATFORM, platform)); } else { Main.warn("Unsupported long/lat type: " + grandchild.getLongLatType()); } } } else { Main.warn("Unsupported grandchild: " + grandchildId); } } String centroidId = child.getCentroidOfArea(); AreaCentroid areaCentroid = findAreaCentroid(centroidId); if (areaCentroid == null) { Main.warn("Cannot find AreaCentroid: " + centroidId); } else if (!areaCentroid.getLongLatType().equals(LongLatTypeType.WGS_84)) { Main.warn("Unsupported long/lat type: " + areaCentroid.getLongLatType()); } else { for (RelationMember member : stopArea.getMembers()) { // Fix stop coordinates if needed if (member.getRole().equals(OSM_PLATFORM) && isNullLatLon(member.getNode().getCoor())) { member.getNode().setCoor(createLatLon(areaCentroid)); } } } } else { Main.warn("Unsupported child type: " + child.getStopAreaExtension().getAreaType()); } } } else if (childId.contains("StopPoint")) { StopPoint child = findStopPoint(childId); if (child == null) { Main.warn("Cannot find StopPoint: " + childId); } else { // TODO Main.info("TODO: handle StopPoint " + childId); } } else { Main.warn("Unsupported child: " + childId); } } } else if (sa.getStopAreaExtension() .getAreaType() .equals(ChouetteAreaType.BOARDING_POSITION)) { // Main.info("skipping StopArea with type "+sa.getStopAreaExtension().getAreaType()+": // "+sa.getObjectId()); } else { Main.warn("Unsupported StopArea type: " + sa.getStopAreaExtension().getAreaType()); } } Relation routeMaster = createRouteMaster(root.getChouetteLineDescription().getLine()); network.addMember(new RelationMember(null, routeMaster)); for (ChouetteRoute cr : root.getChouetteLineDescription().getChouetteRoute()) { Relation route = createRoute(cr); routeMaster.addMember(new RelationMember(null, route)); for (String id : cr.getPtLinkId()) { PTLinkType ptlink = findPtLink(id); if (ptlink == null) { Main.warn("Cannot find PTLinkType: " + id); } else { /*StopPoint start = findStopPoint(ptlink.getStartOfLink()); StopPoint end = findStopPoint(ptlink.getEndOfLink());*/ OsmPrimitive start = tridentObjects.get(ptlink.getStartOfLink()); OsmPrimitive end = tridentObjects.get(ptlink.getEndOfLink()); if (start == null) { Main.warn("Cannot find start StopPoint: " + ptlink.getStartOfLink()); } else if (start.get(OSM_PUBLIC_TRANSPORT).equals(OSM_STOP) || start.get(OSM_PUBLIC_TRANSPORT).equals(OSM_PLATFORM)) { addStopToRoute(route, start); } if (end == null) { Main.warn("Cannot find end StopPoint: " + ptlink.getEndOfLink()); } else if (end.get(OSM_PUBLIC_TRANSPORT).equals(OSM_STOP) || end.get(OSM_PUBLIC_TRANSPORT).equals(OSM_PLATFORM)) { addStopToRoute(route, end); } } } } return ds; }
@Override public Iterable<RelationMember> getMembers(Relation relation) { return relation.getMembers(); }
@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); } } } } }