Ticket #20057: 20057-beta.patch

File 20057-beta.patch, 9.0 KB (added by GerdP, 6 years ago)
  • src/org/openstreetmap/josm/data/validation/tests/UnconnectedWays.java

     
    241241        minmiddledist = Config.getPref().getDouble(PREFIX + ".way_way_distance", 0.0);
    242242        ds = OsmDataManager.getInstance().getActiveDataSet();
    243243        dsArea = ds == null ? null : ds.getDataSourceArea();
     244        maxLen = DETOUR_FACTOR * mindist;
    244245    }
    245246
    246247    protected Map<Node, MyWaySegment> getHighwayEndNodesNearOtherHighway() {
     
    350351            Node node = error.getKey();
    351352            MyWaySegment ws = error.getValue();
    352353            errors.add(TestError.builder(this, severity, code)
    353                     .message(message)
     354                    .message(this.name, message)
    354355                    .primitives(node, ws.w)
    355356                    .highlight(node)
    356357                    .build());
     
    371372        }
    372373        fillSearchNodes(endnodes);
    373374        if (!searchNodes.isEmpty()) {
    374             maxLen = DETOUR_FACTOR * mindist;
    375375            if (isHighwayTest) {
    376                 addErrors(Severity.WARNING, getHighwayEndNodesNearOtherHighway(), tr("Way end node near other highway"));
     376                addErrors(Severity.WARNING, getHighwayEndNodesNearOtherHighway(), tr("Way end node near other way"));
    377377            } else {
    378378                addErrors(Severity.WARNING, getWayEndNodesNearOtherWay(), tr("Way end node near other way"));
    379379            }
     
    382382        /* the following two should use a shorter distance */
    383383        boolean includeOther = isBeforeUpload ? ValidatorPrefHelper.PREF_OTHER_UPLOAD.get() : ValidatorPrefHelper.PREF_OTHER.get();
    384384        if (minmiddledist > 0.0 && includeOther) {
    385             maxLen = DETOUR_FACTOR * minmiddledist;
    386385            fillSearchNodes(middlenodes);
    387386            addErrors(Severity.OTHER, getWayNodesNearOtherWay(), tr("Way node near other way"));
    388387            fillSearchNodes(othernodes);
     
    415414        private final Node n2;
    416415        private final boolean concernsArea;
    417416
    418         MyWaySegment(Way w, Node n1, Node n2, boolean concersArea) {
     417        MyWaySegment(Way w, Node n1, Node n2, boolean concernsArea) {
    419418            this.w = w;
    420419            this.n1 = n1;
    421420            this.n2 = n2;
    422             this.concernsArea = concersArea;
     421            this.concernsArea = concernsArea;
    423422        }
    424423
    425424        /**
     
    444443                return false;
    445444            }
    446445            if (n1 == node || n2 == node) {
    447                 Node uncon = visited.iterator().next();
    448                 LatLon cl = ProjectionRegistry.getProjection().eastNorth2latlon(calcClosest(uncon));
     446                Node startNode = visited.iterator().next();
     447                LatLon cl = ProjectionRegistry.getProjection().eastNorth2latlon(calcClosest(startNode));
    449448                // calculate real detour length, closest point might be somewhere between n1 and n2
    450449                double detourLen = len + node.getCoor().greatCircleDistance(cl);
    451450                if (detourLen > maxLen)
    452451                    return false;
    453                 // see #17914: flag also nodes which are very close
    454                 double directDist = getDist(uncon);
    455                 if (directDist <= 0.1)
     452                if (!endnodes.contains(startNode))
     453                    return true;
     454                // see #17914: flag also unconnected nodes which are very close
     455                double directDist = getDist(startNode);
     456                if (directDist <= 0.1) {
    456457                    return false;
     458                }
    457459                return directDist > 0.5 || (visited.size() == 2 && directDist * 1.5 > detourLen);
    458460            }
    459             if (visited != null) {
    460                 visited.add(node);
    461                 List<Way> wantedParents = node.getParentWays().stream().filter(pw -> isWantedWay(pw))
    462                         .collect(Collectors.toList());
    463                 if (wantedParents.size() > 1 && wantedParents.indexOf(parent) != wantedParents.size() - 1) {
     461            List<Way> wantedParents = node.getParentWays().stream().filter(UnconnectedWays.this::isWantedWay)
     462                    .collect(Collectors.toList());
     463            if (wantedParents.size() > 1) {
     464                int posWanted = wantedParents.indexOf(parent);
     465                if (posWanted >= 0 && posWanted != wantedParents.size() - 1) {
    464466                    // we want to find a different way. so move known way to the end of the list
    465467                    wantedParents.remove(parent);
    466468                    wantedParents.add(parent);
    467469                }
    468 
    469                 for (final Way way : wantedParents) {
    470                     List<Node> nextNodes = new ArrayList<>();
    471                     int pos = way.getNodes().indexOf(node);
    472                     if (pos > 0) {
    473                         nextNodes.add(way.getNode(pos - 1));
     470            }
     471            for (final Way way : wantedParents) {
     472                if (len == 0)
     473                    visited.clear(); // first node might not be an end node
     474                visited.add(node);
     475                List<Node> nextNodes = new ArrayList<>();
     476                int pos = way.getNodes().indexOf(node);
     477                if (pos > 0) {
     478                    nextNodes.add(way.getNode(pos - 1));
     479                }
     480                if (pos + 1 < way.getNodesCount()) {
     481                    nextNodes.add(way.getNode(pos + 1));
     482                }
     483                for (Node next : nextNodes) {
     484                    final boolean containsN = visited.contains(next);
     485                    visited.add(next);
     486                    if (!containsN && isConnectedTo(next, visited,
     487                            len + node.getCoor().greatCircleDistance(next.getCoor()), way)) {
     488                        return true;
    474489                    }
    475                     if (pos + 1 < way.getNodesCount()) {
    476                         nextNodes.add(way.getNode(pos + 1));
    477                     }
    478                     for (Node next : nextNodes) {
    479                         final boolean containsN = visited.contains(next);
    480                         visited.add(next);
    481                         if (!containsN && isConnectedTo(next, visited,
    482                                 len + node.getCoor().greatCircleDistance(next.getCoor()), way)) {
    483                             return true;
    484                         }
    485                     }
    486490                }
    487491            }
    488492            return false;
     
    585589            return ret;
    586590
    587591        int size = w.getNodesCount();
     592        // TODO: concernsArea probably only useful with waterway=riverbank
    588593        boolean concersArea = w.concernsArea();
    589594        for (int i = 1; i < size; ++i) {
    590595            if (i < size-1) {
  • test/unit/org/openstreetmap/josm/data/validation/tests/UnconnectedWaysTest.java

     
    2121import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    2222import org.openstreetmap.josm.io.IllegalDataException;
    2323import org.openstreetmap.josm.io.OsmReader;
     24import org.openstreetmap.josm.spi.preferences.Config;
    2425
    2526/**
    2627 * Unit tests of {@code UnconnectedWays} class.
     
    8081    }
    8182
    8283    /**
    83      * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/18136">Bug #18106</a>.
     84     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/18106">Bug #18106</a>.
    8485     * @throws IOException if any I/O error occurs
    8586     * @throws IllegalDataException if the OSM data cannot be parsed
    8687     * @throws FileNotFoundException if the data file cannot be found
     
    138139            assertThat(bib.getErrors(), isEmpty());
    139140        }
    140141    }
     142
     143    /**
     144     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/20057">Bug #20057</a>.
     145     * @throws IOException if any I/O error occurs
     146     * @throws IllegalDataException if the OSM data cannot be parsed
     147     * @throws FileNotFoundException if the data file cannot be found
     148     */
     149    @Test
     150    void testTicket20057() throws IOException, IllegalDataException, FileNotFoundException {
     151        try (InputStream fis = TestUtils.getRegressionDataStream(20057, "data.osm")) {
     152            final DataSet ds = OsmReader.parseDataSet(fis, NullProgressMonitor.INSTANCE);
     153            MainApplication.getLayerManager().addLayer(new OsmDataLayer(ds, null, null));
     154            Config.getPref().putDouble(UnconnectedWays.PREFIX + ".way_way_distance", 1.0);
     155            Config.getPref().putBoolean("validator.other", true);
     156            bib.startTest(null);
     157            bib.setBeforeUpload(false);
     158            bib.visit(ds.allPrimitives());
     159            bib.endTest();
     160            assertThat(bib.getErrors(), isEmpty());
     161        }
     162    }
    141163}