Changeset 15510 in josm


Ignore:
Timestamp:
2019-11-05T10:50:31+01:00 (5 years ago)
Author:
GerdP
Message:

see #18240 : apply 18240.patch

  • Warn if incomplete multipolygon relation (MP) was modified.
  • Perform check for crossing ways for all complete ways of the MP
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java

    r15244 r15510  
    7373    /** Multipolygon rings share nodes */
    7474    public static final int RINGS_SHARE_NODES = 1617;
     75    /** Incomplete multipolygon was modified */
     76    public static final int MODIFIED_INCOMPLETE = 1618;
    7577
    7678    private static final int FOUND_INSIDE = 1;
     
    9698            boolean hasUnexpectedWayRoles = checkMembersAndRoles(r, tmpErrors);
    9799            boolean hasRepeatedMembers = checkRepeatedWayMembers(r);
     100            if (r.isModified() && r.hasIncompleteMembers()) {
     101                errors.add(TestError.builder(this, Severity.WARNING, MODIFIED_INCOMPLETE)
     102                        .message(tr("Incomplete multipolygon relation was modified"))
     103                        .primitives(r)
     104                        .build());
     105            }
    98106            // Rest of checks is only for complete multipolygon
    99             if (!hasUnexpectedWayRoles && !hasRepeatedMembers && !r.hasIncompleteMembers()) {
    100                 Multipolygon polygon = new Multipolygon(r);
    101                 checkStyleConsistency(r, polygon);
    102                 checkGeometryAndRoles(r, polygon);
    103                 // see #17010: don't report problems twice
    104                 tmpErrors.removeIf(e -> e.getCode() == WRONG_MEMBER_ROLE);
     107            if (!hasUnexpectedWayRoles && !hasRepeatedMembers) {
     108                if (r.hasIncompleteMembers()) {
     109                    findIntersectingWaysIncomplete(r);
     110                } else {
     111                    Multipolygon polygon = new Multipolygon(r);
     112                    checkStyleConsistency(r, polygon);
     113                    checkGeometryAndRoles(r, polygon);
     114                    // see #17010: don't report problems twice
     115                    tmpErrors.removeIf(e -> e.getCode() == WRONG_MEMBER_ROLE);
     116                }
    105117            }
    106118            errors.addAll(tmpErrors);
     
    507519    }
    508520
     521
    509522    /**
    510523     * Determine multipolygon ways which are intersecting (crossing without a common node) or sharing one or more way segments.
     
    521534
    522535        for (int loop = 0; loop < 2; loop++) {
    523             /** All way segments, grouped by cells */
    524             final Map<Point2D, List<WaySegment>> cellSegments = new HashMap<>(1000);
    525             /** The already detected ways in error */
    526             final Map<List<Way>, List<WaySegment>> problemWays = new HashMap<>(50);
    527 
    528             Map<PolyData, List<PolyData>> problemPolygonMap = (loop == 0) ? crossingPolygonsMap
    529                     : sharedWaySegmentsPolygonsMap;
    530 
    531             for (Way w : r.getMemberPrimitives(Way.class)) {
    532                 findIntersectingWay(w, cellSegments, problemWays, loop == 1);
    533             }
    534 
    535             if (!problemWays.isEmpty()) {
     536
     537            Map<List<Way>, List<WaySegment>> crossingWays = findIntersectingWays(r, loop == 1);
     538
     539            if (!crossingWays.isEmpty()) {
     540                Map<PolyData, List<PolyData>> problemPolygonMap = (loop == 0) ? crossingPolygonsMap
     541                        : sharedWaySegmentsPolygonsMap;
     542
    536543                List<PolyData> allPolygons = new ArrayList<>(innerPolygons.size() + outerPolygons.size());
    537544                allPolygons.addAll(innerPolygons);
    538545                allPolygons.addAll(outerPolygons);
    539546
    540                 for (Entry<List<Way>, List<WaySegment>> entry : problemWays.entrySet()) {
     547                for (Entry<List<Way>, List<WaySegment>> entry : crossingWays.entrySet()) {
    541548                    List<Way> ways = entry.getKey();
    542549                    if (ways.size() != 2)
     
    587594
    588595    /**
     596    * Determine multipolygon ways which are intersecting (crossing without a common node).
     597    * This should only be used for relations with incomplete members.
     598    * See also {@link CrossingWays}
     599    * @param r the relation (for error reporting)
     600     */
     601    private void findIntersectingWaysIncomplete(Relation r) {
     602        for (Entry<List<Way>, List<WaySegment>> entry : findIntersectingWays(r, false).entrySet()) {
     603            List<Way> ways = entry.getKey();
     604            if (ways.size() != 2)
     605                continue;
     606
     607            errors.add(TestError.builder(this, Severity.ERROR, CROSSING_WAYS)
     608                    .message(tr("Intersection between multipolygon ways"))
     609                    .primitives(Arrays.asList(r, ways.get(0), ways.get(1)))
     610                    .highlightWaySegments(entry.getValue())
     611                    .build());
     612        }
     613    }
     614
     615    /**
     616     * See {@link CrossingWays}
     617     * @param r the relation
     618     * @param findSharedWaySegments true: find shared way segments instead of crossings
     619     * @return map with crossing ways and the related segments
     620     */
     621    private static Map<List<Way>, List<WaySegment>> findIntersectingWays(Relation r, boolean findSharedWaySegments) {
     622        /** All way segments, grouped by cells */
     623        final Map<Point2D, List<WaySegment>> cellSegments = new HashMap<>(1000);
     624        /** The detected crossing ways */
     625        final Map<List<Way>, List<WaySegment>> crossingWays = new HashMap<>(50);
     626
     627        for (Way w: r.getMemberPrimitives(Way.class)) {
     628            if (!w.hasIncompleteNodes()) {
     629                findIntersectingWay(w, cellSegments, crossingWays, findSharedWaySegments);
     630            }
     631        }
     632        return crossingWays;
     633    }
     634
     635
     636    /**
    589637     * Find ways which are crossing without sharing a node.
    590638     * @param w way that is member of the relation
    591639     * @param cellSegments map with already collected way segments
    592      * @param crossingWays list to collect crossing ways
     640     * @param crossingWays map to collect crossing ways and related segments
    593641     * @param findSharedWaySegments true: find shared way segments instead of crossings
    594642     */
     
    608656
    609657                    List<WaySegment> highlight;
    610                     if (es2.way == w)
    611                         continue; // reported by CrossingWays.SelfIntersection
    612                     if (findSharedWaySegments && !es1.isSimilar(es2))
    613                         continue;
    614                     if (!findSharedWaySegments && !es1.intersects(es2))
     658                    if (es2.way == w // reported by CrossingWays.SelfIntersection
     659                            || (findSharedWaySegments && !es1.isSimilar(es2))
     660                            || (!findSharedWaySegments && !es1.intersects(es2)))
    615661                        continue;
    616662
Note: See TracChangeset for help on using the changeset viewer.