/** * Extract and store relation information based on the relation member * * @param src The relation member to store information about */ public RelMember(RelationMember src) { role = src.getRole(); type = src.getType(); rel_id = 0; coor = new ArrayList<LatLon>(); if (src.isNode()) { Node r = src.getNode(); tags = r.getKeys(); coor = new ArrayList<LatLon>(1); coor.add(r.getCoor()); } if (src.isWay()) { Way r = src.getWay(); tags = r.getKeys(); List<Node> wNodes = r.getNodes(); coor = new ArrayList<LatLon>(wNodes.size()); for (Node wNode : wNodes) { coor.add(wNode.getCoor()); } } if (src.isRelation()) { Relation r = src.getRelation(); tags = r.getKeys(); rel_id = r.getId(); coor = new ArrayList<LatLon>(); } }
/** * Populates the turn restriction editor model with a turn restriction. {@code turnRestriction} is * an arbitrary relation. A tag type=restriction isn't required. If it is missing, it is added * here. {@code turnRestriction} must not be null and it must belong to a dataset. * * @param turnRestriction the turn restriction * @throws IllegalArgumentException thrown if turnRestriction is null * @throws IllegalArgumentException thrown if turnRestriction doesn't belong to a dataset */ public void populate(Relation turnRestriction) { CheckParameterUtil.ensureParameterNotNull(turnRestriction, "turnRestriction"); if (turnRestriction.getDataSet() != null && turnRestriction.getDataSet() != layer.data) { throw new IllegalArgumentException( // don't translate - it's a technical message MessageFormat.format( "turnRestriction {0} must not belong to a different dataset than the dataset of layer ''{1}''", turnRestriction.getId(), layer.getName())); } initFromTurnRestriction(turnRestriction); }
private void formatRelationNameAndType( Relation relation, StringBuilder result, TaggingPreset preset) { if (preset == null) { result.append(getRelationTypeName(relation)); String relationName = getRelationName(relation); if (relationName == null) { relationName = Long.toString(relation.getId()); } else { relationName = "\"" + relationName + "\""; } result.append(" (").append(relationName).append(", "); } else { preset.nameTemplate.appendText(result, relation); result.append("("); } }
protected void loadIncompleteRelationMembers() throws OsmTransferException { // if incomplete relation members exist, download them too for (Relation r : ds.getRelations()) { if (canceled) return; // Relations may be incomplete in case of nested relations if child relations are accessed // before their parent // (it may happen because "relations" has no deterministic sort order, see #10388) if (r.isIncomplete() || r.hasIncompleteMembers()) { synchronized (this) { if (canceled) return; objectReader = new OsmServerObjectReader(r.getId(), OsmPrimitiveType.RELATION, fullRelation); } DataSet theirDataSet = objectReader.parseOsm( progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); synchronized (this) { objectReader = null; } new DataSetMerger(ds, theirDataSet).merge(); } } }
/** * 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); }
@Test public void testBackrefrenceForRelation_Full() throws OsmTransferException { Relation r = lookupRelation(ds, 1); assertNotNull(r); // way with name "relation-1" is referred to by four relations: // relation-6, relation-7, relation-8, relation-9 // OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(r); reader.setReadFull(true); DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE); Set<Long> referringRelationsIds = new HashSet<Long>(); r = lookupRelation(referers, 6); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); r = lookupRelation(referers, 7); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); r = lookupRelation(referers, 8); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); r = lookupRelation(referers, 9); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); // all relations are fully loaded // for (Relation r1 : referers.getRelations()) { assertEquals(false, r1.isIncomplete()); } // make sure we read all ways referred to by parent relations. These // ways are completely read after reading the relations // Set<Long> expectedWayIds = new HashSet<Long>(); for (RelationMember m : lookupRelation(ds, 6).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (RelationMember m : lookupRelation(ds, 7).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (RelationMember m : lookupRelation(ds, 8).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (RelationMember m : lookupRelation(ds, 9).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (long id : expectedWayIds) { Way w = (Way) referers.getPrimitiveById(id, OsmPrimitiveType.WAY); assertNotNull(w); assertEquals(false, w.isIncomplete()); } Set<Long> expectedNodeIds = new HashSet<Long>(); for (int i = 6; i < 10; i++) { Relation r1 = lookupRelation(ds, i); expectedNodeIds.addAll(getNodeIdsInRelation(r1)); } assertEquals(expectedNodeIds.size(), referers.getNodes().size()); for (Node n : referers.getNodes()) { assertEquals(true, expectedNodeIds.contains(n.getId())); } }
@Test public void testBackrefrenceForRelation() throws OsmTransferException { Relation r = lookupRelation(ds, 1); assertNotNull(r); // way with name "relation-1" is referred to by four relations: // relation-6, relation-7, relation-8, relation-9 // OsmServerBackreferenceReader reader = new OsmServerBackreferenceReader(r); reader.setReadFull(false); DataSet referers = reader.parseOsm(NullProgressMonitor.INSTANCE); Set<Long> referringRelationsIds = new HashSet<Long>(); r = lookupRelation(referers, 6); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); r = lookupRelation(referers, 7); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); r = lookupRelation(referers, 8); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); r = lookupRelation(referers, 9); assertNotNull(r); assertEquals(false, r.isIncomplete()); referringRelationsIds.add(r.getId()); for (Relation r1 : referers.getRelations()) { if (!referringRelationsIds.contains(r1.getId())) { assertEquals(true, r1.isIncomplete()); } } // make sure we read all ways referred to by parent relations. These // ways are incomplete after reading. // Set<Long> expectedWayIds = new HashSet<Long>(); for (RelationMember m : lookupRelation(ds, 6).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (RelationMember m : lookupRelation(ds, 7).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (RelationMember m : lookupRelation(ds, 8).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } for (RelationMember m : lookupRelation(ds, 9).getMembers()) { if (m.isWay()) { expectedWayIds.add(m.getMember().getId()); } } assertEquals(expectedWayIds.size(), referers.getWays().size()); for (Way w1 : referers.getWays()) { assertEquals(true, expectedWayIds.contains(w1.getId())); assertEquals(true, w1.isIncomplete()); } // make sure we didn't read any nodes // assertEquals(0, referers.getNodes().size()); }