Skip to content

Commit 816bcb3

Browse files
author
taylor.smock
committed
Fix #13097: Angle snapping impossible with WGS84 projection
git-svn-id: https://josm.openstreetmap.de/svn/trunk@18612 0c6e7542-c601-0410-84e7-c038aed88b3b
1 parent 29301e3 commit 816bcb3

File tree

2 files changed

+84
-1
lines changed

2 files changed

+84
-1
lines changed

src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.openstreetmap.josm.data.osm.Node;
2525
import org.openstreetmap.josm.data.osm.Way;
2626
import org.openstreetmap.josm.data.osm.WaySegment;
27+
import org.openstreetmap.josm.data.projection.ProjectionRegistry;
2728
import org.openstreetmap.josm.gui.MainApplication;
2829
import org.openstreetmap.josm.gui.MapView;
2930
import org.openstreetmap.josm.gui.MapViewState;
@@ -439,7 +440,7 @@ public EastNorth getSnapPoint(EastNorth p) {
439440
double de = p.east()-e0;
440441
double dn = p.north()-n0;
441442
double l = de*pe+dn*pn;
442-
double delta = MainApplication.getMap().mapView.getDist100Pixel()/20;
443+
double delta = MainApplication.getMap().mapView.getDist100Pixel() / (20 * ProjectionRegistry.getProjection().getMetersPerUnit());
443444
if (!absoluteFix && l < delta) {
444445
active = false;
445446
return p;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// License: GPL. For details, see LICENSE file.
2+
package org.openstreetmap.josm.actions.mapmode;
3+
4+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
5+
import static org.junit.jupiter.api.Assertions.assertEquals;
6+
import static org.junit.jupiter.api.Assertions.assertNotSame;
7+
8+
import java.util.Arrays;
9+
import java.util.stream.Stream;
10+
11+
import javax.swing.JCheckBoxMenuItem;
12+
13+
import org.junit.jupiter.api.extension.RegisterExtension;
14+
import org.junit.jupiter.params.ParameterizedTest;
15+
import org.junit.jupiter.params.provider.Arguments;
16+
import org.junit.jupiter.params.provider.MethodSource;
17+
import org.openstreetmap.josm.data.coor.EastNorth;
18+
import org.openstreetmap.josm.data.coor.LatLon;
19+
import org.openstreetmap.josm.data.osm.DataSet;
20+
import org.openstreetmap.josm.data.osm.Node;
21+
import org.openstreetmap.josm.data.osm.Way;
22+
import org.openstreetmap.josm.data.osm.WaySegment;
23+
import org.openstreetmap.josm.data.projection.Projection;
24+
import org.openstreetmap.josm.data.projection.ProjectionRegistry;
25+
import org.openstreetmap.josm.data.projection.Projections;
26+
import org.openstreetmap.josm.gui.MainApplication;
27+
import org.openstreetmap.josm.gui.layer.OsmDataLayer;
28+
import org.openstreetmap.josm.testutils.JOSMTestRules;
29+
import org.openstreetmap.josm.tools.Utils;
30+
31+
/**
32+
* Test class for {@link DrawSnapHelper}
33+
*/
34+
class DrawSnapHelperTest {
35+
@RegisterExtension
36+
static JOSMTestRules rule = new JOSMTestRules().projection().main();
37+
38+
static Stream<Arguments> testNonRegression13097() {
39+
return Stream.of(
40+
Arguments.of(Projections.getProjectionByCode("EPSG:4326")), // WGS84 Geographic
41+
Arguments.of(Projections.getProjectionByCode("EPSG:3857")) // Mercator
42+
);
43+
}
44+
45+
/**
46+
* See #13097: Angle snapping impossible with WGS84 projection
47+
*/
48+
@ParameterizedTest
49+
@MethodSource
50+
void testNonRegression13097(Projection projection) {
51+
ProjectionRegistry.setProjection(projection);
52+
DrawAction drawAction = new DrawAction();
53+
DrawSnapHelper drawSnapHelper = new DrawSnapHelper(drawAction);
54+
drawSnapHelper.setMenuCheckBox(new JCheckBoxMenuItem()); // Just needed to avoid an NPE in enableSnapping
55+
drawSnapHelper.init(); // Needed to get the default angle snaps
56+
drawSnapHelper.enableSnapping();
57+
Way way1 = new Way();
58+
Node node1 = new Node(new LatLon(39.1260035, -108.5624143));
59+
Node node2 = new Node(new LatLon(39.1260973, -108.5622908));
60+
way1.setNodes(Arrays.asList(node1, node2));
61+
DataSet ds = new DataSet();
62+
ds.addPrimitiveRecursive(way1);
63+
ds.setSelected(way1, node2);
64+
MainApplication.getLayerManager().addLayer(new OsmDataLayer(ds, "testNonRegression13097", null));
65+
// We need to ensure that the mapView is zoomed in enough. This takes several zoom in events after we zoom to node2.
66+
MainApplication.getMap().mapView.zoomTo(node2);
67+
for (int i = 0; i < 4; i++) {
68+
MainApplication.getMap().mapView.zoomIn();
69+
}
70+
drawAction.enterMode();
71+
drawSnapHelper.setBaseSegment(new WaySegment(way1, 0));
72+
EastNorth position = projection.latlon2eastNorth(new LatLon(39.1260263, -108.5621895));
73+
double wayHeading = Utils.toDegrees(
74+
assertDoesNotThrow(() -> way1.firstNode().getEastNorth(projection).heading(way1.lastNode().getEastNorth()))
75+
);
76+
drawSnapHelper.checkAngleSnapping(position, wayHeading, wayHeading + 90);
77+
EastNorth snapPoint = drawSnapHelper.getSnapPoint(position);
78+
// We can't really check the latlon -- 90 degrees is different based off of projection.
79+
assertNotSame(position, snapPoint, "The snap point should not be the same as the original position");
80+
assertEquals(90, Math.abs(wayHeading - Utils.toDegrees(node2.getEastNorth(projection).heading(snapPoint))), 1e-8);
81+
}
82+
}

0 commit comments

Comments
 (0)