From fceeea8c7d3e4993f12f42d84a7daefa57befe9b Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Thu, 21 Nov 2019 13:50:39 -0700 Subject: [PATCH] Fix an issue where ways could have a zig-zag Signed-off-by: Taylor Smock --- .../commands/AddNodeToWayCommand.java | 32 +++++++++++++++++-- .../commands/AddNodeToWayCommandTest.java | 30 ++++++++++++++--- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/commands/AddNodeToWayCommand.java b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/commands/AddNodeToWayCommand.java index 202008c..ef74330 100644 --- a/src/main/java/org/openstreetmap/josm/plugins/mapwithai/commands/AddNodeToWayCommand.java +++ b/src/main/java/org/openstreetmap/josm/plugins/mapwithai/commands/AddNodeToWayCommand.java @@ -3,13 +3,19 @@ package org.openstreetmap.josm.plugins.mapwithai.commands; import static org.openstreetmap.josm.tools.I18n.tr; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; import org.openstreetmap.josm.command.Command; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.Way; +import org.openstreetmap.josm.data.osm.WaySegment; +import org.openstreetmap.josm.plugins.mapwithai.backend.MapWithAIPreferenceHelper; +import org.openstreetmap.josm.tools.Geometry; public class AddNodeToWayCommand extends Command { private final Node toAddNode; @@ -35,9 +41,29 @@ public class AddNodeToWayCommand extends Command { @Override public boolean executeCommand() { - final int index = Math.max(getWay().getNodes().indexOf(getFirstNode()), - getWay().getNodes().indexOf(getSecondNode())); - getWay().addNode(index, getToAddNode()); + int index = Integer.MIN_VALUE; + try { + WaySegment.forNodePair(getWay(), getFirstNode(), getSecondNode()); + index = Math.max(getWay().getNodes().indexOf(getFirstNode()), getWay().getNodes().indexOf(getSecondNode())); + } catch (IllegalArgumentException e) { + // OK, someone has added a node between the two nodes since calculation + Way tWay = new Way(); + tWay.setNodes(Arrays.asList(getFirstNode(), getSecondNode())); + List relevantNodes = new ArrayList<>(getWay().getNodes().stream() + .filter(node -> Geometry.getDistance(tWay, node) < MapWithAIPreferenceHelper.getMaxNodeDistance()) + .collect(Collectors.toList())); + for (int i = 0; i < relevantNodes.size() - 1; i++) { + Way tWay2 = new Way(); + tWay2.setNodes(Arrays.asList(relevantNodes.get(i), relevantNodes.get(i + 1))); + if (Geometry.getDistance(tWay2, getToAddNode()) < MapWithAIPreferenceHelper.getMaxNodeDistance()) { + index = Math.max(way.getNodes().indexOf(tWay2.firstNode()), + way.getNodes().indexOf(tWay2.lastNode())); + } + } + } + if (index != Integer.MIN_VALUE) { + getWay().addNode(index, getToAddNode()); + } return true; } diff --git a/test/unit/org/openstreetmap/josm/plugins/mapwithai/commands/AddNodeToWayCommandTest.java b/test/unit/org/openstreetmap/josm/plugins/mapwithai/commands/AddNodeToWayCommandTest.java index 55277c7..cfab40d 100644 --- a/test/unit/org/openstreetmap/josm/plugins/mapwithai/commands/AddNodeToWayCommandTest.java +++ b/test/unit/org/openstreetmap/josm/plugins/mapwithai/commands/AddNodeToWayCommandTest.java @@ -1,6 +1,8 @@ // License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.mapwithai.commands; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.util.ArrayList; import java.util.List; @@ -14,7 +16,6 @@ import org.openstreetmap.josm.data.osm.DataSet; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.Way; -import org.openstreetmap.josm.plugins.mapwithai.commands.AddNodeToWayCommand; import org.openstreetmap.josm.testutils.JOSMTestRules; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; @@ -25,12 +26,12 @@ public class AddNodeToWayCommandTest { private AddNodeToWayCommand command; @Rule @SuppressFBWarnings("URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD") - public JOSMTestRules test = new JOSMTestRules(); + public JOSMTestRules test = new JOSMTestRules().projection(); @Before public void setupArea() { - toAdd = new Node(new LatLon(0.1, 0.1)); - way = TestUtils.newWay("", new Node(new LatLon(0, 0)), new Node(new LatLon(-0.1, -0.1))); + toAdd = new Node(new LatLon(0, 0)); + way = TestUtils.newWay("", new Node(new LatLon(0.1, 0.1)), new Node(new LatLon(-0.1, -0.1))); new DataSet(toAdd, way.firstNode(), way.lastNode(), way); command = new AddNodeToWayCommand(toAdd, way, way.firstNode(), way.lastNode()); } @@ -67,4 +68,25 @@ public class AddNodeToWayCommandTest { Assert.assertTrue(added.isEmpty()); Assert.assertEquals(2, modified.size()); } + + @Test + public void testMultiAddConnections() { + command.executeCommand(); + Node tNode = new Node(new LatLon(0.01, 0.01)); + way.getDataSet().addPrimitive(tNode); + command = new AddNodeToWayCommand(tNode, way, way.firstNode(), way.lastNode()); + command.executeCommand(); + assertEquals(new LatLon(0.1, 0.1), way.firstNode().getCoor()); + assertEquals(new LatLon(0.01, 0.01), way.getNode(1).getCoor()); + assertEquals(new LatLon(0, 0), way.getNode(2).getCoor()); + assertEquals(new LatLon(-0.1, -0.1), way.lastNode().getCoor()); + command.undoCommand(); + tNode.setCoor(new LatLon(-0.01, -0.01)); + command = new AddNodeToWayCommand(tNode, way, way.firstNode(), way.lastNode()); + command.executeCommand(); + assertEquals(new LatLon(0.1, 0.1), way.firstNode().getCoor()); + assertEquals(new LatLon(0, 0), way.getNode(1).getCoor()); + assertEquals(new LatLon(-0.01, -0.01), way.getNode(2).getCoor()); + assertEquals(new LatLon(-0.1, -0.1), way.lastNode().getCoor()); + } }