Ticket #17010: 17010-v2.patch
| File 17010-v2.patch, 8.5 KB (added by , 7 years ago) |
|---|
-
src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
53 53 public static final int WRONG_MEMBER_ROLE = 1602; 54 54 /** Multipolygon is not closed */ 55 55 public static final int NON_CLOSED_WAY = 1603; 56 /** No outer way for multipolygon */57 public static final int MISSING_OUTER_WAY = 1604;58 56 /** Multipolygon inner way is outside */ 59 57 public static final int INNER_WAY_OUTSIDE = 1605; 60 58 /** Intersection between multipolygon ways */ … … 132 130 @Override 133 131 public void visit(Relation r) { 134 132 if (r.isMultipolygon() && r.getMembersCount() > 0) { 135 checkMembersAndRoles(r);136 checkOuterWay(r);133 List<TestError> tmpErrors = new ArrayList<>(30); 134 boolean hasUnexpectedWayRoles = checkMembersAndRoles(r, tmpErrors); 137 135 boolean hasRepeatedMembers = checkRepeatedWayMembers(r); 138 136 // Rest of checks is only for complete multipolygon 139 if (!has RepeatedMembers && !r.hasIncompleteMembers()) {137 if (!hasUnexpectedWayRoles && !hasRepeatedMembers && !r.hasIncompleteMembers()) { 140 138 Multipolygon polygon = new Multipolygon(r); 141 139 checkStyleConsistency(r, polygon); 142 140 checkGeometryAndRoles(r, polygon); 141 } else { 142 // if we are not able to calculate the geometry we report the messages found by simple checks 143 errors.addAll(tmpErrors); 143 144 } 144 145 } 145 146 } 146 147 147 148 /** 148 * Checks that multipolygon has at least an outer way:<ul>149 * <li>{@link #MISSING_OUTER_WAY}: No outer way for multipolygon</li>150 * </ul>151 * @param r relation152 */153 private void checkOuterWay(Relation r) {154 for (RelationMember m : r.getMembers()) {155 if (m.isWay() && "outer".equals(m.getRole())) {156 return;157 }158 }159 errors.add(TestError.builder(this, Severity.WARNING, MISSING_OUTER_WAY)160 .message(r.isBoundary() ? tr("No outer way for boundary") : tr("No outer way for multipolygon"))161 .primitives(r)162 .build());163 }164 165 /**166 149 * Various style-related checks:<ul> 167 150 * <li>{@link #NO_STYLE_POLYGON}: Multipolygon relation should be tagged with area tags and not the outer way</li> 168 151 * <li>{@link #INNER_STYLE_MISMATCH}: With the currently used mappaint style the style for inner way equals the multipolygon style</li> … … 527 510 String calculatedRole = (pol.level % 2 == 0) ? "outer" : "inner"; 528 511 for (long wayId : pol.outerWay.getWayIds()) { 529 512 RelationMember member = wayMap.get(wayId); 530 if (! member.getRole().equals(calculatedRole)) {513 if (!calculatedRole.equals(member.getRole())) { 531 514 errors.add(TestError.builder(this, Severity.ERROR, WRONG_MEMBER_ROLE) 532 515 .message(RelationChecker.ROLE_VERIF_PROBLEM_MSG, 533 516 marktr("Role for ''{0}'' should be ''{1}''"), … … 704 687 * <li>{@link #WRONG_MEMBER_TYPE}: Non-Way in multipolygon</li> 705 688 * </ul> 706 689 * @param r relation 690 * @param tmpErrors list that will contain found errors 691 * @return true if ways with roles other than inner, outer or empty where found 707 692 */ 708 private void checkMembersAndRoles(Relation r) { 693 private boolean checkMembersAndRoles(Relation r, List<TestError> tmpErrors) { 694 boolean hasUnexpectedWayRole = false; 709 695 for (RelationMember rm : r.getMembers()) { 710 696 if (rm.isWay()) { 711 if (!(rm.hasRole("inner", "outer") || !rm.hasRole())) { 712 errors.add(TestError.builder(this, Severity.WARNING, WRONG_MEMBER_ROLE) 713 .message(tr("No useful role for multipolygon member")) 697 if (rm.hasRole() && !(rm.hasRole("inner", "outer"))) 698 hasUnexpectedWayRole = true; 699 if (!(rm.hasRole("inner", "outer")) || !rm.hasRole()) { 700 tmpErrors.add(TestError.builder(this, Severity.ERROR, WRONG_MEMBER_ROLE) 701 .message(tr("Role for multipolygon way member should be inner or outer")) 714 702 .primitives(Arrays.asList(r, rm.getMember())) 715 703 .build()); 716 704 } 717 705 } else { 718 706 if (!r.isBoundary() || !rm.hasRole("admin_centre", "label", "subarea", "land_area")) { 719 errors.add(TestError.builder(this, Severity.WARNING, WRONG_MEMBER_TYPE)707 tmpErrors.add(TestError.builder(this, Severity.WARNING, WRONG_MEMBER_TYPE) 720 708 .message(r.isBoundary() ? tr("Non-Way in boundary") : tr("Non-Way in multipolygon")) 721 709 .primitives(Arrays.asList(r, rm.getMember())) 722 710 .build()); … … 723 711 } 724 712 } 725 713 } 714 return hasUnexpectedWayRole; 726 715 } 727 716 728 717 private static Collection<? extends OsmPrimitive> combineRelAndPrimitives(Relation r, Collection<? extends OsmPrimitive> primitives) { … … 748 737 boolean hasDups = false; 749 738 Map<OsmPrimitive, List<RelationMember>> seenMemberPrimitives = new HashMap<>(); 750 739 for (RelationMember rm : r.getMembers()) { 740 if (!rm.isWay()) 741 continue; 751 742 List<RelationMember> list = seenMemberPrimitives.get(rm.getMember()); 752 743 if (list == null) { 753 744 list = new ArrayList<>(2); -
src/org/openstreetmap/josm/data/validation/tests/RelationChecker.java
18 18 import org.openstreetmap.josm.data.osm.OsmPrimitiveType; 19 19 import org.openstreetmap.josm.data.osm.Relation; 20 20 import org.openstreetmap.josm.data.osm.RelationMember; 21 import org.openstreetmap.josm.data.validation.OsmValidator; 21 22 import org.openstreetmap.josm.data.validation.Severity; 22 23 import org.openstreetmap.josm.data.validation.Test; 23 24 import org.openstreetmap.josm.data.validation.TestError; 25 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 24 26 import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset; 25 27 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetItem; 26 28 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetType; … … 60 62 * @since 6731 61 63 */ 62 64 public static final String ROLE_VERIF_PROBLEM_MSG = tr("Role verification problem"); 65 private boolean ignoreMultiPolygons; 63 66 64 67 /** 65 68 * Constructor … … 99 102 } 100 103 101 104 @Override 105 public void startTest(ProgressMonitor progressMonitor) { 106 super.startTest(progressMonitor); 107 108 for (Test t : OsmValidator.getEnabledTests(false)) { 109 if (t instanceof MultipolygonTest) { 110 ignoreMultiPolygons = true; 111 break; 112 } 113 } 114 } 115 116 @Override 102 117 public void visit(Relation n) { 118 Map<String, RoleInfo> map = buildRoleInfoMap(n); 119 if (map.isEmpty()) { 120 errors.add(TestError.builder(this, Severity.ERROR, RELATION_EMPTY) 121 .message(tr("Relation is empty")) 122 .primitives(n) 123 .build()); 124 } 125 if (ignoreMultiPolygons && n.isMultipolygon()) { 126 // see #17010: don't report same problem twice 127 return; 128 } 103 129 Map<Role, String> allroles = buildAllRoles(n); 104 130 if (allroles.isEmpty() && n.hasTag("type", "route") 105 131 && n.hasTag("route", "train", "subway", "monorail", "tram", "bus", "trolleybus", "aerialway", "ferry")) { … … 114 140 .build()); 115 141 } 116 142 117 Map<String, RoleInfo> map = buildRoleInfoMap(n); 118 if (map.isEmpty()) { 119 errors.add(TestError.builder(this, Severity.ERROR, RELATION_EMPTY) 120 .message(tr("Relation is empty")) 121 .primitives(n) 122 .build()); 123 } else if (!allroles.isEmpty()) { 143 if (!map.isEmpty() && !allroles.isEmpty()) { 124 144 checkRoles(n, allroles, map); 125 145 } 126 146 }
