Search in sources :

Example 1 with Edge

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

the class SinkIslandCheck method flag.

@Override
protected Optional<CheckFlag> flag(final AtlasObject object) {
    // Flag to keep track of whether we found an issue or not
    boolean emptyFlag = false;
    // The current edge to be explored
    Edge candidate = (Edge) object;
    // A set of all edges that we have already explored
    final Set<AtlasObject> explored = new HashSet<>(this.storeSize, LOAD_FACTOR);
    // A set of all edges that we explore that have no outgoing edges
    final Set<AtlasObject> terminal = new HashSet<>();
    // Current queue of candidates that we can draw from
    final Queue<Edge> candidates = new ArrayDeque<>(this.storeSize);
    // Start edge always explored
    explored.add(candidate);
    // Keep looping while we still have a valid candidate to explore
    while (candidate != null) {
        // process
        if (this.isFlagged(candidate.getIdentifier())) {
            emptyFlag = true;
            break;
        }
        // Retrieve all the valid outgoing edges to explore
        final Set<Edge> outEdges = candidate.outEdges().stream().filter(this::validEdge).collect(Collectors.toSet());
        if (outEdges.isEmpty()) {
            // Sink edge. Don't mark the edge explored until we know how big the tree is
            terminal.add(candidate);
        } else {
            // Add the current candidate to the set of already explored edges
            explored.add(candidate);
            // From the list of outgoing edges from the current candidate filter out any edges
            // that have already been explored and add all the rest to the queue of possible
            // candidates
            outEdges.stream().filter(outEdge -> !explored.contains(outEdge)).forEach(candidates::add);
            // loop and assume that this is not a SinkIsland
            if (candidates.size() + explored.size() > this.treeSize) {
                emptyFlag = true;
                break;
            }
        }
        // Get the next candidate
        candidate = candidates.poll();
    }
    // flag.
    if (!emptyFlag) {
        // Include all touched edges
        explored.addAll(terminal);
    }
    // Set every explored edge as flagged for any other processes to know that we have already
    // process all those edges
    explored.forEach(marked -> this.markAsFlagged(marked.getIdentifier()));
    // Create the flag if and only if the empty flag value is not set to false
    return emptyFlag ? Optional.empty() : Optional.of(createFlag(explored, this.getLocalizedInstruction(0)));
}
Also used : Arrays(java.util.Arrays) Set(java.util.Set) Edge(org.openstreetmap.atlas.geography.atlas.items.Edge) RouteTag(org.openstreetmap.atlas.tags.RouteTag) Collectors(java.util.stream.Collectors) Validators(org.openstreetmap.atlas.tags.annotations.validation.Validators) HashSet(java.util.HashSet) HighwayTag(org.openstreetmap.atlas.tags.HighwayTag) List(java.util.List) BaseCheck(org.openstreetmap.atlas.checks.base.BaseCheck) Configuration(org.openstreetmap.atlas.utilities.configuration.Configuration) AtlasObject(org.openstreetmap.atlas.geography.atlas.items.AtlasObject) TagPredicates(org.openstreetmap.atlas.checks.atlas.predicates.TagPredicates) SyntheticBoundaryNodeTag(org.openstreetmap.atlas.tags.SyntheticBoundaryNodeTag) Optional(java.util.Optional) AerowayTag(org.openstreetmap.atlas.tags.AerowayTag) Queue(java.util.Queue) ArrayDeque(java.util.ArrayDeque) CheckFlag(org.openstreetmap.atlas.checks.flag.CheckFlag) AtlasObject(org.openstreetmap.atlas.geography.atlas.items.AtlasObject) Edge(org.openstreetmap.atlas.geography.atlas.items.Edge) ArrayDeque(java.util.ArrayDeque) HashSet(java.util.HashSet)

Example 2 with Edge

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

the class RoundaboutValenceCheck method getAllRoundaboutEdges.

/**
 * This method gets all edges in a roundabout given one edge in that roundabout
 *
 * @param edge
 *            An Edge object known to be a roundabout edge
 * @return A set of edges in the roundabout
 */
private Set<Edge> getAllRoundaboutEdges(final Edge edge) {
    final Set<Edge> roundaboutEdges = new HashSet<>();
    // Initialize a queue to add yet to be processed connected edges to
    final Queue<Edge> queue = new LinkedList<>();
    // Mark the current Edge as visited and enqueue it
    this.markAsFlagged(edge.getIdentifier());
    queue.add(edge);
    // As long as the queue is not empty
    while (!queue.isEmpty()) {
        // Dequeue a connected edge and add it to the roundaboutEdges
        final Edge currentEdge = queue.poll();
        roundaboutEdges.add(currentEdge);
        // Get the edges connected to the edge e as an iterator
        final Set<Edge> connectedEdges = currentEdge.connectedEdges();
        for (final Edge connectedEdge : connectedEdges) {
            final Long edgeId = connectedEdge.getIdentifier();
            if (JunctionTag.isRoundabout(connectedEdge) && !roundaboutEdges.contains(connectedEdge)) {
                this.markAsFlagged(edgeId);
                queue.add(connectedEdge);
            }
        }
    }
    return roundaboutEdges;
}
Also used : Edge(org.openstreetmap.atlas.geography.atlas.items.Edge) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet)

Example 3 with Edge

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

the class SignPostCheck method findFirstRampEdge.

/**
 * Given a final {@link Edge}, hops back and finds the first edge that was forming the ramp.
 *
 * @param finalEdge
 *            {@link Edge} that is the last/final piece of the ramp
 * @return {@link Edge} that possibly is the first {@link Edge} forming the ramp
 */
private Edge findFirstRampEdge(final Edge finalEdge) {
    int count = 0;
    // Go back and collect edges
    Edge nextEdge = finalEdge;
    while (count < MAX_EDGE_COUNT_FOR_RAMP) {
        count++;
        // Break if edge has no heading
        final Optional<Heading> initialHeading = nextEdge.asPolyLine().initialHeading();
        if (!initialHeading.isPresent()) {
            break;
        }
        // Collect in edges and make sure there is not more than one
        final Set<Edge> inEdges = nextEdge.inEdges();
        if (inEdges.isEmpty() || inEdges.size() > 1) {
            break;
        }
        // Find the edge that precedes nextEdge
        final HighwayTag highwayTag = nextEdge.highwayTag();
        final Edge precedingEdge = inEdges.iterator().next();
        // Ignore if edge has a different classification
        if (!highwayTag.isIdenticalClassification(precedingEdge.highwayTag())) {
            break;
        }
        // Break if given edge has no heading
        final Optional<Heading> finalHeading = precedingEdge.asPolyLine().finalHeading();
        if (!finalHeading.isPresent() || initialHeading.get().asPositiveAngle().difference(finalHeading.get().asPositiveAngle()).isGreaterThan(this.rampAngleDifference)) {
            break;
        }
        nextEdge = precedingEdge;
    }
    return nextEdge;
}
Also used : Heading(org.openstreetmap.atlas.geography.Heading) HighwayTag(org.openstreetmap.atlas.tags.HighwayTag) Edge(org.openstreetmap.atlas.geography.atlas.items.Edge)

Example 4 with Edge

use of org.openstreetmap.atlas.geography.atlas.items.Edge 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 5 with Edge

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

the class RoundaboutValenceCheck method flag.

/**
 * This is the actual function that will check to see whether the object needs to be flagged.
 *
 * @param object
 *            the atlas object supplied by the Atlas-Checks framework for evaluation
 * @return an optional {@link CheckFlag} object that
 */
@Override
protected Optional<CheckFlag> flag(final AtlasObject object) {
    final Edge edge = (Edge) object;
    // Get all edges in the roundabout
    final Set<Edge> roundaboutEdges = getAllRoundaboutEdges(edge);
    final Set<Edge> connectedEdges = roundaboutEdges.stream().flatMap(roundaboutEdge -> roundaboutEdge.connectedEdges().stream()).filter(HighwayTag::isCarNavigableHighway).filter(Edge::isMasterEdge).filter(currentEdge -> !JunctionTag.isRoundabout(currentEdge)).filter(currentEdge -> !roundaboutEdges.contains(currentEdge)).collect(Collectors.toSet());
    final int totalRoundaboutValence = connectedEdges.size();
    // or greater than or equal to the maximum configured number of connections
    if (totalRoundaboutValence < this.minimumValence || totalRoundaboutValence > this.maximumValence) {
        this.markAsFlagged(object.getIdentifier());
        // If the roundabout valence is 1, this should be labelled as a turning loop instead
        if (totalRoundaboutValence == 1) {
            return Optional.of(this.createFlag(roundaboutEdges, this.getLocalizedInstruction(1, edge.getOsmIdentifier())));
        }
        // Otherwise, we want to flag and given information about identifier and valence
        return Optional.of(this.createFlag(roundaboutEdges, this.getLocalizedInstruction(0, edge.getOsmIdentifier(), totalRoundaboutValence)));
    } else // If the totalRoundaboutValence is not unusual, we don't flag the object
    {
        return Optional.empty();
    }
}
Also used : Arrays(java.util.Arrays) Set(java.util.Set) Edge(org.openstreetmap.atlas.geography.atlas.items.Edge) Collectors(java.util.stream.Collectors) HashSet(java.util.HashSet) HighwayTag(org.openstreetmap.atlas.tags.HighwayTag) List(java.util.List) BaseCheck(org.openstreetmap.atlas.checks.base.BaseCheck) JunctionTag(org.openstreetmap.atlas.tags.JunctionTag) Configuration(org.openstreetmap.atlas.utilities.configuration.Configuration) AtlasObject(org.openstreetmap.atlas.geography.atlas.items.AtlasObject) Optional(java.util.Optional) Queue(java.util.Queue) LinkedList(java.util.LinkedList) CheckFlag(org.openstreetmap.atlas.checks.flag.CheckFlag) HighwayTag(org.openstreetmap.atlas.tags.HighwayTag) Edge(org.openstreetmap.atlas.geography.atlas.items.Edge)

Aggregations

Edge (org.openstreetmap.atlas.geography.atlas.items.Edge)13 CheckFlag (org.openstreetmap.atlas.checks.flag.CheckFlag)6 HashSet (java.util.HashSet)5 HighwayTag (org.openstreetmap.atlas.tags.HighwayTag)4 Arrays (java.util.Arrays)3 List (java.util.List)3 Optional (java.util.Optional)3 Set (java.util.Set)3 BaseCheck (org.openstreetmap.atlas.checks.base.BaseCheck)3 Location (org.openstreetmap.atlas.geography.Location)3 AtlasObject (org.openstreetmap.atlas.geography.atlas.items.AtlasObject)3 Configuration (org.openstreetmap.atlas.utilities.configuration.Configuration)3 LinkedList (java.util.LinkedList)2 Queue (java.util.Queue)2 Collectors (java.util.stream.Collectors)2 Heading (org.openstreetmap.atlas.geography.Heading)2 PolyLine (org.openstreetmap.atlas.geography.PolyLine)2 Area (org.openstreetmap.atlas.geography.atlas.items.Area)2 Validators (org.openstreetmap.atlas.tags.annotations.validation.Validators)2 ArrayDeque (java.util.ArrayDeque)1