Ticket #2746: 2746.patch

File 2746.patch, 14.4 KB (added by simon04, 5 months 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}