/** * 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; }
protected Relation parseRelation() throws XMLStreamException { RelationData rd = new RelationData(); readCommon(rd); Relation r = new Relation(rd.getId(), rd.getVersion()); r.setVisible(rd.isVisible()); r.load(rd); externalIdMap.put(rd.getPrimitiveId(), r); Collection<RelationMemberData> members = new ArrayList<RelationMemberData>(); while (true) { int event = parser.next(); if (event == XMLStreamConstants.START_ELEMENT) { if (parser.getLocalName().equals("member")) { members.add(parseRelationMember(r)); } else if (parser.getLocalName().equals("tag")) { parseTag(r); } else { parseUnknown(); } } else if (event == XMLStreamConstants.END_ELEMENT) { break; } } if (r.isDeleted() && members.size() > 0) { System.out.println(tr("Deleted relation {0} contains members", r.getUniqueId())); members = new ArrayList<RelationMemberData>(); } relations.put(rd.getUniqueId(), members); return r; }
public void visit(Relation r) { if (r.isNewOrUndeleted() || r.isModified() || r.isDeleted()) { hull.add(r); for (OsmPrimitive p : r.getMemberPrimitives()) { // add new relation members. Don't include modified // relation members. r shouldn't refer to deleted primitives, // so wont check here for deleted primitives here // if (p.isNewOrUndeleted()) { p.visit(this); } } } }
/** * 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; }
/** * Determines if the given relation is listable in last relations. * * @param relation relation * @return {@code true} if relation is non null, not deleted, and in current dataset */ public static boolean isRelationListable(Relation relation) { return relation != null && !relation.isDeleted() && Main.main.getCurrentDataSet().containsRelation(relation); }
/** * Determines if the given relation is listable in last relations. * * @param relation relation * @return {@code true} if relation is non null, not deleted, and in current dataset */ public static boolean isRelationListable(Relation relation) { return relation != null && !relation.isDeleted() && Main.getLayerManager().getEditDataSet().containsRelation(relation); }