Ticket #18240: 18240.patch
| File 18240.patch, 7.2 KB (added by , 6 years ago) |
|---|
-
src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
72 72 public static final int EQUAL_RINGS = 1616; 73 73 /** Multipolygon rings share nodes */ 74 74 public static final int RINGS_SHARE_NODES = 1617; 75 /** Incomplete multipolygon was modified */ 76 public static final int MODIFIED_INCOMPLETE = 1618; 75 77 76 78 private static final int FOUND_INSIDE = 1; 77 79 private static final int FOUND_OUTSIDE = 2; … … 95 97 List<TestError> tmpErrors = new ArrayList<>(30); 96 98 boolean hasUnexpectedWayRoles = checkMembersAndRoles(r, tmpErrors); 97 99 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 } 98 106 // 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 } 105 117 } 106 118 errors.addAll(tmpErrors); 107 119 } … … 506 518 return en != null && p.get().contains(en.getX(), en.getY()); 507 519 } 508 520 521 509 522 /** 510 523 * Determine multipolygon ways which are intersecting (crossing without a common node) or sharing one or more way segments. 511 524 * See also {@link CrossingWays} … … 520 533 HashMap<PolyData, List<PolyData>> sharedWaySegmentsPolygonsMap = new HashMap<>(); 521 534 522 535 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 536 528 Map<PolyData, List<PolyData>> problemPolygonMap = (loop == 0) ? crossingPolygonsMap 529 : sharedWaySegmentsPolygonsMap; 537 Map<List<Way>, List<WaySegment>> crossingWays = findIntersectingWays(r, loop == 1); 530 538 531 for (Way w : r.getMemberPrimitives(Way.class)) {532 findIntersectingWay(w, cellSegments, problemWays, loop == 1);533 }539 if (!crossingWays.isEmpty()) { 540 Map<PolyData, List<PolyData>> problemPolygonMap = (loop == 0) ? crossingPolygonsMap 541 : sharedWaySegmentsPolygonsMap; 534 542 535 if (!problemWays.isEmpty()) {536 543 List<PolyData> allPolygons = new ArrayList<>(innerPolygons.size() + outerPolygons.size()); 537 544 allPolygons.addAll(innerPolygons); 538 545 allPolygons.addAll(outerPolygons); 539 546 540 for (Entry<List<Way>, List<WaySegment>> entry : problemWays.entrySet()) {547 for (Entry<List<Way>, List<WaySegment>> entry : crossingWays.entrySet()) { 541 548 List<Way> ways = entry.getKey(); 542 549 if (ways.size() != 2) 543 550 continue; … … 586 593 } 587 594 588 595 /** 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 /** 589 637 * Find ways which are crossing without sharing a node. 590 638 * @param w way that is member of the relation 591 639 * @param cellSegments map with already collected way segments 592 * @param crossingWays list to collect crossing ways640 * @param crossingWays map to collect crossing ways and related segments 593 641 * @param findSharedWaySegments true: find shared way segments instead of crossings 594 642 */ 595 643 private static void findIntersectingWay(Way w, Map<Point2D, List<WaySegment>> cellSegments, … … 607 655 for (WaySegment es2 : segments) { 608 656 609 657 List<WaySegment> highlight; 610 if (es2.way == w )611 continue; // reported by CrossingWays.SelfIntersection612 if (findSharedWaySegments && !es1.isSimilar(es2))658 if (es2.way == w // reported by CrossingWays.SelfIntersection 659 || (findSharedWaySegments && !es1.isSimilar(es2)) 660 || (!findSharedWaySegments && !es1.intersects(es2))) 613 661 continue; 614 if (!findSharedWaySegments && !es1.intersects(es2))615 continue;616 662 617 663 List<Way> prims = Arrays.asList(es1.way, es2.way); 618 664 if ((highlight = crossingWays.get(prims)) == null) {
