Ticket #20473: 20473.patch
File 20473.patch, 6.5 KB (added by , 3 years ago) |
---|
-
src/org/openstreetmap/josm/data/validation/tests/TagChecker.java
42 42 import org.openstreetmap.josm.data.osm.OsmPrimitive; 43 43 import org.openstreetmap.josm.data.osm.OsmUtils; 44 44 import org.openstreetmap.josm.data.osm.Relation; 45 import org.openstreetmap.josm.data.osm.RelationMember; 45 46 import org.openstreetmap.josm.data.osm.Tag; 46 47 import org.openstreetmap.josm.data.osm.TagMap; 47 48 import org.openstreetmap.josm.data.osm.Tagged; 49 import org.openstreetmap.josm.data.osm.Way; 48 50 import org.openstreetmap.josm.data.osm.visitor.MergeSourceBuildingVisitor; 49 51 import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper; 50 52 import org.openstreetmap.josm.data.validation.OsmValidator; … … 101 103 /** tag keys that have only numerical values in the presets */ 102 104 private static final Set<String> ignoreForLevenshtein = new HashSet<>(); 103 105 106 /** tag keys that are allowed to be the same on a multipolygon and an outer way */ 107 private static final Set<String> ignoreForOuterMPSameTagCheck = new HashSet<>(); 108 104 109 /** The preferences prefix */ 105 110 protected static final String PREFIX = ValidatorPrefHelper.PREFIX + "." + TagChecker.class.getSimpleName(); 106 111 … … 155 160 */ 156 161 public static final String PREF_CHECK_PRESETS_TYPES_BEFORE_UPLOAD = PREF_CHECK_PRESETS_TYPES + BEFORE_UPLOAD; 157 162 163 /** 164 * The preference key for the list of tag keys that are allowed to be the same on a multipolygon and an outer way 165 */ 166 public static final String PREF_KEYS_IGNORE_OUTER_MP_SAME_TAG = PREFIX + ".ignore-keys-outer-mp-same-tag"; 167 168 158 169 private static final int MAX_LEVENSHTEIN_DISTANCE = 2; 159 170 160 171 protected boolean includeOtherSeverity; … … 199 210 protected static final int MULTIPOLYGON_NO_AREA = 1218; 200 211 protected static final int MULTIPOLYGON_INCOMPLETE = 1219; 201 212 protected static final int MULTIPOLYGON_MAYBE_NO_AREA = 1220; 213 protected static final int MULTIPOLYGON_SAME_TAG_ON_OUTER = 1221; 202 214 // CHECKSTYLE.ON: SingleSpaceSeparator 203 215 204 216 protected EditableList sourcesList; … … 218 230 initializeData(); 219 231 initializePresets(); 220 232 analysePresets(); 233 221 234 } 222 235 223 236 /** … … 253 266 ignoreForLevenshtein.clear(); 254 267 oftenUsedTags.clear(); 255 268 presetIndex.clear(); 269 ignoreForOuterMPSameTagCheck.clear(); 256 270 257 271 StringBuilder errorSources = new StringBuilder(); 258 272 for (String source : Config.getPref().getList(PREF_SOURCES, DEFAULT_SOURCES)) { … … 635 649 } 636 650 } 637 651 638 if (p instanceof Relation && p.hasTag("type", "multipolygon")) { 639 checkMultipolygonTags(p); 640 } 652 checkMultipolygonTags(p); 641 653 642 654 if (checkPresetsTypes) { 643 655 TagMap tags = p.getKeys(); … … 677 689 private static final Collection<String> NO_AREA_KEYS = Arrays.asList("name", "area", "ref", "access", "operator"); 678 690 679 691 private void checkMultipolygonTags(OsmPrimitive p) { 680 if ( p.isAnnotated() || hasAcceptedPrimaryTagForMultipolygon(p))692 if (!(p instanceof Relation) || !p.hasTag("type", "multipolygon")) 681 693 return; 682 if (p.keySet().stream().anyMatch(k -> k.matches("^(abandoned|construction|demolished|disused|planned|razed|removed|was).*"))) 694 695 if (p.isAnnotated() || p.keySet().stream() 696 .anyMatch(k -> k.matches("^(abandoned|construction|demolished|disused|planned|razed|removed|was).*"))) 683 697 return; 684 698 699 checkOuterWaysOfRelation((Relation) p); 700 701 if (hasAcceptedPrimaryTagForMultipolygon(p)) 702 return; 685 703 TestError.Builder builder = null; 686 704 if (p.hasKey("surface")) { 687 705 // accept often used tag surface=* as area tag … … 708 726 } 709 727 710 728 /** 729 * Check if an outer way of the relation has the same tag as the relation. 730 * @param rel the relation 731 */ 732 private void checkOuterWaysOfRelation(Relation rel) { 733 for (Entry<String, String> tag : rel.getInterestingTags().entrySet()) { 734 if (ignoreForOuterMPSameTagCheck.contains(tag.getKey())) 735 continue; 736 737 Set<Way> sameOuters = rel.getMembers().stream() 738 .filter(rm -> rm.isWay() && rm.getWay().isArea() && "outer".equals(rm.getRole()) 739 && tag.getValue().equals(rm.getWay().get(tag.getKey()))) 740 .map(RelationMember::getWay).collect(Collectors.toSet()); 741 if (!sameOuters.isEmpty()) { 742 List<OsmPrimitive> primitives = new ArrayList<>(sameOuters.size() + 1); 743 primitives.add(rel); 744 primitives.addAll(sameOuters); 745 Way w = new Way(); 746 w.put(tag.getKey(), tag.getValue()); 747 if (hasAcceptedPrimaryTagForMultipolygon(w)) { 748 errors.add(TestError.builder(this, Severity.WARNING, MULTIPOLYGON_SAME_TAG_ON_OUTER) 749 .message(tr("Multipolygon outer way repeats major tag of relation"), 750 marktr("Same tag:''{0}''=''{1}''"), tag.getKey(), tag.getValue()) 751 .primitives(primitives) 752 .build()); 753 } else { 754 errors.add(TestError.builder(this, Severity.OTHER, MULTIPOLYGON_SAME_TAG_ON_OUTER) 755 .message(tr("Multipolygon outer way repeats tag of relation"), 756 marktr("Same tag:''{0}''=''{1}''"), tag.getKey(), tag.getValue()) 757 .primitives(primitives) 758 .build()); 759 } 760 } 761 } 762 } 763 764 /** 711 765 * Check if a multipolygon has a main tag that describes the type of area. Accepts also some deprecated tags and typos. 712 766 * @param p the multipolygon 713 767 * @return true if the multipolygon has a main tag that (likely) describes the type of area. … … 1046 1100 checkPresetsTypes = checkPresetsTypes && Config.getPref().getBoolean(PREF_CHECK_PRESETS_TYPES_BEFORE_UPLOAD, true); 1047 1101 } 1048 1102 deprecatedChecker = OsmValidator.getTest(MapCSSTagChecker.class); 1103 ignoreForOuterMPSameTagCheck.addAll(Config.getPref().getList(PREF_KEYS_IGNORE_OUTER_MP_SAME_TAG, Collections.emptyList())); 1049 1104 } 1050 1105 1051 1106 @Override