use of org.openstreetmap.atlas.geography.PolyLine in project atlas-checks by osmlab.
the class CheckFlag method getMapRouletteTask.
/**
* Builds a MapRouletted {@link Task} from this {@link CheckFlag}
*
* @return a {@link Task}
*/
public Task getMapRouletteTask() {
final Task task = new Task();
task.setInstruction(this.getInstructions());
task.setProjectName(this.getCountryISO());
task.setChallengeName(this.getChallengeName().orElse(this.getClass().getSimpleName()));
task.setTaskIdentifier(this.identifier);
// Add custom pin point(s), if supplied.
final Set<Location> points = getPoints();
if (!points.isEmpty()) {
task.setPoints(points);
} else {
final Set<PolyLine> polyLines = getPolyLines();
if (!polyLines.isEmpty()) {
// Retrieve the first item in the list and retrieve the first point in the
// geometry for the object
task.setPoint(polyLines.iterator().next().iterator().next());
}
}
final JsonArray features = new JsonArray();
this.getLocationIterableProperties().forEach(shape -> features.add(new GeoJsonBuilder().create(shape)));
task.setGeoJson(Optional.of(features));
return task;
}
use of org.openstreetmap.atlas.geography.PolyLine in project atlas-checks by osmlab.
the class SelfIntersectingPolylineCheck method flag.
@Override
protected Optional<CheckFlag> flag(final AtlasObject object) {
final Optional<CheckFlag> response;
final int localizedInstructionIndex;
final PolyLine polyline;
if (object instanceof Edge) {
polyline = ((Edge) object).asPolyLine();
// Send building instructions if building tag exists
localizedInstructionIndex = (TagPredicates.IS_BUILDING.test(object)) ? 2 : 0;
} else if (object instanceof Line) {
polyline = ((Line) object).asPolyLine();
// Send building instructions if building tag exists
localizedInstructionIndex = (TagPredicates.IS_BUILDING.test(object)) ? 2 : 0;
} else if (object instanceof Area) {
polyline = ((Area) object).asPolygon();
// Send duplicate Edge instructions if duplicate Edges exist
localizedInstructionIndex = hasDuplicateSegments(polyline) ? THREE : 1;
} else {
throw new CoreException("Invalid item type {}", object.getClass().toString());
}
// First, find shape point intersections
final Set<Location> selfIntersections = polyline.selfIntersections();
if (selfIntersections.size() > 0) {
final CheckFlag flag = new CheckFlag(Long.toString(object.getIdentifier()));
flag.addObject(object);
flag.addInstruction(this.getLocalizedInstruction(localizedInstructionIndex, object.getOsmIdentifier(), selfIntersections.toString()));
selfIntersections.forEach(flag::addPoint);
response = Optional.of(flag);
} else {
// Next, find intersections occurring at non-shape points using JTS verification
boolean isJtsValid = true;
try {
if (object instanceof Area) {
isJtsValid = GeometryValidator.isValidPolygon((Polygon) polyline);
} else {
isJtsValid = GeometryValidator.isValidPolyLine(polyline);
}
} catch (final IllegalArgumentException e) {
// Invalid geometry found when converting the PolyLine/Polygon.
// This can be a number of cases. For example, a LineString expects exactly 0 or >=2
// points or a Polygon expects 0 or >= 4 points. This isn't self-intersecting
// geometry, but rather inconsistent geometry, according to JTS.
logger.error("Encountered invalid geometry for feature {}", object.getOsmIdentifier(), e);
}
if (!isJtsValid) {
response = Optional.of(createFlag(object, this.getLocalizedInstruction(localizedInstructionIndex)));
} else {
response = Optional.empty();
}
}
return response;
}
use of org.openstreetmap.atlas.geography.PolyLine in project atlas-checks by osmlab.
the class IntersectingBuildingsCheck method findIntersectionType.
/**
* Find {@link IntersectionType} for given {@link Polygon}s. There are some edge cases where
* there are minor boundary intersections. So we do additional area check to filter off the
* false positives.
*
* @param polygon
* {@link Polygon} to check for intersection
* @param otherPolygon
* Another {@link Polygon} to check against for intersection
* @param areaSizeToCheck
* Area size to decide if intersection area is big enough for overlap
* @return {@link IntersectionType} between given {@link Polygon}s
*/
private IntersectionType findIntersectionType(final Polygon polygon, final Polygon otherPolygon) {
Clip clip = null;
try {
clip = polygon.clip(otherPolygon, ClipType.AND);
} catch (final TopologyException e) {
logger.warn(String.format("Skipping intersection check. Error clipping [%s] and [%s].", polygon, otherPolygon), e);
}
// Skip if nothing is returned
if (clip == null) {
return IntersectionType.NONE;
}
// Sum intersection area
long intersectionArea = 0;
for (final PolyLine polyline : clip.getClip()) {
if (polyline != null && polyline instanceof Polygon) {
final Polygon clippedPolygon = (Polygon) polyline;
intersectionArea += clippedPolygon.surface().asDm7Squared();
}
}
// Avoid division by zero
if (intersectionArea == 0) {
return IntersectionType.NONE;
}
// Pick the smaller building's area as baseline
final long baselineArea = Math.min(polygon.surface().asDm7Squared(), otherPolygon.surface().asDm7Squared());
final double proportion = (double) intersectionArea / baselineArea;
if (proportion >= this.overlapLowerLimit) {
return IntersectionType.OVERLAP;
} else if (proportion >= this.intersectionLowerLimit) {
return IntersectionType.INTERSECT;
}
return IntersectionType.NONE;
}
use of org.openstreetmap.atlas.geography.PolyLine in project atlas-checks by osmlab.
the class EdgeCrossingEdgeCheck method flag.
@Override
protected Optional<CheckFlag> flag(final AtlasObject object) {
// Prepare the edge being tested for checks
final Edge edge = (Edge) object;
final PolyLine edgeAsPolyLine = edge.asPolyLine();
final Rectangle edgeBounds = edge.bounds();
final Optional<Long> edgeLayer = LayerTag.getTaggedOrImpliedValue(object, 0L);
// Retrieve crossing edges
final Atlas atlas = object.getAtlas();
final Iterable<Edge> crossingEdges = atlas.edgesIntersecting(edgeBounds, // filter out the same edge, non-valid crossing edges and already flagged ones
crossingEdge -> edge.getIdentifier() != crossingEdge.getIdentifier() && isValidCrossingEdge(crossingEdge) && !this.isFlagged(generateAtlasObjectPairIdentifier(edge, crossingEdge)));
List<Edge> invalidEdges = null;
// each edge will be marked explicitly.
for (final Edge crossingEdge : crossingEdges) {
final PolyLine crossingEdgeAsPolyLine = crossingEdge.asPolyLine();
final Optional<Long> crossingEdgeLayer = LayerTag.getTaggedOrImpliedValue(crossingEdge, 0L);
final Set<Location> intersections = edgeAsPolyLine.intersections(crossingEdgeAsPolyLine);
// Check whether crossing edge can actually cross
for (final Location intersection : intersections) {
// Add this set to flagged pairs to skip it next time
this.markAsFlagged(generateAtlasObjectPairIdentifier(edge, crossingEdge));
// Check if crossing is valid or not
if (canCross(edgeAsPolyLine, edgeLayer, crossingEdgeAsPolyLine, crossingEdgeLayer, intersection)) {
continue;
}
if (invalidEdges == null) {
// Normally we expect 1 or 2 edges in the list
invalidEdges = new LinkedList<>();
}
invalidEdges.add(crossingEdge);
}
}
if (invalidEdges != null) {
final CheckFlag newFlag = new CheckFlag(getTaskIdentifier(object));
newFlag.addObject(object);
newFlag.addInstruction(this.getLocalizedInstruction(0, object.getOsmIdentifier()));
invalidEdges.forEach(invalidEdge -> {
newFlag.addObject(invalidEdge);
newFlag.addInstruction(this.getLocalizedInstruction(1, invalidEdge.getOsmIdentifier()));
});
return Optional.of(newFlag);
}
return Optional.empty();
}
Aggregations