Search in sources :

Example 1 with RelationBean

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);
}
Also used : SortedSet(java.util.SortedSet) TreeSet(java.util.TreeSet) Set(java.util.Set) CompleteRelation(org.openstreetmap.atlas.geography.atlas.complete.CompleteRelation) Rectangle(org.openstreetmap.atlas.geography.Rectangle) Relation(org.openstreetmap.atlas.geography.atlas.items.Relation) CompleteRelation(org.openstreetmap.atlas.geography.atlas.complete.CompleteRelation) CoreException(org.openstreetmap.atlas.exception.CoreException) RelationBean(org.openstreetmap.atlas.geography.atlas.builder.RelationBean) AtlasEntity(org.openstreetmap.atlas.geography.atlas.items.AtlasEntity)

Example 2 with RelationBean

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);
}
Also used : StringList(org.openstreetmap.atlas.utilities.collections.StringList) RelationBean(org.openstreetmap.atlas.geography.atlas.builder.RelationBean) HashMap(java.util.HashMap)

Example 3 with RelationBean

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);
}
Also used : AtlasMetaData(org.openstreetmap.atlas.geography.atlas.AtlasMetaData) PackedAtlasBuilder(org.openstreetmap.atlas.geography.atlas.packed.PackedAtlasBuilder) RelationBean(org.openstreetmap.atlas.geography.atlas.builder.RelationBean) PackedAtlas(org.openstreetmap.atlas.geography.atlas.packed.PackedAtlas) ArrayList(java.util.ArrayList) PolyLine(org.openstreetmap.atlas.geography.PolyLine) Polygon(org.openstreetmap.atlas.geography.Polygon) File(org.openstreetmap.atlas.streaming.resource.File) Location(org.openstreetmap.atlas.geography.Location)

Example 4 with RelationBean

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;
}
Also used : FeatureChange(org.openstreetmap.atlas.geography.atlas.change.FeatureChange) AtomicLong(java.util.concurrent.atomic.AtomicLong) RelationBean(org.openstreetmap.atlas.geography.atlas.builder.RelationBean) CompleteRelation(org.openstreetmap.atlas.geography.atlas.complete.CompleteRelation) CompleteNode(org.openstreetmap.atlas.geography.atlas.complete.CompleteNode) Node(org.openstreetmap.atlas.geography.atlas.items.Node) AtomicLong(java.util.concurrent.atomic.AtomicLong) Rectangle(org.openstreetmap.atlas.geography.Rectangle) CompleteEdge(org.openstreetmap.atlas.geography.atlas.complete.CompleteEdge) Edge(org.openstreetmap.atlas.geography.atlas.items.Edge) HashSet(java.util.HashSet)

Example 5 with RelationBean

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);
    }
}
Also used : CoreException(org.openstreetmap.atlas.exception.CoreException) RelationBean(org.openstreetmap.atlas.geography.atlas.builder.RelationBean) HashSet(java.util.HashSet)

Aggregations

RelationBean (org.openstreetmap.atlas.geography.atlas.builder.RelationBean)73 Test (org.junit.Test)40 PackedAtlasBuilder (org.openstreetmap.atlas.geography.atlas.packed.PackedAtlasBuilder)21 CompleteRelation (org.openstreetmap.atlas.geography.atlas.complete.CompleteRelation)20 Atlas (org.openstreetmap.atlas.geography.atlas.Atlas)17 RelationBeanItem (org.openstreetmap.atlas.geography.atlas.builder.RelationBean.RelationBeanItem)17 PolyLine (org.openstreetmap.atlas.geography.PolyLine)12 Relation (org.openstreetmap.atlas.geography.atlas.items.Relation)9 ArrayList (java.util.ArrayList)8 Location (org.openstreetmap.atlas.geography.Location)8 PackedAtlas (org.openstreetmap.atlas.geography.atlas.packed.PackedAtlas)8 Polygon (org.openstreetmap.atlas.geography.Polygon)7 ItemType (org.openstreetmap.atlas.geography.atlas.items.ItemType)7 AtlasResourceLoader (org.openstreetmap.atlas.geography.atlas.AtlasResourceLoader)6 FeatureChange (org.openstreetmap.atlas.geography.atlas.change.FeatureChange)6 ByteArrayResource (org.openstreetmap.atlas.streaming.resource.ByteArrayResource)6 CoreException (org.openstreetmap.atlas.exception.CoreException)5 CompleteNode (org.openstreetmap.atlas.geography.atlas.complete.CompleteNode)5 HashMap (java.util.HashMap)4 HashSet (java.util.HashSet)4