Ticket #12524: LatLonHeadingFix.patch
| File LatLonHeadingFix.patch, 6.9 KB (added by , 10 years ago) |
|---|
-
src/org/openstreetmap/josm/data/coor/LatLon.java
diff --git a/src/org/openstreetmap/josm/data/coor/LatLon.java b/src/org/openstreetmap/josm/data/coor/LatLon.java index fcb9435..c963f26 100644
a b public class LatLon extends Coordinate { 326 326 } 327 327 328 328 /** 329 * Returns the heading, in radians, that you have to use to get from this lat/lon to another. 329 * Returns the heading that you have to use to get from this lat/lon to another. 330 * 331 * Angle starts from north and increases counterclockwise (!), PI/2 means west. 332 * You can get usual clockwise angle from {@link #bearing(LatLon)} method. 333 * This method is kept as deprecated because it is called from many plugins. 330 334 * 331 335 * (I don't know the original source of this formula, but see 332 336 * <a href="https://math.stackexchange.com/questions/720/how-to-calculate-a-heading-on-the-earths-surface">this question</a> 333 337 * for some hints how it is derived.) 334 338 * 339 * @deprecated see bearing method 335 340 * @param other the "destination" position 336 * @return heading in the range 0 <= hd < 2*PI341 * @return heading in radians in the range 0 <= hd < 2*PI 337 342 */ 343 @Deprecated 338 344 public double heading(LatLon other) { 339 345 double hd = atan2(sin(toRadians(this.lon() - other.lon())) * cos(toRadians(other.lat())), 340 346 cos(toRadians(this.lat())) * sin(toRadians(other.lat())) - … … public class LatLon extends Coordinate { 347 353 } 348 354 349 355 /** 356 * Returns bearing from this point to another. 357 * 358 * Angle starts from north and increases clockwise, PI/2 means east. 359 * Old deprecated method {@link #heading(LatLon)} used unusual reverse angle. 360 * 361 * Please note that reverse bearing (from other point to this point) should NOT be 362 * calculated from return value of this method, because great circle path 363 * between the two points have different bearings at each position. 364 * 365 * To get bearing from another point to this point call other.bearing(this) 366 * 367 * @param other the "destination" position 368 * @return heading in radians in the range 0 <= hd < 2*PI 369 */ 370 public double bearing(LatLon other) { 371 double lat1 = toRadians(this.lat()); 372 double lat2 = toRadians(other.lat()); 373 double dlon = toRadians(other.lon() - this.lon()); 374 double bearing = atan2( 375 sin(dlon) * cos(lat2), 376 cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dlon) 377 ); 378 bearing %= 2 * PI; 379 if (bearing < 0) { 380 bearing += 2 * PI; 381 } 382 return bearing; 383 } 384 385 /** 350 386 * Returns this lat/lon pair in human-readable format. 351 387 * 352 388 * @return String in the format "lat=1.23456 deg, lon=2.34567 deg" -
src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
diff --git a/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java b/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java index ed925af..2ca6174 100644
a b public class GpxDrawHelper { 88 88 private static final int sl4 = 5; 89 89 private static final int sl9 = 3; 90 90 private static final int[][] dir = { 91 {+sl4, +ll0, +ll0, +sl4}, {-sl9, +ll0, +sl9, +ll0}, {-ll0, +sl4, -sl4, +ll0}, 92 {-ll0, -sl9, -ll0, +sl9}, {-sl4, -ll0, -ll0, -sl4}, {+sl9, -ll0, -sl9, -ll0}, 93 {+ll0, -sl4, +sl4, -ll0}, {+ll0, +sl9, +ll0, -sl9}, {+sl4, +ll0, +ll0, +sl4}, 94 {-sl9, +ll0, +sl9, +ll0}, {-ll0, +sl4, -sl4, +ll0}, {-ll0, -sl9, -ll0, +sl9}}; 91 {+sl4, +ll0, +ll0, +sl4}, {-sl9, +ll0, +sl9, +ll0}, 92 {-ll0, +sl4, -sl4, +ll0}, {-ll0, -sl9, -ll0, +sl9}, 93 {-sl4, -ll0, -ll0, -sl4}, {+sl9, -ll0, -sl9, -ll0}, 94 {+ll0, -sl4, +sl4, -ll0}, {+ll0, +sl9, +ll0, -sl9} 95 }; 95 96 96 97 private void setupColors() { 97 98 hdopAlpha = Main.pref.getInteger("hdop.color.alpha", -1); … … public class GpxDrawHelper { 332 333 } 333 334 break; 334 335 case DIRECTION: 335 double dirColor = oldWp.getCoor(). heading(trkPnt.getCoor());336 double dirColor = oldWp.getCoor().bearing(trkPnt.getCoor()); 336 337 color = directionScale.getColor(dirColor); 337 338 break; 338 339 case TIME: … … public class GpxDrawHelper { 347 348 } 348 349 if (!noDraw && (maxLineLength == -1 || dist <= maxLineLength)) { 349 350 trkPnt.drawLine = true; 350 trkPnt.dir = (int) oldWp.getCoor().heading(trkPnt.getCoor()); 351 double bearing = oldWp.getCoor().bearing(trkPnt.getCoor()); 352 trkPnt.dir = ((int) (bearing / Math.PI * 4 + 1.5)) % 8; 351 353 } else { 352 354 trkPnt.drawLine = false; 353 355 } -
src/org/openstreetmap/josm/tools/ColorScale.java
diff --git a/src/org/openstreetmap/josm/tools/ColorScale.java b/src/org/openstreetmap/josm/tools/ColorScale.java index ea3b5ac..f2e482c 100644
a b public final class ColorScale { 44 44 sc.colors = new Color[count]; 45 45 for (int i = 0; i < sc.colors.length; i++) { 46 46 47 float angle = 4 -i / 256f * 4;47 float angle = i / 256f * 4; 48 48 int quadrant = (int) angle; 49 49 angle -= quadrant; 50 50 quadrant = Utils.mod(quadrant+1, 4); -
test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java
diff --git a/test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java b/test/unit/org/openstreetmap/josm/data/coor/LatLonTest.java index 74cdcf0..a0ef2d0 100644
a b import org.junit.Test; 10 10 */ 11 11 public class LatLonTest { 12 12 13 private static final double EPSILON = 1e-6; 14 13 15 public static final double[] SAMPLE_VALUES = new double[]{ 14 16 -180.0, -179.9, -179.6, -179.5, -179.4, -179.1, -179.0, -100.0, -99.9, -10.0, -9.9, -1.0, -0.1, 15 17 180.0, 179.9, 179.6, 179.5, 179.4, 179.1, 179.0, 100.0, 99.9, 10.0, 9.9, 1.0, 0.1, … … public class LatLonTest { 123 125 assertEquals(a.hashCode(), b.hashCode()); 124 126 } 125 127 } 128 129 /** 130 * Test of {@link LatLon#bearing} 131 */ 132 @Test 133 public void testBearing() { 134 LatLon c = new LatLon(47.000000, 19.000000); 135 LatLon e = new LatLon(47.000000, 19.000001); 136 LatLon n = new LatLon(47.000001, 19.000000); 137 assertEquals( 0, Math.toDegrees(c.bearing(n)), EPSILON); 138 assertEquals( 90, Math.toDegrees(c.bearing(e)), EPSILON); 139 assertEquals(180, Math.toDegrees(n.bearing(c)), EPSILON); 140 assertEquals(270, Math.toDegrees(e.bearing(c)), EPSILON); 141 } 126 142 }
