Search in sources :

Example 1 with Polygon

use of org.openstreetmap.atlas.geography.Polygon 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;
}
Also used : PolyLine(org.openstreetmap.atlas.geography.PolyLine) PolyLine(org.openstreetmap.atlas.geography.PolyLine) Line(org.openstreetmap.atlas.geography.atlas.items.Line) Area(org.openstreetmap.atlas.geography.atlas.items.Area) CoreException(org.openstreetmap.atlas.exception.CoreException) CheckFlag(org.openstreetmap.atlas.checks.flag.CheckFlag) Polygon(org.openstreetmap.atlas.geography.Polygon) Edge(org.openstreetmap.atlas.geography.atlas.items.Edge) Location(org.openstreetmap.atlas.geography.Location)

Example 2 with Polygon

use of org.openstreetmap.atlas.geography.Polygon 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;
}
Also used : Clip(org.openstreetmap.atlas.geography.clipping.Clip) PolyLine(org.openstreetmap.atlas.geography.PolyLine) Polygon(org.openstreetmap.atlas.geography.Polygon) TopologyException(com.vividsolutions.jts.geom.TopologyException)

Example 3 with Polygon

use of org.openstreetmap.atlas.geography.Polygon in project atlas-checks by osmlab.

the class IntersectingBuildingsCheck method flag.

@Override
protected Optional<CheckFlag> flag(final AtlasObject object) {
    final Area building = (Area) object;
    // Fetch building's area as polygon and make sure it has at least 3 points
    final Polygon buildingPolygon = building.asPolygon();
    if (buildingPolygon.size() < MINIMUM_POINT_COUNT_FOR_POLYGON) {
        return Optional.empty();
    }
    // Fetch possibly intersecting buildings
    final Iterable<Area> possiblyIntersectingBuildings = object.getAtlas().areasIntersecting(building.bounds(), area -> BuildingTag.isBuilding(area) && building.getIdentifier() != area.getIdentifier() && area.intersects(buildingPolygon));
    // Assuming that we'd find intersections/overlaps below, create a flag
    final CheckFlag flag = new CheckFlag(this.getTaskIdentifier(object));
    flag.addObject(object);
    boolean hadIntersection = false;
    // Go over possible intersections
    for (final Area otherBuilding : possiblyIntersectingBuildings) {
        // Fetch other building's area as polygon and make sure it has at least 3 points
        final Polygon otherBuildingsPolygon = otherBuilding.asPolygon();
        if (otherBuildingsPolygon.size() < MINIMUM_POINT_COUNT_FOR_POLYGON) {
            continue;
        }
        // Create a unique identifier for building tuple to avoid processing same buildings more
        // than once
        final String uniqueIdentifier = getIdentifierTuple(building, otherBuilding);
        if (this.isFlagged(getIdentifierTuple(building, otherBuilding))) {
            continue;
        }
        // Find intersection type
        final IntersectionType resultType = this.findIntersectionType(buildingPolygon, otherBuildingsPolygon);
        // Flag based on intersection type
        if (resultType == IntersectionType.OVERLAP) {
            flag.addObject(otherBuilding, this.getLocalizedInstruction(0, object.getOsmIdentifier(), otherBuilding.getOsmIdentifier()));
            this.markAsFlagged(uniqueIdentifier);
            hadIntersection = true;
        } else if (resultType == IntersectionType.INTERSECT) {
            flag.addObject(otherBuilding, this.getLocalizedInstruction(1, object.getOsmIdentifier(), otherBuilding.getOsmIdentifier()));
            this.markAsFlagged(uniqueIdentifier);
            hadIntersection = true;
        }
    }
    if (hadIntersection) {
        return Optional.of(flag);
    }
    return Optional.empty();
}
Also used : Area(org.openstreetmap.atlas.geography.atlas.items.Area) CheckFlag(org.openstreetmap.atlas.checks.flag.CheckFlag) Polygon(org.openstreetmap.atlas.geography.Polygon)

Aggregations

Polygon (org.openstreetmap.atlas.geography.Polygon)3 CheckFlag (org.openstreetmap.atlas.checks.flag.CheckFlag)2 PolyLine (org.openstreetmap.atlas.geography.PolyLine)2 Area (org.openstreetmap.atlas.geography.atlas.items.Area)2 TopologyException (com.vividsolutions.jts.geom.TopologyException)1 CoreException (org.openstreetmap.atlas.exception.CoreException)1 Location (org.openstreetmap.atlas.geography.Location)1 Edge (org.openstreetmap.atlas.geography.atlas.items.Edge)1 Line (org.openstreetmap.atlas.geography.atlas.items.Line)1 Clip (org.openstreetmap.atlas.geography.clipping.Clip)1