Changeset 15555 in josm


Ignore:
Timestamp:
2019-12-03T16:28:41+01:00 (4 years ago)
Author:
GerdP
Message:

fix #18385: Combine way action may remove parts of the ways

  • Count all edges that are added to the graph, even if they are rejected because they are duplicates.
  • add new method buildSpanningPathNoRemove() which returns null if any duplicate edge was found

and use this method in CombineWayAction

Location:
trunk
Files:
2 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java

    r14397 r15555  
    124124        // try to build a new way which includes all the combined ways
    125125        NodeGraph graph = NodeGraph.createNearlyUndirectedGraphFromNodeWays(ways);
    126         List<Node> path = graph.buildSpanningPath();
     126        List<Node> path = graph.buildSpanningPathNoRemove();
    127127        if (path == null) {
    128128            warnCombiningImpossible();
  • trunk/src/org/openstreetmap/josm/data/osm/NodeGraph.java

    r15554 r15555  
    139139    private final Set<NodePair> edges;
    140140    private int numUndirectedEges;
     141    /** counts the number of edges that were added */
     142    private int addedEdges;
    141143    private final Map<Node, List<NodePair>> successors = new LinkedHashMap<>();
    142144    private final Map<Node, List<NodePair>> predecessors = new LinkedHashMap<>();
     
    195197     */
    196198    public void add(NodePair pair) {
    197         if (!edges.contains(pair)) {
    198             edges.add(pair);
    199         }
     199        addedEdges++;
     200        edges.add(pair);
    200201    }
    201202
     
    290291    public List<Node> buildSpanningPath() {
    291292        prepare();
    292         if(numUndirectedEges > 0 && isConnected()) {
     293        if (numUndirectedEges > 0 && isConnected()) {
    293294            // try to find a path from each "terminal node", i.e. from a
    294295            // node which is connected by exactly one undirected edges (or
     
    311312
    312313    /**
     314     * Tries to find a path through the graph which visits each edge (i.e.
     315     * the segment of a way) exactly once. If the graph was build from overlapping
     316     * ways duplicate edges were removed already. This method will return null if
     317     * any duplicated edge was removed.
     318     *
     319     * @return the path; null, if no path was found or duplicated edges were found
     320     * @since xxx
     321     */
     322    public List<Node> buildSpanningPathNoRemove() {
     323        if (edges.size() != addedEdges)
     324            return null;
     325        return buildSpanningPath();
     326    }
     327
     328    /**
    313329     * Find out if the graph is connected.
    314330     * @return true if it is connected.
     
    321337        HashSet<Node> visited = new HashSet<>();
    322338        toVisit.add(nodes.iterator().next());
    323         while(!toVisit.isEmpty()) {
     339        while (!toVisit.isEmpty()) {
    324340            Node n = toVisit.pop();
    325341            if (!visited.contains(n)) {
  • trunk/test/unit/org/openstreetmap/josm/actions/CombineWayActionTest.java

    r14604 r15555  
    33
    44import static org.junit.Assert.assertEquals;
     5import static org.junit.Assert.assertNull;
    56
    67import java.io.IOException;
     
    4647            DataSet ds = OsmReader.parseDataSet(is, null);
    4748            NodeGraph graph = NodeGraph.createNearlyUndirectedGraphFromNodeWays(ds.getWays());
    48             List<Node> path = graph.buildSpanningPath();
     49            List<Node> path = graph.buildSpanningPathNoRemove();
    4950            assertEquals(10, path.size());
    5051            Set<Long> firstAndLastObtained = new HashSet<>();
     
    5556            firstAndLastExpected.add(35213705L);
    5657            assertEquals(firstAndLastExpected, firstAndLastObtained);
     58        }
     59    }
     60
     61    /**
     62     * Non-regression test for bug #1835 (combine way with overlapping ways)
     63     * @throws IOException if any I/O error occurs
     64     * @throws IllegalDataException if OSM parsing fails
     65     */
     66    @Test
     67    public void testTicket18385() throws IOException, IllegalDataException {
     68        try (InputStream is = TestUtils.getRegressionDataStream(18385, "data.osm")) {
     69            DataSet ds = OsmReader.parseDataSet(is, null);
     70            NodeGraph graph = NodeGraph.createNearlyUndirectedGraphFromNodeWays(ds.getWays());
     71            List<Node> path = graph.buildSpanningPathNoRemove();
     72            assertNull(path);
    5773        }
    5874    }
Note: See TracChangeset for help on using the changeset viewer.