@Override public RelationMemberList allKnownOsmMembers() { return membersFor(attribute(Relation::allKnownOsmMembers).asBean()); }
public static CompleteRelation from(final Relation relation) { return new CompleteRelation(relation.getIdentifier(), relation.getTags(), relation.bounds(), relation.members().asBean(), relation.allRelationsWithSameOsmIdentifier().stream().map(Relation::getIdentifier) .collect(Collectors.toList()), relation.allKnownOsmMembers().asBean(), relation.osmRelationIdentifier(), relation.relations().stream().map(Relation::getIdentifier) .collect(Collectors.toSet())); }
/** * Assign this {@link CompleteRelation} with members. * <p> * In case this {@link CompleteRelation} is created from an existing relation, and the new * member list has had some existing members removed, use * {@link #withMembersAndSource(RelationMemberList, Relation)} * * @param members * The full members of the Relation * @return This */ public CompleteRelation withMembers(final RelationMemberList members) { return withMembers(members.asBean(), members.bounds()); }
/** * Here the members have to be full so the new bounds can be computed from them. * * @param members * The full members of the Relation * @param source * The relation that was used as a base to create that BloatedRelation, if any. Due * to the weak nature of relation membership across Atlas(es), this helps decide what * relation members are forcibly removed if any. * @return This. */ public CompleteRelation withMembersAndSource(final RelationMemberList members, final Relation source) { return withMembersAndSource(members.asBean(), source, members.bounds()); }
: ((Relation) entity).members().asBean(), Optional.of(relationBeanMerger)); final Rectangle mergedBounds = Rectangle.forLocated(thisReference, thatReference); thatReference, entity -> ((Relation) entity).allKnownOsmMembers() == null ? null : ((Relation) entity).allKnownOsmMembers().asBean(), Optional.of(relationBeanMerger));
private boolean neighboringAtlasContainingInitialRelation(final Atlas atlas) { for (final Relation newRelation : atlas.relations()) { final Relation currentRelation = this.dynamicAtlas .subRelation(newRelation.getIdentifier()); if (currentRelation != null && this.policy.getAtlasEntitiesToConsiderForExpansion().test(currentRelation) && relationCoversInitialShardBounds(currentRelation)) { final RelationBean newMembers = newRelation.members().asBean(); final RelationBean currentMembers = currentRelation.members().asBean(); for (final RelationBeanItem newMember : newMembers) { if (!currentMembers.contains(newMember)) { newShapeLog(newRelation, currentRelation); return true; } } } } return false; }
protected void validateRelationsLinked() { for (final AtlasEntity entity : this.atlas.entities()) { for (final Relation relation : entity.relations()) { if (!relation.members().asBean() .getItemFor(entity.getIdentifier(), entity.getType()).isPresent()) { throw new CoreException( "Entity {} {} lists parent relation {} which does not have it as a member.", entity.getType(), entity.getIdentifier(), relation.getIdentifier()); } } } }
public CompleteRelation withExtraMember(final AtlasEntity newMember, final AtlasEntity memberFromWhichToCopyRole) { final Relation sourceRelation = Iterables.stream(memberFromWhichToCopyRole.relations()) .firstMatching(relation -> relation.getIdentifier() == this.getIdentifier()) .orElseThrow(() -> new CoreException( "Cannot copy role from {} {} as it does not have relation {} as parent", memberFromWhichToCopyRole.getType(), memberFromWhichToCopyRole.getIdentifier(), this.getIdentifier())); final String role = sourceRelation.members().asBean() .getItemFor(memberFromWhichToCopyRole.getIdentifier(), memberFromWhichToCopyRole.getType()) .orElseThrow(() -> new CoreException( "Cannot copy role from {} {} as it is not a member of {} {}", memberFromWhichToCopyRole.getType(), memberFromWhichToCopyRole.getIdentifier(), this.getClass().getSimpleName(), this)) .getRole(); return withExtraMember(newMember, role); }
@Test public void testFull() { final Atlas atlas = this.rule.getAtlas(); final Relation source = atlas.relation(22); final CompleteRelation result = CompleteRelation.from(source); Assert.assertEquals(source.getIdentifier(), result.getIdentifier()); Assert.assertEquals(source.bounds(), result.bounds()); Assert.assertEquals(source.members().asBean(), result.members().asBean()); Assert.assertEquals(source.allKnownOsmMembers().asBean(), result.allKnownOsmMembers().asBean()); Assert.assertEquals(source.osmRelationIdentifier(), result.osmRelationIdentifier()); Assert.assertEquals( source.relations().stream().map(Relation::getIdentifier) .collect(Collectors.toSet()), result.relations().stream().map(Relation::getIdentifier) .collect(Collectors.toSet())); }
@Test public void splitRoundaboutEdges() { resetAndChange("splitRoundaboutEdges", new AtlasChangeGeneratorSplitRoundabout()); Assert.assertEquals(6, Iterables.size(this.atlas.edges(JunctionTag::isRoundabout))); Assert.assertEquals(12, Iterables.size(this.changeAtlas.edges(JunctionTag::isRoundabout))); final Set<Long> extectedParentRelations = this.atlas.edge(221434104000005L).relations() .stream().map(Relation::getIdentifier).collect(Collectors.toSet()); Assert.assertEquals(extectedParentRelations, this.changeAtlas.edge(14L).relations().stream() .map(Relation::getIdentifier).collect(Collectors.toSet())); Assert.assertEquals(extectedParentRelations, this.changeAtlas.edge(15L).relations().stream() .map(Relation::getIdentifier).collect(Collectors.toSet())); Assert.assertTrue(this.changeAtlas.relation(3001321000000L).members().asBean() .getItemFor(14L, ItemType.EDGE).isPresent()); Assert.assertTrue(this.changeAtlas.relation(3001321000000L).members().asBean() .getItemFor(15L, ItemType.EDGE).isPresent()); Assert.assertTrue(this.atlas.relation(3001321000000L).members().asBean() .getItemFor(221434104000005L, ItemType.EDGE).isPresent()); // Make sure the removed edge was not added back by a mishap in the relation bean merging // somewhere Assert.assertFalse(this.changeAtlas.relation(3001321000000L).members().asBean() .getItemFor(221434104000005L, ItemType.EDGE).isPresent()); }
@Test public void testShallow() { final Atlas atlas = this.rule.getAtlas(); final Relation source = atlas.relation(22); final CompleteRelation result = CompleteRelation.shallowFrom(source); Assert.assertEquals(source.getIdentifier(), result.getIdentifier()); Assert.assertEquals(source.bounds(), result.bounds()); result.withMembersAndSource(new RelationMemberList(source.members()), source); Assert.assertEquals(source.members().asBean(), result.members().asBean()); result.withMembersAndSource(source.members().asBean(), source, source.bounds()); Assert.assertEquals(source.bounds(), result.bounds()); Assert.assertEquals(source.members().asBean(), result.members().asBean()); result.withAllKnownOsmMembers(source.allKnownOsmMembers().asBean()); Assert.assertEquals(source.allKnownOsmMembers().asBean(), result.allKnownOsmMembers().asBean()); result.withOsmRelationIdentifier(source.osmRelationIdentifier()); Assert.assertEquals(source.osmRelationIdentifier(), result.osmRelationIdentifier()); result.withRelationIdentifiers(source.relations().stream().map(Relation::getIdentifier) .collect(Collectors.toSet())); Assert.assertEquals( source.relations().stream().map(Relation::getIdentifier) .collect(Collectors.toSet()), result.relations().stream().map(Relation::getIdentifier) .collect(Collectors.toSet())); } }
@Test public void testRemoveRelationMemberIsReflectedInMemberListAutomatically() { final Atlas atlas = this.rule.getAtlas(); final ChangeBuilder changeBuilder = new ChangeBuilder(); final Relation disconnectedFeatures = atlas.relation(41834000000L); // Remove the point from the list final RelationMemberList newMembers = new RelationMemberList(disconnectedFeatures.members() .stream().filter(member -> !(member.getEntity() instanceof Point)) .collect(Collectors.toList())); // Here only remove the point. Do not remove the member in the relation. It should // automatically be removed. changeBuilder.add(new FeatureChange(ChangeType.REMOVE, CompletePoint.shallowFrom(atlas.point(41822000000L)))); final Change change = changeBuilder.get(); final Atlas changeAtlas = new ChangeAtlas(atlas, change); Assert.assertEquals(newMembers.asBean(), changeAtlas.relation(41834000000L).members().asBean()); final Relation parentRelation = changeAtlas.relation(41860000000L); final Relation fromRelation = (Relation) Iterables.stream(parentRelation.members()) .firstMatching(member -> "child1".equals(member.getRole())).get().getEntity(); Assert.assertEquals(newMembers.asBean(), fromRelation.members().asBean()); }
@Test public void testRemoveRelationMember() { final Atlas atlas = this.rule.getAtlas(); final ChangeBuilder changeBuilder = new ChangeBuilder(); final Relation disconnectedFeatures = atlas.relation(41834000000L); // Remove the point from the list final RelationMemberList newMembers = new RelationMemberList(disconnectedFeatures.members() .stream().filter(member -> !(member.getEntity() instanceof Point)) .collect(Collectors.toList())); changeBuilder.add( new FeatureChange(ChangeType.ADD, CompleteRelation.shallowFrom(disconnectedFeatures) .withMembersAndSource(newMembers, disconnectedFeatures))); changeBuilder.add(new FeatureChange(ChangeType.REMOVE, CompletePoint.shallowFrom(atlas.point(41822000000L)))); final Change change = changeBuilder.get(); final Atlas changeAtlas = new ChangeAtlas(atlas, change); Assert.assertEquals(newMembers.asBean(), changeAtlas.relation(41834000000L).members().asBean()); final Relation parentRelation = changeAtlas.relation(41860000000L); final Relation fromRelation = (Relation) Iterables.stream(parentRelation.members()) .firstMatching(member -> "child1".equals(member.getRole())).get().getEntity(); Assert.assertEquals(newMembers.asBean(), fromRelation.members().asBean()); }
@Test public void testChangeRelationTags() { final Atlas atlas = this.rule.getAtlas(); final ChangeBuilder changeBuilder = new ChangeBuilder(); final Relation disconnectedFeatures = atlas.relation(41834000000L); final Map<String, String> tags = disconnectedFeatures.getTags(); tags.put("newKey", "newValue"); changeBuilder.add(FeatureChange .add(CompleteRelation.shallowFrom(disconnectedFeatures).withTags(tags))); final Change change = changeBuilder.get(); final Atlas changeAtlas = new ChangeAtlas(atlas, change); final Relation changeRelation = changeAtlas.relation(41834000000L); Assert.assertEquals(tags, changeRelation.getTags()); Assert.assertEquals(disconnectedFeatures.members().asBean(), changeRelation.members().asBean()); final Relation parentRelation = changeAtlas.relation(41860000000L); final Relation changeRelationFromParentRelation = (Relation) Iterables .stream(parentRelation.members()) .firstMatching(member -> "child1".equals(member.getRole())).get().getEntity(); Assert.assertEquals(tags, changeRelationFromParentRelation.getTags()); Assert.assertEquals(disconnectedFeatures.members().asBean(), changeRelationFromParentRelation.members().asBean()); }
@Test public void addTurnRestrictions() { resetAndChange("addTurnRestrictions", new AtlasChangeGeneratorAddTurnRestrictions()); final Node via = this.changeAtlas.node(3985226613000000L); final Relation restriction = via.relations().iterator().next(); Assert.assertNotNull(restriction); final RelationBean members = new RelationBean(); members.addItem(221434099000002L, "from", ItemType.EDGE); members.addItem(via.getIdentifier(), "via", ItemType.NODE); members.addItem(634444999000000L, "to", ItemType.EDGE); members.addItem(-634444999000000L, "to", ItemType.EDGE); Assert.assertEquals(members, restriction.members().asBean()); }
@Test public void testMergeRelationMembers() { final RelationBean members = new RelationBean(); members.addItem(new RelationBeanItem(456L, "myRole", ItemType.AREA)); final FeatureChange featureChange1 = new FeatureChange(ChangeType.ADD, new CompleteRelation( 123L, null, Rectangle.TEST_RECTANGLE, members, null, null, null, null)); final FeatureChange featureChange2 = new FeatureChange(ChangeType.ADD, new CompleteRelation( 123L, null, Rectangle.TEST_RECTANGLE, members, null, null, null, null)); Assert.assertEquals(members, ((Relation) featureChange1.merge(featureChange2).getReference()).members() .asBean()); }
@Test public void testMergeRelationMembersPartial() { final RelationBean members1 = new RelationBean(); members1.addItem(new RelationBeanItem(456L, "myRole1", ItemType.AREA)); final RelationBean members2 = new RelationBean(); final FeatureChange featureChange1 = new FeatureChange(ChangeType.ADD, new CompleteRelation( 123L, null, Rectangle.TEST_RECTANGLE, members1, null, null, null, null)); final FeatureChange featureChange2 = new FeatureChange(ChangeType.ADD, new CompleteRelation( 123L, null, Rectangle.TEST_RECTANGLE, members2, null, null, null, null)); Assert.assertEquals(members1, ((Relation) featureChange1.merge(featureChange2).getReference()).members() .asBean()); }
@Test public void testMergeRelationMembersRoleCollision() { // OSM allows (but discourages) the same feature to appear multiple times with the same or // different roles. final RelationBean members1 = new RelationBean(); members1.addItem(new RelationBeanItem(456L, "myRole1", ItemType.AREA)); final RelationBean members2 = new RelationBean(); members2.addItem(new RelationBeanItem(456L, "myRole2", ItemType.AREA)); final RelationBean result = new RelationBean(); result.addItem(new RelationBeanItem(456L, "myRole1", ItemType.AREA)); result.addItem(new RelationBeanItem(456L, "myRole2", ItemType.AREA)); final FeatureChange featureChange1 = new FeatureChange(ChangeType.ADD, new CompleteRelation( 123L, null, Rectangle.TEST_RECTANGLE, members1, null, null, null, null)); final FeatureChange featureChange2 = new FeatureChange(ChangeType.ADD, new CompleteRelation( 123L, null, Rectangle.TEST_RECTANGLE, members2, null, null, null, null)); Assert.assertEquals(result, ((Relation) featureChange1.merge(featureChange2).getReference()) .members().asBean()); }