Ticket #14708: patch-14708.patch

File patch-14708.patch, 4.4 KB (added by michael2402, 9 years ago)
  • src/org/openstreetmap/josm/data/validation/tests/LongSegment.java

     
    44import static org.openstreetmap.josm.tools.I18n.marktr;
    55import static org.openstreetmap.josm.tools.I18n.tr;
    66
     7import java.util.Collections;
     8import java.util.HashSet;
     9import java.util.Set;
     10
    711import org.openstreetmap.josm.Main;
     12import org.openstreetmap.josm.data.coor.LatLon;
     13import org.openstreetmap.josm.data.osm.Node;
    814import org.openstreetmap.josm.data.osm.OsmPrimitive;
    915import org.openstreetmap.josm.data.osm.Way;
     16import org.openstreetmap.josm.data.osm.WaySegment;
    1017import org.openstreetmap.josm.data.validation.Severity;
    1118import org.openstreetmap.josm.data.validation.Test;
    1219import org.openstreetmap.josm.data.validation.TestError;
     
    2431    /** Maximum segment length for this test */
    2532    protected int maxlength;
    2633
     34    protected Set<WaySegment> reported;
     35
    2736    /**
    2837     * Constructor
    2938     */
     
    3443
    3544    @Override
    3645    public void visit(Way w) {
    37         if (w.hasTag("route", "ferry")) {
     46        if (ignoreWay(w)) {
    3847            return;
    3948        }
    40         Double length = w.getLongestSegmentLength();
    41         if (length > maxlength) {
    42             length /= 1000.0;
     49        for (int i = 0; i < w.getNodesCount() - 1; i++) {
     50            visitWaySegment(w, i);
     51        }
     52    }
     53
     54    @Override
     55    public void visit(Node n) {
     56        // Test all way segments around this node.
     57        // If there is an error in the unchanged part of the way, we do not need to warn the user about it.
     58
     59        for (OsmPrimitive referrer : n.getReferrers()) {
     60            if (!(referrer instanceof Way)) {
     61                continue;
     62            }
     63            Way way = (Way) referrer;
     64            if (ignoreWay(way)) {
     65                continue;
     66            }
     67            // Do not simply use index of - a node may be in a way multiple times
     68            for (int i = 0; i < way.getNodesCount(); i++) {
     69                if (n == way.getNode(i)) {
     70                    if (i > 0) {
     71                        visitWaySegment(way, i - 1);
     72                    }
     73                    if (i < way.getNodesCount() - 1) {
     74                        visitWaySegment(way, i);
     75                    }
     76                }
     77            }
     78        }
     79    }
     80
     81    private boolean ignoreWay(Way w) {
     82        return w.hasTag("route", "ferry");
     83    }
     84
     85    private void visitWaySegment(Way w, int i) {
     86        LatLon coor1 = w.getNode(i).getCoor();
     87        LatLon coor2 = w.getNode(i + 1).getCoor();
     88
     89        if (coor1 != null && coor2 != null) {
     90            Double length = coor1.greatCircleDistance(coor2);
     91            if (length > maxlength) {
     92                addErrorForSegment(new WaySegment(w, i), length / 1000.0);
     93            }
     94        }
     95    }
     96
     97    private void addErrorForSegment(WaySegment waySegment, Double length) {
     98        if (reported.add(waySegment)) {
    4399            errors.add(TestError.builder(this, Severity.WARNING, LONG_SEGMENT)
    44100                    .message(tr("Long segments"), marktr("Very long segment of {0} kilometers"), length.intValue())
    45                     .primitives(w)
     101                    .primitives(waySegment.way)
     102                    .highlightWaySegments(Collections.singleton(waySegment))
    46103                    .build());
    47104        }
    48105    }
     
    51108    public void startTest(ProgressMonitor monitor) {
    52109        super.startTest(monitor);
    53110        maxlength = Main.pref.getInteger("validator.maximum.segment.length", 15_000);
     111        reported = Collections.synchronizedSet(new HashSet<>());
    54112    }
    55113
    56114    @Override
     115    public void endTest() {
     116        super.endTest();
     117        // free memory
     118        reported = null;
     119    }
     120
     121    @Override
    57122    public boolean isPrimitiveUsable(OsmPrimitive p) {
    58         return p.isUsable() && p instanceof Way && ((Way) p).getNodesCount() > 1; // test only Ways with at least 2 nodes
     123        if (!p.isUsable()) {
     124            return false;
     125        } else if (p instanceof Way && ((Way) p).getNodesCount() > 1) {
     126            // test only Ways with at least 2 nodes
     127            return true;
     128        } else {
     129            // test all nodes - ways referred by them may not be checked automatically.
     130            return p instanceof Node;
     131        }
    59132    }
    60133}