Changeset 16406 in josm


Ignore:
Timestamp:
2020-05-13T15:14:41+02:00 (3 weeks ago)
Author:
GerdP
Message:

fix #19136: Validator no longer raises issues for old-style multipolygons

  • implement a a mix of blacklisting / whitelisting for tags which possibly describe the meaning of the multipolygon area
  • ignore outer way tags when looking for multipolygon area style
Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/nodist/data/multipolygon.osm

    r15244 r16406  
    37543754    <member type='way' ref='-41419' role='outer' />
    37553755    <member type='way' ref='-41421' role='outer' />
     3756    <tag k='josm_error_codes' v='1606,1610,1617' />
    37563757    <tag k='name' v='old style' />
    37573758    <tag k='type' v='multipolygon' />
     
    37843785    <member type='way' ref='-41585' role='inner' />
    37853786    <member type='way' ref='-41809' role='outer' />
     3787    <tag k='josm_error_codes' v='1610' />
    37863788    <tag k='name' v='Example 1 (02)' />
    37873789    <tag k='type' v='multipolygon' />
     
    38003802    <member type='way' ref='-41667' role='outer' />
    38013803    <member type='way' ref='-41727' role='inner' />
     3804    <tag k='josm_error_codes' v='1610' />
    38023805    <tag k='name' v='Example 3 (02)' />
    38033806    <tag k='type' v='multipolygon' />
     
    38483851    <member type='way' ref='-41575' role='inner' />
    38493852    <member type='way' ref='-41545' role='outer' />
     3853    <tag k='josm_error_codes' v='1610' />
    38503854    <tag k='name' v='Example 2 (04)' />
    38513855    <tag k='type' v='multipolygon' />
     
    38573861    <member type='way' ref='-41761' role='inner' />
    38583862    <member type='way' ref='-41655' role='outer' />
     3863    <tag k='josm_error_codes' v='1610' />
    38593864    <tag k='name' v='Example 5 (02)' />
    38603865    <tag k='type' v='multipolygon' />
     
    38643869    <member type='way' ref='-41473' role='inner' />
    38653870    <member type='way' ref='-41671' role='outer' />
     3871    <tag k='josm_error_codes' v='1610' />
    38663872    <tag k='name' v='Example 2 (02)' />
    38673873    <tag k='type' v='multipolygon' />
     
    39023908    <member type='way' ref='-41567' role='inner' />
    39033909    <member type='way' ref='-41495' role='inner' />
     3910    <tag k='josm_error_codes' v='1610' />
    39043911    <tag k='name' v='Example 6 (02)' />
    39053912    <tag k='type' v='multipolygon' />
     
    39133920    <member type='way' ref='-41659' role='outer' />
    39143921    <member type='way' ref='-41651' role='outer' />
    3915     <tag k='josm_error_codes' v='1606,1617' />
     3922    <tag k='josm_error_codes' v='1606,1610,1617' />
    39163923    <tag k='name' v='07/04 - Mixed Geometry' />
    39173924    <tag k='type' v='multipolygon' />
     
    39793986    <member type='way' ref='-41845' role='outer' />
    39803987    <member type='way' ref='-41769' role='inner' />
     3988    <tag k='josm_error_codes' v='1610' />
    39813989    <tag k='name' v='Example 7 (04) Inner' />
    39823990    <tag k='type' v='multipolygon' />
     
    39934001    <member type='way' ref='-41741' role='inner' />
    39944002    <member type='way' ref='-41447' role='outer' />
     4003    <tag k='josm_error_codes' v='1610' />
    39954004    <tag k='name' v='Example 1 (04)' />
    39964005    <tag k='type' v='multipolygon' />
     
    40024011    <member type='way' ref='-41753' role='outer' />
    40034012    <member type='way' ref='-41521' role='outer' />
     4013    <tag k='josm_error_codes' v='1610' />
    40044014    <tag k='name' v='Example 5 (04)' />
    40054015    <tag k='type' v='multipolygon' />
     
    40214031    <member type='way' ref='-41737' role='' />
    40224032    <member type='relation' ref='-42089' role='' />
    4023     <tag k='josm_error_codes' v='1601,1602' />
     4033    <tag k='josm_error_codes' v='1601,1602,1610' />
    40244034    <tag k='name' v='06/05 - wrong roles' />
    40254035    <tag k='type' v='multipolygon' />
     
    40504060    <member type='way' ref='-41787' role='outer' />
    40514061    <member type='way' ref='-41839' role='outer' />
     4062    <tag k='josm_error_codes' v='1610' />
    40524063    <tag k='name' v='Example 6 (04) Inner' />
    40534064    <tag k='type' v='multipolygon' />
     
    40644075    <member type='way' ref='-41653' role='inner' />
    40654076    <member type='way' ref='-41833' role='outer' />
     4077    <tag k='josm_error_codes' v='1610' />
    40664078    <tag k='name' v='Example 8 (04) Inner' />
    40674079    <tag k='type' v='multipolygon' />
     
    40884100    <member type='way' ref='-41543' role='outer' />
    40894101    <member type='way' ref='-41477' role='outer' />
     4102    <tag k='josm_error_codes' v='1610' />
    40904103    <tag k='name' v='Example 6 (04)' />
    40914104    <tag k='type' v='multipolygon' />
     
    40954108    <member type='way' ref='-41687' role='outer' />
    40964109    <member type='way' ref='-41769' role='outer' />
     4110    <tag k='josm_error_codes' v='1610' />
    40974111    <tag k='name' v='Example 7 (04)' />
    40984112    <tag k='type' v='multipolygon' />
     
    41014115    <member type='way' ref='-41819' role='outer' />
    41024116    <member type='way' ref='-41439' role='outer' />
     4117    <tag k='josm_error_codes' v='1610' />
    41034118    <tag k='name' v='Example 4 (02)' />
    41044119    <tag k='type' v='multipolygon' />
     
    41334148    <member type='way' ref='-41801' role='inner' />
    41344149    <member type='way' ref='-41437' role='outer' />
     4150    <tag k='josm_error_codes' v='1610' />
    41354151    <tag k='name' v='Example 7 (02)' />
    41364152    <tag k='type' v='multipolygon' />
     
    41434159    <member type='way' ref='-41777' role='outer' />
    41444160    <tag k='comment' v='For this test the display style depends on the order of ways and is unpredictable' />
    4145     <tag k='josm_error_codes' v='1607' />
     4161    <tag k='josm_error_codes' v='1610' />
    41464162    <tag k='name' v='06/04 - Mismatching way styles' />
    41474163    <tag k='type' v='multipolygon' />
     
    41604176    <member type='way' ref='-41711' role='outer' />
    41614177    <member type='way' ref='-41765' role='outer' />
     4178    <tag k='josm_error_codes' v='1610' />
    41624179    <tag k='name' v='Example 5 (04) inner' />
    41634180    <tag k='type' v='multipolygon' />
     
    41824199    <member type='way' ref='-41493' role='outer' />
    41834200    <member type='way' ref='-41457' role='outer' />
     4201    <tag k='josm_error_codes' v='1610' />
    41844202    <tag k='name' v='Example 4 (04)' />
    41854203    <tag k='type' v='multipolygon' />
     
    42054223    <member type='way' ref='-41505' role='outer' />
    42064224    <member type='way' ref='-41459' role='outer' />
     4225    <tag k='josm_error_codes' v='1610' />
    42074226    <tag k='name' v='Example 8 (02)' />
    42084227    <tag k='type' v='multipolygon' />
     
    42294248    <member type='way' ref='-41515' role='outer' />
    42304249    <member type='way' ref='-41657' role='outer' />
     4250    <tag k='josm_error_codes' v='1610' />
    42314251    <tag k='name' v='Example 3 (04)' />
    42324252    <tag k='type' v='multipolygon' />
     
    42444264    <member type='way' ref='-41597' role='outer' />
    42454265    <member type='way' ref='-41653' role='outer' />
     4266    <tag k='josm_error_codes' v='1610' />
    42464267    <tag k='name' v='Example 8 (04)' />
    42474268    <tag k='type' v='multipolygon' />
  • trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java

    r16333 r16406  
    121121    /**
    122122     * Various style-related checks:<ul>
     123     * <li>{@link #NO_STYLE}: No area style for multipolygon</li>
    123124     * <li>{@link #INNER_STYLE_MISMATCH}: With the currently used mappaint style the style for inner way equals the multipolygon style</li>
    124      * <li>{@link #OUTER_STYLE_MISMATCH}: Style for outer way mismatches</li>
     125     * <li>{@link #OUTER_STYLE_MISMATCH}: With the currently used mappaint style the style for outer way mismatches the area style</li>
    125126     * <li>{@link #OUTER_STYLE}: Area style on outer way</li>
    126127     * </ul>
     
    129130     */
    130131    private void checkStyleConsistency(Relation r, Multipolygon polygon) {
    131         ElemStyles styles = MapPaintStyles.getStyles();
    132         if (styles != null && !r.isBoundary()) {
     132        if (MapPaintStyles.getStyles() != null && !r.isBoundary()) {
    133133            AreaElement area = ElemStyles.getAreaElemStyle(r, false);
    134             boolean areaStyle = area != null;
    135             // If area style was not found for relation then use style of ways
    136134            if (area == null) {
    137                 for (Way w : polygon.getOuterWays()) {
    138                     area = ElemStyles.getAreaElemStyle(w, true);
    139                     if (area != null) {
    140                         break;
    141                     }
    142                 }
    143                 if (area == null) {
    144                     errors.add(TestError.builder(this, Severity.OTHER, NO_STYLE)
    145                             .message(tr("No area style for multipolygon"))
    146                             .primitives(r)
    147                             .build());
    148                 }
    149             }
    150 
    151             if (area != null) {
     135                errors.add(TestError.builder(this, Severity.OTHER, NO_STYLE)
     136                        .message(tr("No area style for multipolygon"))
     137                        .primitives(r)
     138                        .build());
     139            } else {
    152140                for (Way wInner : polygon.getInnerWays()) {
    153                     if (area.equals(ElemStyles.getAreaElemStyle(wInner, false))) {
     141                    if (wInner.isClosed() && area.equals(ElemStyles.getAreaElemStyle(wInner, false))) {
    154142                        errors.add(TestError.builder(this, Severity.OTHER, INNER_STYLE_MISMATCH)
    155143                                .message(tr("With the currently used mappaint style the style for inner way equals the multipolygon style"))
     
    160148                }
    161149                for (Way wOuter : polygon.getOuterWays()) {
     150                    if (!wOuter.isArea())
     151                        continue;
    162152                    AreaElement areaOuter = ElemStyles.getAreaElemStyle(wOuter, false);
    163153                    if (areaOuter != null) {
    164154                        if (!area.equals(areaOuter)) {
    165                             String message = !areaStyle ? tr("Style for outer way mismatches")
    166                                     : tr("With the currently used mappaint style the style for outer way mismatches the area style");
    167155                            errors.add(TestError.builder(this, Severity.OTHER, OUTER_STYLE_MISMATCH)
    168                                     .message(message)
     156                                    .message(tr("With the currently used mappaint style the style for outer way mismatches the area style"))
    169157                                    .primitives(Arrays.asList(r, wOuter))
    170158                                    .highlight(wOuter)
    171159                                    .build());
    172                         } else if (areaStyle) { /* style on outer way of multipolygon, but equal to polygon */
     160                        } else { /* style on outer way of multipolygon, but equal to polygon */
    173161                            errors.add(TestError.builder(this, Severity.WARNING, OUTER_STYLE)
    174162                                    .message(tr("Area style on outer way"))
  • trunk/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java

    r16332 r16406  
    3939import org.openstreetmap.josm.data.osm.AbstractPrimitive;
    4040import org.openstreetmap.josm.data.osm.OsmPrimitive;
     41import org.openstreetmap.josm.data.osm.OsmUtils;
     42import org.openstreetmap.josm.data.osm.Relation;
    4143import org.openstreetmap.josm.data.osm.Tag;
    4244import org.openstreetmap.josm.data.osm.TagMap;
     
    189191    protected static final int UNUSUAL_UNICODE_CHAR_VALUE = 1216;
    190192    protected static final int INVALID_PRESETS_TYPE     = 1217;
     193    protected static final int MULTIPOLYGON_NO_AREA     = 1218;
     194    protected static final int MULTIPOLYGON_INCOMPLETE  = 1219;
     195    protected static final int MULTIPOLYGON_MAYBE_NO_AREA = 1220;
    191196    // CHECKSTYLE.ON: SingleSpaceSeparator
    192197
     
    623628        }
    624629
     630        if (p instanceof Relation && p.hasTag("type", "multipolygon")) {
     631            checkMultipolygonTags(p);
     632        }
     633
    625634        if (checkPresetsTypes) {
    626635            TagMap tags = p.getKeys();
     
    658667            }
    659668        }
     669    }
     670
     671    private static final Collection<String> NO_AREA_KEYS = Arrays.asList("name", "area", "ref", "access", "operator");
     672
     673    private void checkMultipolygonTags(OsmPrimitive p) {
     674        if (p.isAnnotated() || hasAcceptedPrimaryTagForMultipolygon(p))
     675            return;
     676        if (p.keySet().stream().anyMatch(k -> k.matches("^(abandoned|construction|demolished|disused|planned|razed|removed|was).*")))
     677            return;
     678
     679        TestError.Builder builder = null;
     680        if (p.hasKey("surface")) {
     681            // accept often used tag surface=* as area tag
     682            builder = TestError.builder(this, Severity.OTHER, MULTIPOLYGON_INCOMPLETE)
     683                    .message(tr("Multipolygon tags"), marktr("only {0} tag"), "surface");
     684        } else {
     685            Map<String, String> filteredTags = p.getInterestingTags();
     686            filteredTags.remove("type");
     687            NO_AREA_KEYS.forEach(filteredTags::remove);
     688            filteredTags.keySet().removeIf(key -> !key.matches("[a-z0-9:_]+"));
     689
     690            if (filteredTags.isEmpty()) {
     691                builder = TestError.builder(this, Severity.ERROR, MULTIPOLYGON_NO_AREA)
     692                        .message(tr("Multipolygon tags"), marktr("tag describing the area is missing"), new Object());
     693
     694            }
     695        }
     696        if (builder == null) {
     697            // multipolygon has either no area tag or a rarely used one
     698            builder = TestError.builder(this, Severity.WARNING, MULTIPOLYGON_MAYBE_NO_AREA)
     699                    .message(tr("Multipolygon tags"), marktr("tag describing the area might be missing"), new Object());
     700        }
     701        errors.add(builder.primitives(p).build());
     702    }
     703
     704    /**
     705     * Check if a multipolygon has a main tag that describes the type of area. Accepts also some deprecated tags and typos.
     706     * @param p the multipolygon
     707     * @return true if the multipolygon has a main tag that (likely) describes the type of area.
     708     */
     709    private static boolean hasAcceptedPrimaryTagForMultipolygon(OsmPrimitive p) {
     710        if (p.hasKey("landuse", "amenity", "building", "building:part", "area:highway", "shop", "place", "boundary",
     711                "landform", "piste:type", "sport", "golf", "landcover", "aeroway", "office", "healthcare", "craft", "room")
     712                || p.hasTagDifferent("natural", "tree", "peek", "saddle", "tree_row")
     713                || p.hasTagDifferent("man_made", "survey_point", "mast", "flagpole", "manhole", "watertap")
     714                || p.hasTagDifferent("highway", "crossing", "bus_stop", "turning_circle", "street_lamp",
     715                        "traffic_signals", "stop", "milestone", "mini_roundabout", "motorway_junction", "passing_place",
     716                        "speed_camera", "traffic_mirror", "trailhead", "turning_circle", "turning_loop", "toll_gantry")
     717                || p.hasTagDifferent("tourism", "attraction", "artwork")
     718                || p.hasTagDifferent("leisure", "picnic_table", "slipway", "firepit")
     719                || p.hasTagDifferent("historic", "wayside_cross", "milestone"))
     720            return true;
     721        if (p.hasTag("barrier", "hedge", "retaining_wall")
     722                || p.hasTag("public_transport", "platform", "station")
     723                || p.hasTag("railway", "platform")
     724                || p.hasTag("waterway", "riverbank", "dam", "rapids", "dock", "boatyard", "fuel")
     725                || p.hasTag("indoor", "corridor", "room", "area")
     726                || p.hasTag("power", "substation", "generator", "plant", "switchgear", "converter", "sub_station")
     727                || p.hasTag("seamark:type", "harbour", "fairway", "anchorage", "landmark", "berth", "harbour_basin",
     728                        "separation_zone")
     729                || (p.get("seamark:type") != null && p.get("seamark:type").matches(".*\\_(area|zone)$")))
     730            return true;
     731        return p.hasTag("harbour", OsmUtils.TRUE_VALUE)
     732                || p.hasTag("flood_prone", OsmUtils.TRUE_VALUE)
     733                || p.hasTag("bridge", OsmUtils.TRUE_VALUE)
     734                || p.hasTag("ruins", OsmUtils.TRUE_VALUE)
     735                || p.hasTag("junction", OsmUtils.TRUE_VALUE);
    660736    }
    661737
Note: See TracChangeset for help on using the changeset viewer.