Ticket #20019: 20019.patch

File 20019.patch, 4.5 KB (added by GerdP, 4 months ago)

alpha version, please suggest improvements regarding the i18n strings

  • src/org/openstreetmap/josm/data/validation/OsmValidator.java

     
    4444import org.openstreetmap.josm.data.validation.tests.ConditionalKeys;
    4545import org.openstreetmap.josm.data.validation.tests.ConnectivityRelations;
    4646import org.openstreetmap.josm.data.validation.tests.CrossingWays;
     47import org.openstreetmap.josm.data.validation.tests.DirectionNodes;
    4748import org.openstreetmap.josm.data.validation.tests.DuplicateNode;
    4849import org.openstreetmap.josm.data.validation.tests.DuplicateRelation;
    4950import org.openstreetmap.josm.data.validation.tests.DuplicateWay;
     
    151152        RightAngleBuildingTest.class, // 3700 .. 3799
    152153        SharpAngles.class, // 3800 .. 3899
    153154        ConnectivityRelations.class, // 3900 .. 3999
     155        DirectionNodes.class, // 4000-4099
    154156    };
    155157
    156158    /**
  • src/org/openstreetmap/josm/data/validation/tests/DirectionNodes.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.data.validation.tests;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.util.ArrayList;
     7import java.util.List;
     8import java.util.Map.Entry;
     9import java.util.regex.Pattern;
     10
     11import org.openstreetmap.josm.data.osm.Node;
     12import org.openstreetmap.josm.data.osm.OsmPrimitive;
     13import org.openstreetmap.josm.data.osm.Way;
     14import org.openstreetmap.josm.data.validation.Severity;
     15import org.openstreetmap.josm.data.validation.Test;
     16import org.openstreetmap.josm.data.validation.TestError;
     17
     18/**
     19 * Find nodes with direction tag and invalid number of parent ways or position in way. See #20019.
     20 * @author Gerd Petermann
     21 * @since xxx
     22 */
     23public class DirectionNodes extends Test {
     24    private static final int MULLTIPLE_WAYS_CODE = 4000;
     25    private static final int END_NODE_CODE = 4001;
     26    private static final int NO_WAY_CODE = 4002;
     27
     28    private static final Pattern KEY_PATTERN = Pattern.compile(".*[:]?direction");
     29
     30    /**
     31     * Construct a new {@code DirectionNodes} object
     32     */
     33    public DirectionNodes() {
     34        super(tr("Direction nodes"), tr("Check for nodes which have a direction"));
     35    }
     36
     37    @Override
     38    public void visit(Node n) {
     39        if (!n.isUsable() || !n.isTagged())
     40            return;
     41        for (Entry<String, String> entry : n.getKeys().entrySet()) {
     42            if (("forward".equals(entry.getValue()) || "backward".equals(entry.getValue()))
     43                    && KEY_PATTERN.matcher(entry.getKey()).matches()) {
     44                checkParents(n, entry.getKey());
     45            }
     46        }
     47    }
     48
     49    private void checkParents(Node n, String key) {
     50        final List<Way> ways = new ArrayList<>();
     51        boolean hasWays = false;
     52        for (Way w : n.getParentWays()) {
     53            if (w.hasKey("highway", "railway", "waterway")) {
     54                ways.add(w);
     55            }
     56            hasWays = true;
     57        }
     58
     59        if (ways.isEmpty() && !n.isOutsideDownloadArea() && n.getDataSet().getDataSourceArea() != null) {
     60            if (!hasWays) {
     61                errors.add(TestError.builder(this, Severity.WARNING, NO_WAY_CODE)
     62                        .primitives(n)
     63                        .message(tr("Unconnected node with {0}", key)).build());
     64            }
     65        } else if (ways.size() == 1) {
     66            Way w = ways.get(0);
     67            if (w.firstNode() == n || w.lastNode() == n) {
     68                errors.add(TestError.builder(this, Severity.WARNING, END_NODE_CODE)
     69                        .primitives(n, w)
     70                        .highlight(n)
     71                        .message(tr("Node with {0} on end of way", key)).build());
     72            }
     73        } else if (ways.size() > 1) {
     74            List<OsmPrimitive> primitives = new ArrayList<>();
     75            primitives.add(n);
     76            primitives.addAll(ways);
     77            errors.add(TestError.builder(this, Severity.WARNING, MULLTIPLE_WAYS_CODE)
     78                    .primitives(primitives)
     79                    .highlight(n)
     80                    .message(tr("Node with {0} on a connection of multiple ways", key)).build());
     81        }
     82    }
     83}