Changeset 17501 in josm for trunk/src


Ignore:
Timestamp:
2021-02-21T08:17:42+01:00 (3 years ago)
Author:
GerdP
Message:

see #20473: Multipolygon repeating the tag of an outer way is not flagged

  • add new check in TagChecker
  • add new preference validator.TagChecker.ignore-keys-outer-mp-same-tag tgat can be used to list tag keys which should be ignored by this test
File:
1 edited

Legend:

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

    r17477 r17501  
    4343import org.openstreetmap.josm.data.osm.OsmUtils;
    4444import org.openstreetmap.josm.data.osm.Relation;
     45import org.openstreetmap.josm.data.osm.RelationMember;
    4546import org.openstreetmap.josm.data.osm.Tag;
    4647import org.openstreetmap.josm.data.osm.TagMap;
    4748import org.openstreetmap.josm.data.osm.Tagged;
     49import org.openstreetmap.josm.data.osm.Way;
    4850import org.openstreetmap.josm.data.osm.visitor.MergeSourceBuildingVisitor;
    4951import org.openstreetmap.josm.data.preferences.sources.ValidatorPrefHelper;
     
    102104    private static final Set<String> ignoreForLevenshtein = new HashSet<>();
    103105
     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
    104109    /** The preferences prefix */
    105110    protected static final String PREFIX = ValidatorPrefHelper.PREFIX + "." + TagChecker.class.getSimpleName();
     
    155160     */
    156161    public static final String PREF_CHECK_PRESETS_TYPES_BEFORE_UPLOAD = PREF_CHECK_PRESETS_TYPES + BEFORE_UPLOAD;
     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";
    157167
    158168    private static final int MAX_LEVENSHTEIN_DISTANCE = 2;
     
    180190
    181191    // CHECKSTYLE.OFF: SingleSpaceSeparator
    182     protected static final int EMPTY_VALUES             = 1200;
    183     protected static final int INVALID_KEY              = 1201;
    184     protected static final int INVALID_VALUE            = 1202;
    185     protected static final int FIXME                    = 1203;
    186     protected static final int INVALID_SPACE            = 1204;
    187     protected static final int INVALID_KEY_SPACE        = 1205;
    188     protected static final int INVALID_HTML             = 1206; /* 1207 was PAINT */
    189     protected static final int LONG_VALUE               = 1208;
    190     protected static final int LONG_KEY                 = 1209;
    191     protected static final int LOW_CHAR_VALUE           = 1210;
    192     protected static final int LOW_CHAR_KEY             = 1211;
    193     protected static final int MISSPELLED_VALUE         = 1212;
    194     protected static final int MISSPELLED_KEY           = 1213;
    195     protected static final int MULTIPLE_SPACES          = 1214;
    196     protected static final int MISSPELLED_VALUE_NO_FIX  = 1215;
    197     protected static final int UNUSUAL_UNICODE_CHAR_VALUE = 1216;
    198     protected static final int INVALID_PRESETS_TYPE     = 1217;
    199     protected static final int MULTIPOLYGON_NO_AREA     = 1218;
    200     protected static final int MULTIPOLYGON_INCOMPLETE  = 1219;
    201     protected static final int MULTIPOLYGON_MAYBE_NO_AREA = 1220;
     192    protected static final int EMPTY_VALUES                     = 1200;
     193    protected static final int INVALID_KEY                      = 1201;
     194    protected static final int INVALID_VALUE                    = 1202;
     195    protected static final int FIXME                            = 1203;
     196    protected static final int INVALID_SPACE                    = 1204;
     197    protected static final int INVALID_KEY_SPACE                = 1205;
     198    protected static final int INVALID_HTML                     = 1206; /* 1207 was PAINT */
     199    protected static final int LONG_VALUE                       = 1208;
     200    protected static final int LONG_KEY                         = 1209;
     201    protected static final int LOW_CHAR_VALUE                   = 1210;
     202    protected static final int LOW_CHAR_KEY                     = 1211;
     203    protected static final int MISSPELLED_VALUE                 = 1212;
     204    protected static final int MISSPELLED_KEY                   = 1213;
     205    protected static final int MULTIPLE_SPACES                  = 1214;
     206    protected static final int MISSPELLED_VALUE_NO_FIX          = 1215;
     207    protected static final int UNUSUAL_UNICODE_CHAR_VALUE       = 1216;
     208    protected static final int INVALID_PRESETS_TYPE             = 1217;
     209    protected static final int MULTIPOLYGON_NO_AREA             = 1218;
     210    protected static final int MULTIPOLYGON_INCOMPLETE          = 1219;
     211    protected static final int MULTIPOLYGON_MAYBE_NO_AREA       = 1220;
     212    protected static final int MULTIPOLYGON_SAME_TAG_ON_OUTER   = 1221;
    202213    // CHECKSTYLE.ON: SingleSpaceSeparator
    203214
     
    254265        oftenUsedTags.clear();
    255266        presetIndex.clear();
     267        ignoreForOuterMPSameTagCheck.clear();
    256268
    257269        StringBuilder errorSources = new StringBuilder();
     
    637649
    638650        if (p instanceof Relation && p.hasTag("type", "multipolygon")) {
    639             checkMultipolygonTags(p);
     651        checkMultipolygonTags(p);
    640652        }
    641653
     
    678690
    679691    private void checkMultipolygonTags(OsmPrimitive p) {
    680         if (p.isAnnotated() || hasAcceptedPrimaryTagForMultipolygon(p))
     692        if (p.isAnnotated() || p.keySet().stream()
     693                .anyMatch(k -> k.matches("^(abandoned|construction|demolished|disused|planned|razed|removed|was).*")))
    681694            return;
    682         if (p.keySet().stream().anyMatch(k -> k.matches("^(abandoned|construction|demolished|disused|planned|razed|removed|was).*")))
     695
     696        checkOuterWaysOfRelation((Relation) p);
     697
     698        if (hasAcceptedPrimaryTagForMultipolygon(p))
    683699            return;
    684 
    685700        TestError.Builder builder = null;
    686701        if (p.hasKey("surface")) {
     
    706721        }
    707722        errors.add(builder.primitives(p).build());
     723    }
     724
     725    /**
     726     * Check if an outer way of the relation has the same tag as the relation.
     727     * @param rel the relation
     728     */
     729    private void checkOuterWaysOfRelation(Relation rel) {
     730        for (Entry<String, String> tag : rel.getInterestingTags().entrySet()) {
     731            if (ignoreForOuterMPSameTagCheck.contains(tag.getKey()))
     732                continue;
     733
     734            Set<Way> sameOuters = rel.getMembers().stream()
     735                    .filter(rm -> rm.isWay() && rm.getWay().isArea() && "outer".equals(rm.getRole())
     736                            && tag.getValue().equals(rm.getWay().get(tag.getKey())))
     737                    .map(RelationMember::getWay).collect(Collectors.toSet());
     738            if (!sameOuters.isEmpty()) {
     739                List<OsmPrimitive> primitives = new ArrayList<>(sameOuters.size() + 1);
     740                primitives.add(rel);
     741                primitives.addAll(sameOuters);
     742                Way w = new Way();
     743                w.put(tag.getKey(), tag.getValue());
     744                if (hasAcceptedPrimaryTagForMultipolygon(w)) {
     745                    errors.add(TestError.builder(this, Severity.WARNING, MULTIPOLYGON_SAME_TAG_ON_OUTER)
     746                            .message(tr("Multipolygon outer way repeats major tag of relation"),
     747                                    marktr("Same tag:''{0}''=''{1}''"), tag.getKey(), tag.getValue())
     748                            .primitives(primitives)
     749                            .build());
     750                } else {
     751                    errors.add(TestError.builder(this, Severity.OTHER, MULTIPOLYGON_SAME_TAG_ON_OUTER)
     752                            .message(tr("Multipolygon outer way repeats tag of relation"),
     753                                    marktr("Same tag:''{0}''=''{1}''"), tag.getKey(), tag.getValue())
     754                            .primitives(primitives)
     755                            .build());
     756                }
     757            }
     758        }
    708759    }
    709760
     
    10471098        }
    10481099        deprecatedChecker = OsmValidator.getTest(MapCSSTagChecker.class);
     1100        ignoreForOuterMPSameTagCheck.addAll(Config.getPref().getList(PREF_KEYS_IGNORE_OUTER_MP_SAME_TAG, Collections.emptyList()));
    10491101    }
    10501102
Note: See TracChangeset for help on using the changeset viewer.