Ignore:
Timestamp:
2013-11-18T02:20:41+01:00 (10 years ago)
Author:
Don-vip
Message:

fix #9318 - validator: avoids redundant checks between UnclosedWays and MultipolygonTest

File:
1 edited

Legend:

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

    r6386 r6390  
    77import java.text.MessageFormat;
    88import java.util.Arrays;
     9import java.util.Collections;
     10import java.util.HashSet;
     11import java.util.List;
     12import java.util.Set;
    913
    1014import org.openstreetmap.josm.data.osm.OsmPrimitive;
     
    2024 *
    2125 * @author stoecker
     26 * @since 3669
    2227 */
    2328public class UnclosedWays extends Test {
    2429
    2530    /**
    26      * Constructor
     31     * Constructs a new {@code UnclosedWays} test.
    2732     */
    2833    public UnclosedWays() {
     
    3035    }
    3136
    32     private String type;
    33     private String etype;
    34     private int mode;
    35 
    36     public void set(int m, String text, String desc) {
    37         etype = MessageFormat.format(text, desc);
    38         type = tr(text, tr(desc));
    39         mode = m;
     37    /**
     38     * A check performed by UnclosedWays test.
     39     * @since 6390
     40     */
     41    private class UnclosedWaysCheck {
     42        /** The unique numeric code for this check */
     43        public final int code;
     44        /** The OSM key checked */
     45        public final String key;
     46        /** The English message */
     47        private final String engMessage;
     48        /** The special values, to be ignored if ignore is set to true; to be considered only if ignore is set to false */
     49        private final List<String> specialValues;
     50        /** The boolean indicating if special values must be ignored or considered only */
     51        private final boolean ignore;
     52       
     53        /**
     54         * Constructs a new {@code UnclosedWaysCheck}.
     55         * @param code The unique numeric code for this check
     56         * @param key The OSM key checked
     57         * @param engMessage The English message
     58         */
     59        @SuppressWarnings("unchecked")
     60        public UnclosedWaysCheck(int code, String key, String engMessage) {
     61            this(code, key, engMessage, (List<String>) Collections.EMPTY_LIST);
     62        }
     63       
     64        /**
     65         * Constructs a new {@code UnclosedWaysCheck}.
     66         * @param code The unique numeric code for this check
     67         * @param key The OSM key checked
     68         * @param engMessage The English message
     69         * @param ignoredValues The ignored values.
     70         */
     71        public UnclosedWaysCheck(int code, String key, String engMessage, List<String> ignoredValues) {
     72            this(code, key, engMessage, ignoredValues, true);
     73        }
     74       
     75        /**
     76         * Constructs a new {@code UnclosedWaysCheck}.
     77         * @param code The unique numeric code for this check
     78         * @param key The OSM key checked
     79         * @param engMessage The English message
     80         * @param specialValues The special values, to be ignored if ignore is set to true; to be considered only if ignore is set to false
     81         * @param ignore indicates if special values must be ignored or considered only
     82         */
     83        public UnclosedWaysCheck(int code, String key, String engMessage, List<String> specialValues, boolean ignore) {
     84            this.code = code;
     85            this.key = key;
     86            this.engMessage = engMessage;
     87            this.specialValues = specialValues;
     88            this.ignore = ignore;
     89        }
     90       
     91        /**
     92         * Returns the test error of the given way, if any.
     93         * @param w The way to check
     94         * @return The test error if the way is erroneous, {@code null} otherwise
     95         */
     96        public final TestError getTestError(Way w) {
     97            String value = w.get(key);
     98            if (isValueErroneous(value)) {
     99                String  type = engMessage.contains("{0}") ? tr(engMessage, tr(value)) : tr(engMessage);
     100                String etype = engMessage.contains("{0}") ? MessageFormat.format(engMessage, value) : engMessage;
     101                return new TestError(UnclosedWays.this, Severity.WARNING, tr("Unclosed way"),
     102                        type, etype, code, Arrays.asList(w),
     103                        // The important parts of an unclosed way are the first and
     104                        // the last node which should be connected, therefore we highlight them
     105                        Arrays.asList(w.firstNode(), w.lastNode()));
     106            }
     107            return null;
     108        }
     109       
     110        protected boolean isValueErroneous(String value) {
     111            return value != null && ignore != specialValues.contains(value);
     112        }
    40113    }
    41114
    42     public void set(int m, String text) {
    43         etype = text;
    44         type = tr(text);
    45         mode = m;
     115    /**
     116     * A check performed by UnclosedWays test where the key is treated as boolean.
     117     * @since 6390
     118     */
     119    private final class UnclosedWaysBooleanCheck extends UnclosedWaysCheck {
     120
     121        /**
     122         * Constructs a new {@code UnclosedWaysBooleanCheck}.
     123         * @param code The unique numeric code for this check
     124         * @param key The OSM key checked
     125         * @param engMessage The English message
     126         */
     127        public UnclosedWaysBooleanCheck(int code, String key, String engMessage) {
     128            super(code, key, engMessage);
     129        }
     130
     131        @Override
     132        protected boolean isValueErroneous(String value) {
     133            Boolean btest = OsmUtils.getOsmBoolean(value);
     134            // Not a strict boolean comparison to handle building=house like a building=yes
     135            return (btest != null && btest) || (btest == null && value != null);
     136        }
     137    }
     138
     139    private final UnclosedWaysCheck[] checks = {
     140        new UnclosedWaysCheck(1101, "natural",   marktr("natural type {0}"), Arrays.asList("coastline", "cliff", "tree_row")),
     141        new UnclosedWaysCheck(1102, "landuse",   marktr("landuse type {0}")),
     142        new UnclosedWaysCheck(1103, "amenities", marktr("amenities type {0}")),
     143        new UnclosedWaysCheck(1104, "sport",     marktr("sport type {0}"), Arrays.asList("water_slide", "climbing")),
     144        new UnclosedWaysCheck(1105, "tourism",   marktr("tourism type {0}")),
     145        new UnclosedWaysCheck(1106, "shop",      marktr("shop type {0}")),
     146        new UnclosedWaysCheck(1107, "leisure",   marktr("leisure type {0}"), Arrays.asList("track")),
     147        new UnclosedWaysCheck(1108, "waterway",  marktr("waterway type {0}"), Arrays.asList("riverbank"), false),
     148        new UnclosedWaysBooleanCheck(1120, "building", marktr("building")),
     149        new UnclosedWaysBooleanCheck(1130, "area",     marktr("area")),
     150    };
     151   
     152    /**
     153     * Returns the set of checked OSM keys.
     154     * @return The set of checked OSM keys.
     155     * @since 6390
     156     */
     157    public Set<String> getCheckedKeys() {
     158        Set<String> keys = new HashSet<String>();
     159        for (UnclosedWaysCheck c : checks) {
     160            keys.add(c.key);
     161        }
     162        return keys;
    46163    }
    47164
    48165    @Override
    49166    public void visit(Way w) {
    50         String test;
    51         type = etype = null;
    52         mode = 0;
    53167
    54         if (!w.isUsable())
     168        if (!w.isUsable() || w.isArea())
    55169            return;
    56170
    57         test = w.get("natural");
    58         if (test != null && !"coastline".equals(test) && !"cliff".equals(test) && !"tree_row".equals(test)) {
    59             set(1101, marktr("natural type {0}"), test);
    60         }
    61         test = w.get("landuse");
    62         if (test != null) {
    63             set(1102, marktr("landuse type {0}"), test);
    64         }
    65         test = w.get("amenities");
    66         if (test != null) {
    67             set(1103, marktr("amenities type {0}"), test);
    68         }
    69         test = w.get("sport");
    70         if (test != null && !test.equals("water_slide") && !test.equals("climbing")) {
    71             set(1104, marktr("sport type {0}"), test);
    72         }
    73         test = w.get("tourism");
    74         if (test != null) {
    75             set(1105, marktr("tourism type {0}"), test);
    76         }
    77         test = w.get("shop");
    78         if (test != null) {
    79             set(1106, marktr("shop type {0}"), test);
    80         }
    81         test = w.get("leisure");
    82         if (test != null && !"track".contains(test)) {
    83             set(1107, marktr("leisure type {0}"), test);
    84         }
    85         test = w.get("waterway");
    86         if ("riverbank".equals(test)) {
    87             set(1108, marktr("waterway type {0}"), test);
    88         }
    89         Boolean btest = OsmUtils.getOsmBoolean(w.get("building"));
    90         if (btest != null && btest) {
    91             set(1120, marktr("building"));
    92         }
    93         btest = OsmUtils.getOsmBoolean(w.get("area"));
    94         if (btest != null && btest) {
    95             set(1130, marktr("area"));
     171        for (OsmPrimitive parent: w.getReferrers()) {
     172            if (parent instanceof Relation && ((Relation)parent).isMultipolygon())
     173                return;
    96174        }
    97175
    98         if (type != null && !w.isArea()) {
    99             for (OsmPrimitive parent: w.getReferrers()) {
    100                 if (parent instanceof Relation && ((Relation)parent).isMultipolygon())
    101                     return;
     176        for (UnclosedWaysCheck c : checks) {
     177            TestError error = c.getTestError(w);
     178            if (error != null) {
     179                errors.add(error);
     180                return;
    102181            }
    103 
    104             errors.add(new TestError(this, Severity.WARNING, tr("Unclosed way"),
    105                     type, etype, mode,
    106                     Arrays.asList(w),
    107                     // The important parts of an unclosed way are the first and
    108                     // the last node which should be connected, therefore we highlight them
    109                     Arrays.asList(w.firstNode(), w.lastNode())));
    110182        }
    111183    }
Note: See TracChangeset for help on using the changeset viewer.