Changeset 6390 in josm for trunk/src/org


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

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

Location:
trunk/src/org/openstreetmap/josm
Files:
3 edited

Legend:

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

    r6386 r6390  
    99import java.util.Collection;
    1010import java.util.Collections;
     11import java.util.HashSet;
    1112import java.util.LinkedList;
    1213import java.util.List;
     14import java.util.Set;
    1315
    1416import org.openstreetmap.josm.Main;
     
    2224import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.PolyData.Intersection;
    2325import org.openstreetmap.josm.data.osm.visitor.paint.relations.MultipolygonCache;
     26import org.openstreetmap.josm.data.validation.OsmValidator;
    2427import org.openstreetmap.josm.data.validation.Severity;
    2528import org.openstreetmap.josm.data.validation.Test;
     
    2831import org.openstreetmap.josm.gui.mappaint.ElemStyles;
    2932import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
     33import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    3034
    3135/**
     
    5054
    5155    private final List<List<Node>> nonClosedWays = new ArrayList<List<Node>>();
     56    private final Set<String> keysCheckedByAnotherTest = new HashSet<String>();
    5257
    5358    /**
     
    6267    public void initialize() {
    6368        styles = MapPaintStyles.getStyles();
     69    }
     70   
     71    @Override
     72    public void startTest(ProgressMonitor progressMonitor) {
     73        super.startTest(progressMonitor);
     74        keysCheckedByAnotherTest.clear();
     75        for (Test t : OsmValidator.getEnabledTests(false)) {
     76            if (t instanceof UnclosedWays) {
     77                keysCheckedByAnotherTest.addAll(((UnclosedWays)t).getCheckedKeys());
     78                break;
     79            }
     80        }
    6481    }
    6582
     
    124141            List<Node> nodes = w.getNodes();
    125142            if (nodes.size()<1) return; // fix zero nodes bug
    126             // Fix #9291 - Do not raise warning for sport=climbing + natural=cliff
    127             if (!(w.hasTag("sport", "climbing") && w.hasTag("natural", "cliff"))) {
    128                 errors.add(new TestError(this, Severity.WARNING, tr("Area style way is not closed"), NOT_CLOSED,
    129                         Collections.singletonList(w), Arrays.asList(nodes.get(0), nodes.get(nodes.size() - 1))));
    130             }
     143            for (String key : keysCheckedByAnotherTest) {
     144                if (w.hasKey(key)) {
     145                    return;
     146                }
     147            }
     148            errors.add(new TestError(this, Severity.WARNING, tr("Area style way is not closed"), NOT_CLOSED,
     149                    Collections.singletonList(w), Arrays.asList(nodes.get(0), nodes.get(nodes.size() - 1))));
    131150        }
    132151    }
  • 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    }
  • trunk/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java

    r6235 r6390  
    450450     * we pretend it is. This is useful for generating area styles from the (segmented)
    451451     * outer ways of a multipolygon.
    452      * @return {@code true} iff primitive has an AreaElemStyle
     452     * @return {@code true} if primitive has an AreaElemStyle
    453453     */
    454454    public static boolean hasAreaElemStyle(OsmPrimitive p, boolean pretendWayIsClosed) {
Note: See TracChangeset for help on using the changeset viewer.