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;
}
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;
}
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);
}
Aggregations