Search in sources :

Example 1 with RelationOrAreaToMultiPolygonConverter

use of org.openstreetmap.atlas.geography.atlas.items.complex.RelationOrAreaToMultiPolygonConverter in project atlas by osmlab.

the class SimpleCoverage method getSurface.

/**
 * Gets the area of the item to count
 *
 * @param item
 *            The item to count
 * @return The area of the item to count. In case this is a {@link Relation}, and the
 *         {@link Relation} is type=multipolygon, the area is the area of the multipolygon. In
 *         case the relation is of another type, the area is the sum of all the lowest order
 *         areas that make the relation.
 */
private Surface getSurface(final AtlasEntity item) {
    Surface result = Surface.MINIMUM;
    if (item instanceof Relation && ((Relation) item).isMultiPolygon() || item instanceof Area) {
        try {
            final RelationOrAreaToMultiPolygonConverter converter = new RelationOrAreaToMultiPolygonConverter();
            result = result.add(converter.apply(item).surface());
            return result;
        } catch (final CoreException e) {
        // Many features will not be multipolygons.
        } catch (final IllegalArgumentException e) {
            logger.error("AtlasStatistics cannot compute surface of {}", item, e);
        }
        return result;
    }
    if (item instanceof Relation) {
        // Relation that is not of type multipolygon
        for (final RelationMember member : ((Relation) item).members()) {
            result = result.add(getSurface(member.getEntity()));
        }
    }
    return result;
}
Also used : Relation(org.openstreetmap.atlas.geography.atlas.items.Relation) Area(org.openstreetmap.atlas.geography.atlas.items.Area) RelationMember(org.openstreetmap.atlas.geography.atlas.items.RelationMember) CoreException(org.openstreetmap.atlas.exception.CoreException) RelationOrAreaToMultiPolygonConverter(org.openstreetmap.atlas.geography.atlas.items.complex.RelationOrAreaToMultiPolygonConverter) Surface(org.openstreetmap.atlas.utilities.scalars.Surface)

Example 2 with RelationOrAreaToMultiPolygonConverter

use of org.openstreetmap.atlas.geography.atlas.items.complex.RelationOrAreaToMultiPolygonConverter in project atlas by osmlab.

the class RelationToMultiPolygonCommand method finish.

@Override
protected int finish() {
    if (this.relationAtlases.isEmpty()) {
        this.outputDelegate.printlnErrorMessage("no atlases found with relation");
        return 1;
    }
    final MultiAtlas multiAtlas = new MultiAtlas(this.relationAtlases);
    final MultiPolygon relationMultiPolygon;
    final org.openstreetmap.atlas.geography.MultiPolygon atlasMultiPolygon;
    try {
        final RelationOrAreaToMultiPolygonConverter converter = new RelationOrAreaToMultiPolygonConverter();
        atlasMultiPolygon = converter.convert(multiAtlas.relation(this.relationId));
        if (!atlasMultiPolygon.isOGCValid()) {
            this.outputDelegate.printlnWarnMessage("warning: relation multipolygon is not OGC valid!");
            if (!atlasMultiPolygon.isOSMValid()) {
                this.outputDelegate.printlnErrorMessage("warning: relation multipolygon is not OSM valid, cannot construct WKT!");
                return 1;
            }
        }
        final JtsMultiPolygonToMultiPolygonConverter jtsconverter = new JtsMultiPolygonToMultiPolygonConverter();
        relationMultiPolygon = jtsconverter.backwardConvert(atlasMultiPolygon);
    } catch (final Exception exception) {
        this.outputDelegate.printlnErrorMessage("error building valid multipolygon from relation: ");
        this.outputDelegate.printlnErrorMessage(exception.getMessage());
        return 1;
    }
    if (relationMultiPolygon.toText().length() < MAX_LENGTH) {
        this.outputDelegate.printlnCommandMessage("Relation WKT:");
        this.outputDelegate.printlnCommandMessage(relationMultiPolygon.toText());
    } else {
        this.outputDelegate.printlnWarnMessage("Relation WKT is too large to print!");
    }
    final Path concatenatedWktPath = Paths.get(getOutputPath().toAbsolutePath().toString(), String.format(OUTPUT_WKT_FORMAT, this.relationId));
    final File wktOutputFile = new File(concatenatedWktPath.toAbsolutePath().toString(), this.getFileSystem());
    wktOutputFile.writeAndClose(relationMultiPolygon.toText());
    if (!this.optionAndArgumentDelegate.hasOption(OUTPUT_WKT_OPTION_LONG)) {
        final Path concatenatedPath = Paths.get(getOutputPath().toAbsolutePath().toString(), String.format(OUTPUT_ATLAS_FORMAT, this.relationId));
        final File outputFile = new File(concatenatedPath.toAbsolutePath().toString(), this.getFileSystem());
        final PackedAtlas outputAtlas = multiAtlas.cloneToPackedAtlas();
        outputAtlas.setSaveSerializationFormat(AtlasSerializationFormat.PROTOBUF);
        outputAtlas.save(outputFile);
        if (this.optionAndArgumentDelegate.hasVerboseOption()) {
            this.outputDelegate.printlnCommandMessage("saved atlas to " + concatenatedPath.toString());
        }
    }
    return 0;
}
Also used : Path(java.nio.file.Path) MultiAtlas(org.openstreetmap.atlas.geography.atlas.multi.MultiAtlas) MultiPolygon(org.locationtech.jts.geom.MultiPolygon) RelationOrAreaToMultiPolygonConverter(org.openstreetmap.atlas.geography.atlas.items.complex.RelationOrAreaToMultiPolygonConverter) PackedAtlas(org.openstreetmap.atlas.geography.atlas.packed.PackedAtlas) JtsMultiPolygonToMultiPolygonConverter(org.openstreetmap.atlas.geography.converters.jts.JtsMultiPolygonToMultiPolygonConverter) File(org.openstreetmap.atlas.streaming.resource.File)

Example 3 with RelationOrAreaToMultiPolygonConverter

use of org.openstreetmap.atlas.geography.atlas.items.complex.RelationOrAreaToMultiPolygonConverter in project atlas-checks by osmlab.

the class LineCrossingWaterBodyCheck method flag.

@Override
@SuppressWarnings("squid:S2293")
protected Optional<CheckFlag> flag(final AtlasObject object) {
    // Immediately mark as processed so other shards do not pick this up
    this.markAsFlagged(object.getOsmIdentifier());
    // First convert the waterbody to a GeometricSurface for use in querying
    final GeometricSurface waterbody = object instanceof Area ? ((Area) object).asPolygon() : new RelationOrAreaToMultiPolygonConverter().convert((Relation) object);
    if (waterbody instanceof MultiPolygon) {
        final long shapepoints = ((MultiPolygon) waterbody).outers().stream().mapToLong(Collection::size).sum();
        if (shapepoints > this.shapepointsMax || shapepoints < this.shapepointsMin) {
            logger.info("Skipping processing of multipolygon relation {} since it has {} shapepoints, which is outside the range of {}-{}", object.getOsmIdentifier(), shapepoints, this.shapepointsMin, this.shapepointsMax);
            return Optional.empty();
        }
    }
    // Then retrieve the invalid crossing edges, lines, buildings
    final Atlas atlas = object.getAtlas();
    final Iterable<AtlasItem> invalidCrossingItems = this.flagBuildings ? new MultiIterable<>(collectOffendingLineItems(atlas, object, waterbody), atlas.areasIntersecting(waterbody, area -> BuildingTag.isBuilding(area) && !NONOFFENDING_BUILDINGS.test(area) && LevelTag.areOnSameLevel(object, area) && !this.getInteractionsPerWaterbodyComponent(waterbody, object, area.asPolygon()).isEmpty())) : new MultiIterable<AtlasItem>(collectOffendingLineItems(atlas, object, waterbody));
    // This waterbody has no invalid crossings
    if (!invalidCrossingItems.iterator().hasNext()) {
        return Optional.empty();
    }
    final CheckFlag newFlag = new CheckFlag(getTaskIdentifier(object));
    newFlag.addObject(object);
    newFlag.addInstruction(this.getLocalizedInstruction(0, object.getOsmIdentifier()));
    // Only record an OSM id as crossing once in the instruction
    final Set<Long> recordedOsmIds = new HashSet<>();
    // each edge will be marked explicitly.
    for (final AtlasItem crossingItem : invalidCrossingItems) {
        // Update the flag
        newFlag.addObject(crossingItem);
        if (!recordedOsmIds.contains(crossingItem.getOsmIdentifier())) {
            newFlag.addInstruction(this.getLocalizedInstruction(crossingItem instanceof Area ? 2 : 1, crossingItem.getOsmIdentifier()));
            recordedOsmIds.add(crossingItem.getOsmIdentifier());
        }
    }
    return Optional.of(newFlag);
}
Also used : GeometricSurface(org.openstreetmap.atlas.geography.GeometricSurface) Atlas(org.openstreetmap.atlas.geography.atlas.Atlas) RelationOrAreaToMultiPolygonConverter(org.openstreetmap.atlas.geography.atlas.items.complex.RelationOrAreaToMultiPolygonConverter) Area(org.openstreetmap.atlas.geography.atlas.items.Area) Relation(org.openstreetmap.atlas.geography.atlas.items.Relation) MultiPolygon(org.openstreetmap.atlas.geography.MultiPolygon) AtlasItem(org.openstreetmap.atlas.geography.atlas.items.AtlasItem) CheckFlag(org.openstreetmap.atlas.checks.flag.CheckFlag) HashSet(java.util.HashSet)

Aggregations

RelationOrAreaToMultiPolygonConverter (org.openstreetmap.atlas.geography.atlas.items.complex.RelationOrAreaToMultiPolygonConverter)3 Area (org.openstreetmap.atlas.geography.atlas.items.Area)2 Relation (org.openstreetmap.atlas.geography.atlas.items.Relation)2 Path (java.nio.file.Path)1 HashSet (java.util.HashSet)1 MultiPolygon (org.locationtech.jts.geom.MultiPolygon)1 CheckFlag (org.openstreetmap.atlas.checks.flag.CheckFlag)1 CoreException (org.openstreetmap.atlas.exception.CoreException)1 GeometricSurface (org.openstreetmap.atlas.geography.GeometricSurface)1 MultiPolygon (org.openstreetmap.atlas.geography.MultiPolygon)1 Atlas (org.openstreetmap.atlas.geography.atlas.Atlas)1 AtlasItem (org.openstreetmap.atlas.geography.atlas.items.AtlasItem)1 RelationMember (org.openstreetmap.atlas.geography.atlas.items.RelationMember)1 MultiAtlas (org.openstreetmap.atlas.geography.atlas.multi.MultiAtlas)1 PackedAtlas (org.openstreetmap.atlas.geography.atlas.packed.PackedAtlas)1 JtsMultiPolygonToMultiPolygonConverter (org.openstreetmap.atlas.geography.converters.jts.JtsMultiPolygonToMultiPolygonConverter)1 File (org.openstreetmap.atlas.streaming.resource.File)1 Surface (org.openstreetmap.atlas.utilities.scalars.Surface)1