Ticket #2746: 2746.patch

File 2746.patch, 14.4 KB (added by simon04, 14 years ago)
  • src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java

    diff --git a/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java b/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java
    index 2b7115b..189c1ee 100644
    a b package org.openstreetmap.josm.data.osm;  
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    66import java.text.MessageFormat;
     7import java.util.Arrays;
    78import java.util.Collection;
    89import java.util.Collections;
    910import java.util.Date;
    public abstract class AbstractPrimitive implements IPrimitive {  
    692693        return getName();
    693694    }
    694695
     696    /**
     697     * Tests whether this primitive contains a tag consisting of {@code key} and any of {@code values}.
     698     * @param key the key forming the tag.
     699     * @param values one or many values forming the tag.
     700     * @return true iff primitive contains a tag consisting of {@code key} and any of {@code values}.
     701     */
     702    public boolean hasTag(String key, String... values) {
     703        return hasTag(key, Arrays.asList(values));
     704    }
     705
     706    /**
     707     * Tests whether this primitive contains a tag consisting of {@code key} and any of {@code values}.
     708     * @param key the key forming the tag.
     709     * @param values one or many values forming the tag.
     710     * @return true iff primitive contains a tag consisting of {@code key} and any of {@code values}.
     711     */
     712    public boolean hasTag(String key, Collection<String> values) {
     713        return values.contains(get(key));
     714    }
    695715}
  • src/org/openstreetmap/josm/data/osm/Way.java

    diff --git a/src/org/openstreetmap/josm/data/osm/Way.java b/src/org/openstreetmap/josm/data/osm/Way.java
    index 8336bc4..3ccab04 100644
    a b public final class Way extends OsmPrimitive implements IWay {  
    113113        return nodes[index];
    114114    }
    115115
     116    /**
     117     * Returns the first node of this way.
     118     * The result equals {@link #getNode getNode}{@code (0)}.
     119     * @return the first node of this way
     120     */
     121    public Node getFirstNode() {
     122        return nodes[0];
     123    }
     124
     125        /**
     126     * Returns the last node of this way.
     127     * The result equals <tt>{@link #getNode getNode}({@link #getNodesCount getNodesCount} - 1)</tt>.
     128     * @return the last node of this way
     129     */
     130    public Node getLastNode() {
     131        return nodes[nodes.length - 1];
     132    }
     133
    116134    @Override
    117135    public long getNodeId(int idx) {
    118136        return nodes[idx].getUniqueId();
  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

    diff --git a/src/org/openstreetmap/josm/data/validation/OsmValidator.java b/src/org/openstreetmap/josm/data/validation/OsmValidator.java
    index c8d54ee..351ba70 100644
    a b import org.openstreetmap.josm.data.validation.tests.UnclosedWays;  
    4747import org.openstreetmap.josm.data.validation.tests.UnconnectedWays;
    4848import org.openstreetmap.josm.data.validation.tests.UntaggedNode;
    4949import org.openstreetmap.josm.data.validation.tests.UntaggedWay;
     50import org.openstreetmap.josm.data.validation.tests.WayConnectedToArea;
    5051import org.openstreetmap.josm.data.validation.tests.WronglyOrderedWays;
    5152import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
    5253import org.openstreetmap.josm.gui.layer.Layer;
    public class OsmValidator implements LayerChangeListener {  
    101102        BuildingInBuilding.class, // ID 2001 .. 2099
    102103        DeprecatedTags.class, // ID 2101 .. 2199
    103104        OverlappingAreas.class, // ID 2201 .. 2299
     105        WayConnectedToArea.class, // ID 2301 .. 2399
    104106    };
    105107
    106108    public OsmValidator() {
  • src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java

    diff --git a/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java b/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
    index 805d75b..22a945e 100644
    a b import org.openstreetmap.josm.data.validation.Severity;  
    2525import org.openstreetmap.josm.data.validation.Test;
    2626import org.openstreetmap.josm.data.validation.TestError;
    2727import org.openstreetmap.josm.gui.mappaint.AreaElemStyle;
    28 import org.openstreetmap.josm.gui.mappaint.ElemStyle;
    2928import org.openstreetmap.josm.gui.mappaint.ElemStyles;
    3029import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
    3130
    public class MultipolygonTest extends Test {  
    116115
    117116    @Override
    118117    public void visit(Way w) {
    119         if (styles != null && !w.isClosed()) {
    120             for (ElemStyle s : styles.generateStyles(w, SCALE, null, false).a) {
    121                 if (s instanceof AreaElemStyle) {
    122                     List<Node> nodes = w.getNodes();
    123                     errors.add(new TestError(this, Severity.WARNING, tr("Area style way is not closed"), NOT_CLOSED,
    124                             Collections.singletonList(w), Arrays.asList(nodes.get(0), nodes.get(nodes.size() - 1))));
    125                     break;
    126                 }
    127             }
     118        if (!w.isClosed() && ElemStyles.hasAreaElemStyle(w, false)) {
     119            List<Node> nodes = w.getNodes();
     120            errors.add(new TestError(this, Severity.WARNING, tr("Area style way is not closed"), NOT_CLOSED,
     121                    Collections.singletonList(w), Arrays.asList(nodes.get(0), nodes.get(nodes.size() - 1))));
    128122        }
    129123    }
    130124
    public class MultipolygonTest extends Test {  
    156150            List<List<Node>> outerWays = joinWays(polygon.getOuterWays());
    157151            if (styles != null) {
    158152
    159                 AreaElemStyle area = null;
    160                 boolean areaStyle = false;
    161                 for (ElemStyle s : styles.generateStyles(r, SCALE, null, false).a) {
    162                     if (s instanceof AreaElemStyle) {
    163                         area = (AreaElemStyle) s;
    164                         areaStyle = true;
    165                         break;
    166                     }
    167                 }
     153                AreaElemStyle area = ElemStyles.getAreaElemStyle(r, false);
     154                boolean areaStyle = area != null;
    168155                // If area style was not found for relation then use style of ways
    169156                if (area == null) {
    170157                    for (Way w : polygon.getOuterWays()) {
    171 
    172                         for (ElemStyle s : styles.generateStyles(w, SCALE, null, true).a) {
    173                             if (s instanceof AreaElemStyle) {
    174                                 area = (AreaElemStyle) s;
    175                                 break;
    176                             }
    177                         }
     158                        area = ElemStyles.getAreaElemStyle(w, true);
    178159                        if (area != null) {
    179160                            break;
    180161                        }
    public class MultipolygonTest extends Test {  
    188169
    189170                if (area != null) {
    190171                    for (Way wInner : polygon.getInnerWays()) {
    191                         AreaElemStyle areaInner = null;
    192                         for (ElemStyle s : styles.generateStyles(wInner, SCALE, null, false).a) {
    193                             if (s instanceof AreaElemStyle) {
    194                                 areaInner = (AreaElemStyle) s;
    195                                 break;
    196                             }
    197                         }
     172                        AreaElemStyle areaInner = ElemStyles.getAreaElemStyle(wInner, false);
    198173
    199174                        if (areaInner != null && area.equals(areaInner)) {
    200175                            List<OsmPrimitive> l = new ArrayList<OsmPrimitive>();
    public class MultipolygonTest extends Test {  
    206181                    }
    207182                    if(!areaStyle) {
    208183                        for (Way wOuter : polygon.getOuterWays()) {
    209                             AreaElemStyle areaOuter = null;
    210                             for (ElemStyle s : styles.generateStyles(wOuter, SCALE, null, false).a) {
    211                                 if (s instanceof AreaElemStyle) {
    212                                     areaOuter = (AreaElemStyle) s;
    213                                     break;
    214                                 }
    215                             }
     184                            AreaElemStyle areaOuter = ElemStyles.getAreaElemStyle(wOuter, false);
    216185                            if (areaOuter != null && !area.equals(areaOuter)) {
    217186                                List<OsmPrimitive> l = new ArrayList<OsmPrimitive>();
    218187                                l.add(r);
  • src/org/openstreetmap/josm/data/validation/tests/OverlappingAreas.java

    diff --git a/src/org/openstreetmap/josm/data/validation/tests/OverlappingAreas.java b/src/org/openstreetmap/josm/data/validation/tests/OverlappingAreas.java
    index 2f928cc..dabc64f 100644
    a b import static org.openstreetmap.josm.tools.I18n.tr;  
    44
    55import java.util.Collection;
    66import java.util.Collections;
    7 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    87import org.openstreetmap.josm.data.osm.QuadBuckets;
    98import org.openstreetmap.josm.data.osm.Way;
    109import org.openstreetmap.josm.data.validation.Severity;
    1110import org.openstreetmap.josm.data.validation.Test;
    1211import org.openstreetmap.josm.data.validation.TestError;
    13 import org.openstreetmap.josm.gui.mappaint.AreaElemStyle;
    14 import org.openstreetmap.josm.gui.mappaint.ElemStyle;
    1512import org.openstreetmap.josm.gui.mappaint.ElemStyles;
    16 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
    1713import org.openstreetmap.josm.tools.Geometry;
    1814import org.openstreetmap.josm.tools.Predicate;
    1915import org.openstreetmap.josm.tools.Utils;
    public class OverlappingAreas extends Test {  
    2218
    2319    protected static int OVERLAPPING_AREAS = 2201;
    2420    protected QuadBuckets<Way> index = new QuadBuckets<Way>();
    25     private static ElemStyles styles = MapPaintStyles.getStyles();
    2621
    2722    public OverlappingAreas() {
    2823        super(tr("Overlapping Areas"));
    public class OverlappingAreas extends Test {  
    3025
    3126    @Override
    3227    public void visit(Way w) {
    33         if (w.isUsable() && w.isClosed() && hasAreaElemStyle(w)) {
     28        if (w.isUsable() && w.isClosed() && ElemStyles.hasAreaElemStyle(w, false)) {
    3429            index.add(w);
    3530        }
    3631    }
    public class OverlappingAreas extends Test {  
    5954        }
    6055    }
    6156
    62     private boolean hasAreaElemStyle(OsmPrimitive p) {
    63         for (ElemStyle s : styles.generateStyles(p, 1.0, null, false).a) {
    64             if (s instanceof AreaElemStyle) {
    65                 return true;
    66             }
    67         }
    68         return false;
    69     }
    7057}
  • new file src/org/openstreetmap/josm/data/validation/tests/WayConnectedToArea.java

    diff --git a/src/org/openstreetmap/josm/data/validation/tests/WayConnectedToArea.java b/src/org/openstreetmap/josm/data/validation/tests/WayConnectedToArea.java
    new file mode 100644
    index 0000000..c3a55b0
    - +  
     1package org.openstreetmap.josm.data.validation.tests;
     2
     3import static org.openstreetmap.josm.tools.I18n.tr;
     4
     5import java.util.Arrays;
     6import org.openstreetmap.josm.data.osm.Node;
     7import org.openstreetmap.josm.data.osm.OsmPrimitive;
     8import org.openstreetmap.josm.data.osm.Relation;
     9import org.openstreetmap.josm.data.osm.Way;
     10import org.openstreetmap.josm.data.validation.Severity;
     11import org.openstreetmap.josm.data.validation.Test;
     12import org.openstreetmap.josm.data.validation.TestError;
     13import org.openstreetmap.josm.gui.mappaint.ElemStyles;
     14
     15public class WayConnectedToArea extends Test {
     16
     17    public WayConnectedToArea() {
     18        super(tr("Way connected to Area"));
     19    }
     20
     21    @Override
     22    public void visit(Way w) {
     23        if (!w.isUsable() || w.isClosed() || !w.hasKey("highway")) {
     24            return;
     25        }
     26
     27        for (OsmPrimitive p : w.getFirstNode().getReferrers()) {
     28            testForError(w, w.getFirstNode(), p);
     29        }
     30        for (OsmPrimitive p : w.getLastNode().getReferrers()) {
     31            testForError(w, w.getLastNode(), p);
     32        }
     33
     34    }
     35
     36    private void testForError(Way w, Node wayNode, OsmPrimitive p) {
     37        if (ElemStyles.hasAreaElemStyle(p, false)) {
     38            addError(w, wayNode, p);
     39        } else {
     40            for (OsmPrimitive r : p.getReferrers()) {
     41                if (r instanceof Relation
     42                        && r.hasTag("type", "multipolygon")
     43                        && ElemStyles.hasAreaElemStyle(r, false)) {
     44                    addError(w, wayNode, p);
     45                    break;
     46                }
     47            }
     48        }
     49    }
     50
     51    private void addError(Way w, Node wayNode, OsmPrimitive p) {
     52        errors.add(new TestError(this, Severity.WARNING,
     53                tr("Way terminates on Area"), 2301,
     54                Arrays.asList(w, p),
     55                Arrays.asList(wayNode)));
     56    }
     57}
  • src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java

    diff --git a/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java b/src/org/openstreetmap/josm/gui/mappaint/ElemStyles.java
    index 95be73b..54d4eb7 100644
    a b public class ElemStyles {  
    409409        styleSources.clear();
    410410        styleSources.addAll(sources);
    411411    }
     412
     413    /**
     414     * Returns the first AreaElemStyle for a given primitive.
     415     * @param p the OSM primitive
     416     * @param pretendWayIsClosed For styles that require the way to be closed,
     417     * we pretend it is. This is useful for generating area styles from the (segmented)
     418     * outer ways of a multipolygon.
     419     * @return first AreaElemStyle found or {@code null}.
     420     */
     421    public static AreaElemStyle getAreaElemStyle(OsmPrimitive p, boolean pretendWayIsClosed) {
     422        if (MapPaintStyles.getStyles() == null) {
     423            return null;
     424        }
     425        for (ElemStyle s : MapPaintStyles.getStyles().generateStyles(p, 1.0, null, pretendWayIsClosed).a) {
     426            if (s instanceof AreaElemStyle) {
     427                return (AreaElemStyle) s;
     428            }
     429        }
     430        return null;
     431    }
     432
     433    /**
     434     * Determines whether primitive has an AreaElemStyle.
     435     * @param p the OSM primitive
     436     * @param pretendWayIsClosed For styles that require the way to be closed,
     437     * we pretend it is. This is useful for generating area styles from the (segmented)
     438     * outer ways of a multipolygon.
     439     * @return {@code true} iff primitive has an AreaElemStyle
     440     */
     441    public static boolean hasAreaElemStyle(OsmPrimitive p, boolean pretendWayIsClosed) {
     442        return getAreaElemStyle(p, pretendWayIsClosed) != null;
     443    }
    412444}