Changeset 18963 in josm
- Timestamp:
- 2024-01-30T14:33:14+01:00 (12 months ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyHelper.java
r16438 r18963 44 44 45 45 if (node != null) { 46 Optional<Way> candidate = node.referrers(Way.class).findFirst(); 46 Optional<Way> candidate = node.referrers(Way.class).filter(Way::isUsable).findFirst(); 47 47 if (candidate.isPresent()) { 48 48 return candidate.get(); … … 70 70 EastNorth pEN = mv.getEastNorth(p.x, p.y); 71 71 72 Double bestDistance = Double.MAX_VALUE;73 Double currentDistance;72 double bestDistance = Double.MAX_VALUE; 73 double currentDistance; 74 74 List<Pair<Node, Node>> wpps = w.getNodePairs(false); 75 75 76 76 Node result = null; 77 77 78 mainLoop:79 78 for (Node n : w.getNodes()) { 80 79 EastNorth nEN = n.getEastNorth(); … … 87 86 currentDistance = pEN.distance(nEN); 88 87 89 if (currentDistance < bestDistance) { 90 // Making sure this candidate is not behind any segment. 91 for (Pair<Node, Node> wpp : wpps) { 92 if (!wpp.a.equals(n) 93 && !wpp.b.equals(n) 94 && Geometry.getSegmentSegmentIntersection( 95 wpp.a.getEastNorth(), wpp.b.getEastNorth(), 96 pEN, nEN) != null) { 97 continue mainLoop; 98 } 99 } 88 if (currentDistance < bestDistance && ensureCandidateIsNotBehindSegments(wpps, n, pEN, nEN)) { 100 89 result = n; 101 90 bestDistance = currentDistance; … … 107 96 108 97 /** 98 * Check to see if a candidate node is underneath a way segment 99 * 100 * @param wpps The pairs of nodes to check for crossing way segments 101 * @param n The current node to check 102 * @param pEN The cursor east-north position 103 * @param nEN The node east-north position 104 * @return {@code true} if the candidate node is underneath a way segment 105 */ 106 private static boolean ensureCandidateIsNotBehindSegments(Iterable<Pair<Node, Node>> wpps, Node n, EastNorth pEN, EastNorth nEN) { 107 // Making sure this candidate is not behind any segment. 108 for (Pair<Node, Node> wpp : wpps) { 109 if (!wpp.a.equals(n) 110 && !wpp.b.equals(n) 111 && Geometry.getSegmentSegmentIntersection( 112 wpp.a.getEastNorth(), wpp.b.getEastNorth(), 113 pEN, nEN) != null) { 114 return false; 115 } 116 } 117 return true; 118 } 119 120 /** 109 121 * Returns the nearest way segment to cursor. The distance to segment ab is 110 122 * the length of altitude from p to ab (say, c) or the minimum distance from 111 123 * p to a or b if c is out of ab. 112 * 124 * <p> 113 125 * The priority is given to segments where c is in ab. Otherwise, a segment 114 126 * with the largest angle apb is chosen. … … 126 138 EastNorth pEN = mv.getEastNorth(p.x, p.y); 127 139 128 Double currentDistance; 129 Double currentAngle; 130 Double bestDistance = Double.MAX_VALUE; 131 Double bestAngle = 0.0; 140 double bestDistance = Double.MAX_VALUE; 141 double bestAngle = 0.0; 132 142 133 143 int candidate = -1; … … 144 154 // Finding intersection of the segment with its altitude from p 145 155 EastNorth altitudeIntersection = Geometry.closestPointToSegment(a, b, pEN); 146 currentDistance = pEN.distance(altitudeIntersection); 156 final double currentDistance = pEN.distance(altitudeIntersection); 147 157 158 final double currentAngle; 148 159 if (!altitudeIntersection.equals(a) && !altitudeIntersection.equals(b)) { 149 160 // If the segment intersects with the altitude from p, -
trunk/src/org/openstreetmap/josm/data/validation/ValidationTask.java
r18960 r18963 112 112 113 113 } 114 114 115 protected ValidationTask(ProgressMonitor progressMonitor, 115 116 Collection<Test> tests, -
trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java
r18962 r18963 354 354 return selection; 355 355 } 356 356 357 static boolean isCoastline(OsmPrimitive w) { 357 358 return w.hasTag("natural", "water", "coastline") || w.hasTag(LANDUSE, "reservoir"); -
trunk/test/unit/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyActionTest.java
r18870 r18963 2 2 package org.openstreetmap.josm.actions.mapmode; 3 3 4 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; 4 5 import static org.junit.jupiter.api.Assertions.assertEquals; 6 import static org.junit.jupiter.api.Assertions.assertFalse; 5 7 import static org.junit.jupiter.api.Assertions.assertTrue; 6 8 9 import java.awt.Graphics2D; 10 import java.awt.Point; 11 import java.awt.event.MouseEvent; 12 import java.awt.image.BufferedImage; 13 7 14 import org.junit.jupiter.api.Test; 15 import org.junit.jupiter.api.extension.RegisterExtension; 8 16 import org.openstreetmap.josm.TestUtils; 9 17 import org.openstreetmap.josm.actions.mapmode.ImproveWayAccuracyAction.State; 18 import org.openstreetmap.josm.data.Bounds; 19 import org.openstreetmap.josm.data.coor.ILatLon; 20 import org.openstreetmap.josm.data.coor.LatLon; 10 21 import org.openstreetmap.josm.data.osm.DataSet; 22 import org.openstreetmap.josm.data.osm.Node; 23 import org.openstreetmap.josm.data.osm.Way; 11 24 import org.openstreetmap.josm.gui.MainApplication; 12 25 import org.openstreetmap.josm.gui.MapFrame; 26 import org.openstreetmap.josm.gui.MapView; 13 27 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 28 import org.openstreetmap.josm.gui.util.GuiHelper; 14 29 import org.openstreetmap.josm.testutils.annotations.Main; 15 30 import org.openstreetmap.josm.testutils.annotations.Projection; 31 import org.openstreetmap.josm.testutils.mockers.WindowlessMapViewStateMocker; 32 import org.openstreetmap.josm.testutils.mockers.WindowlessNavigatableComponentMocker; 33 34 import mockit.Mock; 16 35 17 36 /** 18 37 * Unit tests for class {@link ImproveWayAccuracyAction}. 19 38 */ 20 @Main21 39 @Projection 22 40 class ImproveWayAccuracyActionTest { 41 @RegisterExtension 42 Main.MainExtension mainExtension = new Main.MainExtension().setMapViewMocker(SizedWindowlessMapViewStateMocker::new) 43 .setNavigableComponentMocker(SizedWindowlessNavigatableComponentMocker::new); 44 45 private static final int WIDTH = 800; 46 private static final int HEIGHT = 600; 47 private static class SizedWindowlessMapViewStateMocker extends WindowlessMapViewStateMocker { 48 @Mock 49 public int getWidth() { 50 return WIDTH; 51 } 52 53 @Mock 54 public int getHeight() { 55 return HEIGHT; 56 } 57 } 58 59 private static class SizedWindowlessNavigatableComponentMocker extends WindowlessNavigatableComponentMocker { 60 @Mock 61 public int getWidth() { 62 return WIDTH; 63 } 64 65 @Mock 66 public int getHeight() { 67 return HEIGHT; 68 } 69 } 70 71 private static MouseEvent generateEvent(MapView mapView, ILatLon location) { 72 final Point p = mapView.getPoint(location); 73 return new MouseEvent(mapView, 0, 0, 0, p.x, p.y, p.x, p.y, 1, false, MouseEvent.BUTTON1); 74 } 75 23 76 /** 24 77 * Unit test of {@link ImproveWayAccuracyAction#enterMode} and {@link ImproveWayAccuracyAction#exitMode}. … … 45 98 @Test 46 99 void testEnumState() { 47 TestUtils.superficialEnumCodeCoverage(State.class); 100 assertDoesNotThrow(() -> TestUtils.superficialEnumCodeCoverage(State.class)); 101 } 102 103 @Test 104 void testNonRegression23444() { 105 final DataSet dataSet = new DataSet(); 106 final OsmDataLayer layer = new OsmDataLayer(dataSet, "ImproveWayAccuracyActionT", null); 107 MainApplication.getLayerManager().addLayer(layer); 108 final ImproveWayAccuracyAction mapMode = new ImproveWayAccuracyAction(); 109 final MapFrame map = MainApplication.getMap(); 110 assertTrue(map.selectMapMode(mapMode)); 111 assertEquals(mapMode, map.mapMode); 112 final Way testWay = TestUtils.newWay("", new Node(1, 1), new Node(2, 1), 113 new Node(3), new Node(4, 1), new Node(5, 1)); 114 testWay.firstNode().setCoor(new LatLon(0, 0)); 115 testWay.lastNode().setCoor(new LatLon(0.001, 0.001)); 116 testWay.getNode(1).setCoor(new LatLon(0.0001, 0.0001)); 117 testWay.getNode(3).setCoor(new LatLon(0.0009, 0.0009)); 118 dataSet.addPrimitiveRecursive(testWay); 119 assertFalse(testWay.getNode(2).isLatLonKnown(), "The second node should not have valid coordinates"); 120 final Graphics2D g2d = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB).createGraphics(); 121 g2d.setClip(0, 0, WIDTH, HEIGHT); 122 try { 123 // If this fails, something else is wrong 124 assertDoesNotThrow(() -> map.mapView.paint(g2d), "The mapview should be able to handle a null coordinate node"); 125 // Ensure that the test way is selected (and use the methods from the action to do so) 126 GuiHelper.runInEDTAndWaitWithException(() -> { 127 map.mapView.zoomTo(new Bounds(0, 0, 0.001, 0.001)); 128 // Get the target way selected (note: not selected in dataset -- use mapMode.mapReleased for that) 129 mapMode.mouseMoved(generateEvent(map.mapView, testWay.getNode(1))); 130 }); 131 // mouseMoved shouldn't cause the way to get selected 132 assertFalse(dataSet.getAllSelected().contains(testWay)); 133 134 // Now check painting (where the problem should occur; the mapMode.paint call should be called as part of the map.mapView.paint call) 135 assertDoesNotThrow(() -> map.mapView.paint(g2d)); 136 assertDoesNotThrow(() -> mapMode.paint(g2d, map.mapView, new Bounds(0, 0, 0.001, 0.001))); 137 138 // Finally, check painting during selection 139 GuiHelper.runInEDTAndWaitWithException(() -> { 140 // Set the way as selected 141 mapMode.mouseReleased(generateEvent(map.mapView, new LatLon(0.0001, 0.0001))); 142 // Set the mouse location (unset in mouseReleased call) 143 mapMode.mouseMoved(generateEvent(map.mapView, new LatLon(0.0001, 0.0001))); 144 }); 145 // The way shouldn't be selected, since it isn't usable for the improve way tool 146 assertFalse(dataSet.getAllSelected().contains(testWay)); 147 // Now check painting again (just in case) 148 assertDoesNotThrow(() -> map.paint(g2d)); 149 assertDoesNotThrow(() -> mapMode.paint(g2d, map.mapView, new Bounds(0, 0, 0.001, 0.001))); 150 } finally { 151 g2d.dispose(); 152 } 48 153 } 49 154 }
Note:
See TracChangeset
for help on using the changeset viewer.