use of org.openstreetmap.atlas.geography.atlas.builder.RelationBean in project atlas by osmlab.
the class FeatureChangeMergingHelpers method mergeRelations.
private static FeatureChange mergeRelations(final FeatureChange left, final FeatureChange right, final MergedMemberBean<Map<String, String>> mergedTagsBean, final MergedMemberBean<Set<Long>> mergedParentRelationsBean) {
final AtlasEntity beforeEntityLeft = left.getBeforeView();
final AtlasEntity afterEntityLeft = left.getAfterView();
final AtlasEntity beforeEntityRight = right.getBeforeView();
final AtlasEntity afterEntityRight = right.getAfterView();
if (afterEntityLeft == null) {
throw new CoreException(AFTER_ENTITY_LEFT_WAS_NULL);
}
if (afterEntityRight == null) {
throw new CoreException(AFTER_ENTITY_RIGHT_WAS_NULL);
}
final MergedMemberBean<RelationBean> mergedMembersBean = new MemberMerger.Builder<RelationBean>().withMemberName("relationMembers").withBeforeEntityLeft(beforeEntityLeft).withAfterEntityLeft(afterEntityLeft).withBeforeEntityRight(beforeEntityRight).withAfterEntityRight(afterEntityRight).withMemberExtractor(entity -> ((Relation) entity).members() == null ? null : ((Relation) entity).members().asBean()).withAfterViewNoBeforeMerger(MemberMergeStrategies.simpleRelationBeanMerger).withAfterViewConsistentBeforeViewMerger(MemberMergeStrategies.diffBasedRelationBeanMerger).withAfterViewConflictingBeforeViewMerger(MemberMergeStrategies.conflictingBeforeViewRelationBeanMerger).withBeforeViewMerger(MemberMergeStrategies.simpleRelationBeanMerger).build().mergeMember();
final MergedMemberBean<Set<Long>> mergedAllRelationsWithSameOsmIdentifierBean = new MemberMerger.Builder<Set<Long>>().withMemberName("allRelationsWithSameOsmIdentifier").withBeforeEntityLeft(beforeEntityLeft).withAfterEntityLeft(afterEntityLeft).withBeforeEntityRight(beforeEntityRight).withAfterEntityRight(afterEntityRight).withMemberExtractor(atlasEntity -> ((Relation) atlasEntity).allRelationsWithSameOsmIdentifier() == null ? null : ((Relation) atlasEntity).allRelationsWithSameOsmIdentifier().stream().map(Relation::getIdentifier).collect(Collectors.toSet())).withAfterViewNoBeforeMerger(MemberMergeStrategies.simpleLongSetMerger).withAfterViewConsistentBeforeViewMerger(MemberMergeStrategies.diffBasedLongSetMerger).withAfterViewConflictingBeforeViewMerger(MemberMergeStrategies.autofailQuaternaryLongSetMerger).withBeforeViewMerger(MemberMergeStrategies.autofailBinaryLongSetMerger).build().mergeMember();
final MergedMemberBean<RelationBean> mergedAllKnownMembersBean = new MemberMerger.Builder<RelationBean>().withMemberName("allKnownOsmMembers").withBeforeEntityLeft(beforeEntityLeft).withAfterEntityLeft(afterEntityLeft).withBeforeEntityRight(beforeEntityRight).withAfterEntityRight(afterEntityRight).withMemberExtractor(entity -> ((Relation) entity).allKnownOsmMembers() == null ? null : ((Relation) entity).allKnownOsmMembers().asBean()).withAfterViewNoBeforeMerger(MemberMergeStrategies.simpleRelationBeanMerger).withAfterViewConsistentBeforeViewMerger(MemberMergeStrategies.diffBasedRelationBeanMerger).withAfterViewConflictingBeforeViewMerger(MemberMergeStrategies.conflictingBeforeViewRelationBeanMerger).withBeforeViewMerger(MemberMergeStrategies.simpleRelationBeanMerger).build().mergeMember();
final MergedMemberBean<Long> mergedOsmRelationIdentifier = new MemberMerger.Builder<Long>().withMemberName("osmRelationIdentifier").withBeforeEntityLeft(beforeEntityLeft).withAfterEntityLeft(afterEntityLeft).withBeforeEntityRight(beforeEntityRight).withAfterEntityRight(afterEntityRight).withMemberExtractor(entity -> ((Relation) entity).osmRelationIdentifier()).withAfterViewNoBeforeMerger(MemberMergeStrategies.autofailBinaryLongMerger).withAfterViewConsistentBeforeViewMerger(MemberMergeStrategies.diffBasedLongMerger).withAfterViewConflictingBeforeViewMerger(MemberMergeStrategies.autofailQuaternaryLongMerger).withBeforeViewMerger(MemberMergeStrategies.autofailBinaryLongMerger).build().mergeMember();
final Rectangle mergedBounds = Rectangle.forLocated(afterEntityLeft, afterEntityRight);
final CompleteRelation mergedAfterRelation = new CompleteRelation(left.getIdentifier(), mergedTagsBean.getMergedAfterMember(), mergedBounds, mergedMembersBean.getMergedAfterMember(), mergedAllRelationsWithSameOsmIdentifierBean.getMergedAfterMember() != null ? mergedAllRelationsWithSameOsmIdentifierBean.getMergedAfterMember().stream().collect(Collectors.toList()) : null, mergedAllKnownMembersBean.getMergedAfterMember(), mergedOsmRelationIdentifier.getMergedAfterMember(), mergedParentRelationsBean.getMergedAfterMember());
mergedAfterRelation.withBoundsExtendedBy(afterEntityLeft.bounds());
mergedAfterRelation.withBoundsExtendedBy(afterEntityRight.bounds());
final CompleteRelation mergedBeforeRelation;
/*
* Here we just arbitrarily use the left side entity. We have already asserted that both
* left and right explicitly provided or explicitly excluded a beforeView. At this point, we
* have also ensured that both beforeViews, if present, were consistent (or we merged them
* if necessary). Therefore it is safe to arbitrarily choose one from which to "shallowFrom"
* clone a new CompleteEntity.
*/
if (beforeEntityLeft != null) {
mergedBeforeRelation = CompleteRelation.shallowFrom((Relation) beforeEntityLeft).withMembers(mergedMembersBean.getMergedBeforeMember(), beforeEntityLeft.bounds()).withAllRelationsWithSameOsmIdentifier(mergedAllRelationsWithSameOsmIdentifierBean.getMergedAfterMember() != null ? mergedAllRelationsWithSameOsmIdentifierBean.getMergedBeforeMember().stream().collect(Collectors.toList()) : null).withAllKnownOsmMembers(mergedAllKnownMembersBean.getMergedBeforeMember()).withOsmRelationIdentifier(mergedOsmRelationIdentifier.getMergedBeforeMember()).withTags(mergedTagsBean.getMergedBeforeMember()).withRelationIdentifiers(mergedParentRelationsBean.getMergedBeforeMember());
} else {
mergedBeforeRelation = null;
}
return new FeatureChange(ChangeType.ADD, mergedAfterRelation, mergedBeforeRelation);
}
use of org.openstreetmap.atlas.geography.atlas.builder.RelationBean in project atlas by osmlab.
the class TextAtlasBuilder method parseRelation.
private void parseRelation(final PackedAtlasBuilder builder, final String line) {
final StringList split = StringList.split(line, SEPARATOR);
final long identifier = Long.parseLong(split.get(0));
final RelationBean structure = parseRelationBean(split.get(1));
final Map<String, String> tags = new HashMap<>();
if (split.size() > 2) {
tags.putAll(parseTags(split.get(2)));
}
builder.addRelation(identifier, identifier, structure, tags);
}
use of org.openstreetmap.atlas.geography.atlas.builder.RelationBean in project atlas by osmlab.
the class CreateTestAtlas method createTestAtlas.
private static void createTestAtlas() {
final PackedAtlasBuilder builder = new PackedAtlasBuilder();
final AtlasMetaData metaData = new AtlasMetaData(AtlasSize.DEFAULT, true, "testCodeVersion", "testDataVersion", "testCountry", "testShardName", Maps.hashMap("metakey", "metaval"));
builder.setMetaData(metaData);
// add points
builder.addPoint(1, new Location(Latitude.degrees(38), Longitude.degrees(-118)), Maps.hashMap());
builder.addPoint(2, new Location(Latitude.degrees(38.01), Longitude.degrees(-118.01)), Maps.hashMap("some_tag", "some_value"));
builder.addPoint(3, new Location(Latitude.degrees(38.02), Longitude.degrees(-118.01)), Maps.hashMap("key1", "value2", "key2", "value2"));
builder.addPoint(4, new Location(Latitude.degrees(38), Longitude.degrees(-118.05)), Maps.hashMap("", ""));
builder.addPoint(5, new Location(Latitude.degrees(38.05), Longitude.degrees(-118.03)), Maps.hashMap("key1", "value2", "key2", "value2", "key3:subkey1", "value3:subvalue1"));
// add lines
final List<Location> shapePoints = new ArrayList<>();
shapePoints.add(new Location(Latitude.degrees(38.02), Longitude.degrees(-118.02)));
shapePoints.add(new Location(Latitude.degrees(38.03), Longitude.degrees(-118.01)));
shapePoints.add(new Location(Latitude.degrees(38.06), Longitude.degrees(-118.05)));
builder.addLine(1, new PolyLine(shapePoints), Maps.hashMap("key1", "value2", "key2", "value2"));
shapePoints.clear();
shapePoints.add(new Location(Latitude.degrees(38.06), Longitude.degrees(-118.09)));
shapePoints.add(new Location(Latitude.degrees(38.03), Longitude.degrees(-118.1)));
builder.addLine(2, new PolyLine(shapePoints), Maps.hashMap("key1", "value2", "key2", "value2"));
// add areas
shapePoints.add(new Location(Latitude.degrees(38.1), Longitude.degrees(-118.02)));
shapePoints.add(new Location(Latitude.degrees(38.2), Longitude.degrees(-118.01)));
shapePoints.add(new Location(Latitude.degrees(38.09), Longitude.degrees(-118.05)));
builder.addArea(1, new Polygon(shapePoints), Maps.hashMap("key1", "value2", "key2", "value2"));
shapePoints.clear();
shapePoints.add(new Location(Latitude.degrees(39.1), Longitude.degrees(-118.06)));
shapePoints.add(new Location(Latitude.degrees(39.2), Longitude.degrees(-118.02)));
shapePoints.add(new Location(Latitude.degrees(38.09), Longitude.degrees(-118.03)));
builder.addArea(2, new Polygon(shapePoints), Maps.hashMap("random key", "value2", "key2", "somenewvalue"));
// add nodes
builder.addNode(1, new Location(Latitude.degrees(39), Longitude.degrees(-118)), Maps.hashMap());
builder.addNode(2, new Location(Latitude.degrees(39.02), Longitude.degrees(-119.01)), Maps.hashMap("key1", "value2", "key2", "value2"));
builder.addNode(3, new Location(Latitude.degrees(39), Longitude.degrees(-119.05)), Maps.hashMap("asd", "asdf"));
builder.addNode(4, new Location(Latitude.degrees(39.05), Longitude.degrees(-119.03)), Maps.hashMap("key1", "value2", "key2", "value2", "key3:subkey1", "value3:subvalue1"));
// add edges
shapePoints.clear();
shapePoints.add(new Location(Latitude.degrees(39), Longitude.degrees(-119.05)));
shapePoints.add(new Location(Latitude.degrees(39.02), Longitude.degrees(-119.01)));
builder.addEdge(1, new PolyLine(shapePoints), Maps.hashMap("key1", "value2", "key2", "value2"));
shapePoints.clear();
shapePoints.add(new Location(Latitude.degrees(39), Longitude.degrees(-118)));
shapePoints.add(new Location(Latitude.degrees(39.05), Longitude.degrees(-119.03)));
builder.addEdge(2, new PolyLine(shapePoints), Maps.hashMap("key5", "asdsavalue2", "key2", "value2"));
shapePoints.clear();
shapePoints.add(new Location(Latitude.degrees(39.05), Longitude.degrees(-119.03)));
shapePoints.add(new Location(Latitude.degrees(39), Longitude.degrees(-119.05)));
builder.addEdge(3, new PolyLine(shapePoints), Maps.hashMap("key5", "asdsavalue2", "key2", "value2"));
// add relations
RelationBean bean = new RelationBean();
bean.addItem(1L, "node 1", ItemType.NODE);
bean.addItem(2L, "an edge", ItemType.EDGE);
builder.addRelation(1, 1, bean, Maps.hashMap("type", "road", "status", "foo"));
bean = new RelationBean();
bean.addItem(1L, "a point", ItemType.POINT);
bean.addItem(2L, "another point", ItemType.POINT);
builder.addRelation(2, 2, bean, Maps.hashMap("key5", "qwertyvalue2", "key5", "asdvalue2"));
final PackedAtlas atlas = (PackedAtlas) builder.get();
atlas.setSaveSerializationFormat(AtlasSerializationFormat.PROTOBUF);
final File resource = new File("test.atlas");
System.out.println("Test atlas dumped to: " + resource.getAbsolutePath());
atlas.save(resource);
}
use of org.openstreetmap.atlas.geography.atlas.builder.RelationBean in project atlas by osmlab.
the class AtlasChangeGeneratorAddTurnRestrictions method generateWithoutValidation.
@Override
public Set<FeatureChange> generateWithoutValidation(final Atlas atlas) {
final AtomicLong identifierGenerator = new AtomicLong();
final Set<FeatureChange> result = new HashSet<>();
final Long parentRelationIdentifier = identifierGenerator.incrementAndGet();
final RelationBean parentMembers = new RelationBean();
Rectangle parentBounds = null;
for (final Node node : atlas.nodes(node -> node.valence() > this.minimumNodeValence)) {
final SortedSet<Edge> inEdges = node.inEdges();
final SortedSet<Edge> outEdges = node.outEdges();
for (final Edge inEdge : inEdges) {
for (final Edge outEdge : outEdges) {
final RelationBean members = new RelationBean();
members.addItem(inEdge.getIdentifier(), "from", ItemType.EDGE);
inEdge.reversed().ifPresent(reversed -> members.addItem(reversed.getIdentifier(), "from", ItemType.EDGE));
members.addItem(node.getIdentifier(), "via", ItemType.NODE);
members.addItem(outEdge.getIdentifier(), "to", ItemType.EDGE);
outEdge.reversed().ifPresent(reversed -> members.addItem(reversed.getIdentifier(), "to", ItemType.EDGE));
final Long relationIdentifier = identifierGenerator.incrementAndGet();
final Rectangle bounds = Rectangle.forLocated(inEdge, outEdge);
if (parentBounds == null) {
parentBounds = bounds;
} else {
parentBounds = Rectangle.forLocated(parentBounds, bounds);
}
parentMembers.addItem(relationIdentifier, "addition", ItemType.RELATION);
result.add(FeatureChange.add(new CompleteRelation(relationIdentifier, Maps.hashMap("type", "restriction", "restriction", "no_left_turn"), bounds, members, Lists.newArrayList(relationIdentifier), members, relationIdentifier, Sets.hashSet(parentRelationIdentifier))));
result.add(FeatureChange.add(CompleteEdge.shallowFrom(inEdge).withRelationIdentifiers(mergeRelationMembers(inEdge.relations(), relationIdentifier))));
if (inEdge.hasReverseEdge()) {
result.add(FeatureChange.add(CompleteEdge.shallowFrom(inEdge.reversed().get()).withRelationIdentifiers(mergeRelationMembers(inEdge.relations(), relationIdentifier))));
}
result.add(FeatureChange.add(CompleteNode.shallowFrom(node).withRelationIdentifiers(mergeRelationMembers(node.relations(), relationIdentifier))));
result.add(FeatureChange.add(CompleteEdge.shallowFrom(outEdge).withRelationIdentifiers(mergeRelationMembers(outEdge.relations(), relationIdentifier))));
if (outEdge.hasReverseEdge()) {
result.add(FeatureChange.add(CompleteEdge.shallowFrom(outEdge.reversed().get()).withRelationIdentifiers(mergeRelationMembers(outEdge.relations(), relationIdentifier))));
}
// super slow for unit tests.
break;
}
// slow for unit tests.
break;
}
}
if (!result.isEmpty()) {
result.add(FeatureChange.add(new CompleteRelation(parentRelationIdentifier, Maps.hashMap("name", "parent_of_new_restrictions"), parentBounds, parentMembers, Lists.newArrayList(parentRelationIdentifier), parentMembers, parentRelationIdentifier, Sets.hashSet())));
}
return result;
}
use of org.openstreetmap.atlas.geography.atlas.builder.RelationBean in project atlas by osmlab.
the class ChangeSetAtlasBuilder method handleRelations.
private void handleRelations() {
this.originalAtlas.relations().forEach(relation -> {
if (this.changeSet.contains(relation.getIdentifier(), ItemType.RELATION, ChangeAction.DELETE)) {
return;
}
final Optional<ChangeItem> optionalItem = this.changeSet.get(relation.getIdentifier(), ItemType.RELATION, ChangeAction.UPDATE);
if (optionalItem.isPresent()) {
final ChangeItem changeItem = optionalItem.get();
this.builder.addRelation(relation.getIdentifier(), relation.getOsmIdentifier(), changeItem.getRelationBean().get(), changeItem.getTags());
} else {
final RelationBean bean = new RelationBean();
relation.members().forEach(member -> bean.addItem(member.getEntity().getIdentifier(), member.getRole(), member.getEntity().getType()));
this.builder.addRelation(relation.getIdentifier(), relation.osmRelationIdentifier(), bean, relation.getTags());
}
});
// Add all the relations that do not have members that are relations.
Set<Long> stagedRelationIdentifiers = new HashSet<>();
final Iterator<ChangeItem> iterator = this.changeSet.iterator(ItemType.RELATION, ChangeAction.CREATE);
while (iterator.hasNext()) {
final ChangeItem relationMatchResult = iterator.next();
if (StreamSupport.stream(relationMatchResult.getMembers().spliterator(), false).anyMatch(member -> member.getType() == ItemType.RELATION)) {
stagedRelationIdentifiers.add(relationMatchResult.getIdentifier());
} else {
this.builder.addRelation(relationMatchResult.getIdentifier(), relationMatchResult.getIdentifier(), relationMatchResult.getRelationBean().get(), relationMatchResult.getTags());
}
}
// Add all the other relations
int iterations = 0;
while (++iterations < MAXIMUM_RELATION_LOOPS && !stagedRelationIdentifiers.isEmpty()) {
logger.trace("Copying relations level {} deep.", iterations);
final Set<Long> stagedRelationIdentifiersCopy = new HashSet<>();
for (final Long relationIdentifier : stagedRelationIdentifiers) {
final Optional<ChangeItem> optionalItem = this.changeSet.get(relationIdentifier, ItemType.RELATION, ChangeAction.CREATE);
if (!optionalItem.isPresent()) {
logger.error("can't find relation with id {}", relationIdentifier);
continue;
}
final ChangeItem relationItem = optionalItem.get();
final boolean skip = StreamSupport.stream(relationItem.getMembers().spliterator(), false).allMatch(member -> member.getType() == ItemType.RELATION && this.builder.peek().relation(member.getIdentifier()) == null);
if (!skip) {
this.builder.addRelation(relationItem.getIdentifier(), relationItem.getIdentifier(), relationItem.getRelationBean().get(), relationItem.getTags());
} else {
stagedRelationIdentifiersCopy.add(relationIdentifier);
}
}
stagedRelationIdentifiers = stagedRelationIdentifiersCopy;
}
if (iterations >= MAXIMUM_RELATION_LOOPS) {
throw new CoreException("There might be a loop in relations! It took more than {} loops to copy the relation.", MAXIMUM_RELATION_LOOPS);
}
}
Aggregations