source: josm/trunk/src/org/openstreetmap/josm/data/coor/LatLon.java@ 1724

Last change on this file since 1724 was 1724, checked in by stoecker, 15 years ago

some more changes and bug fixes related to new projection stuff - GPX should now work also

  • Property svn:eol-style set to native
File size: 5.1 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.data.coor;
3
4
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import org.openstreetmap.josm.data.Bounds;
8import org.openstreetmap.josm.data.projection.Projection;
9import org.openstreetmap.josm.Main;
10
11import java.text.DecimalFormat;
12import java.text.NumberFormat;
13
14/**
15 * LatLon are unprojected latitude / longitude coordinates.
16 *
17 * This class is immutable.
18 *
19 * @author Imi
20 */
21public class LatLon extends Coordinate {
22
23 private static DecimalFormat cDmsMinuteFormatter = new DecimalFormat("00");
24 private static DecimalFormat cDmsSecondFormatter = new DecimalFormat("00.0");
25 private static DecimalFormat cDdFormatter = new DecimalFormat("###0.0000");
26
27 /**
28 * Possible ways to display coordinates
29 */
30 public enum CoordinateFormat {
31 DECIMAL_DEGREES {public String toString() {return tr("Decimal Degrees");}},
32 DEGREES_MINUTES_SECONDS {public String toString() {return tr("Degrees Minutes Seconds");}};
33 }
34
35 public static String dms(double pCoordinate) {
36
37 double tAbsCoord = Math.abs(pCoordinate);
38 int tDegree = (int) tAbsCoord;
39 double tTmpMinutes = (tAbsCoord - tDegree) * 60;
40 int tMinutes = (int) tTmpMinutes;
41 double tSeconds = (tTmpMinutes - tMinutes) * 60;
42
43 return tDegree + "\u00B0" + cDmsMinuteFormatter.format(tMinutes) + "\'"
44 + cDmsSecondFormatter.format(tSeconds) + "\"";
45 }
46
47 public LatLon(double lat, double lon) {
48 super(lon, lat);
49 }
50
51 public double lat() {
52 return y;
53 }
54
55 public String latToString(CoordinateFormat d) {
56 switch(d) {
57 case DECIMAL_DEGREES: return cDdFormatter.format(y);
58 case DEGREES_MINUTES_SECONDS: return dms(y) + ((y < 0) ? tr("S") : tr("N"));
59 default: return "ERR";
60 }
61 }
62
63 public double lon() {
64 return x;
65 }
66
67 public String lonToString(CoordinateFormat d) {
68 switch(d) {
69 case DECIMAL_DEGREES: return cDdFormatter.format(x);
70 case DEGREES_MINUTES_SECONDS: return dms(x) + ((x < 0) ? tr("W") : tr("E"));
71 default: return "ERR";
72 }
73 }
74
75 /**
76 * @return <code>true</code> if the other point has almost the same lat/lon
77 * values, only differing by no more than
78 * 1 / {@link org.openstreetmap.josm.data.projection.Projection#MAX_SERVER_PRECISION MAX_SERVER_PRECISION}.
79 */
80 public boolean equalsEpsilon(LatLon other) {
81 final double p = 1/Projection.MAX_SERVER_PRECISION;
82 return Math.abs(lat()-other.lat()) <= p && Math.abs(lon()-other.lon()) <= p;
83 }
84
85 /**
86 * @return <code>true</code>, if the coordinate is outside the world, compared
87 * by using lat/lon.
88 */
89 public boolean isOutSideWorld() {
90 Bounds b = Main.proj.getWorldBoundsLatLon();
91 return lat() < b.min.lat() || lat() > b.max.lat() ||
92 lon() < b.min.lon() || lon() > b.max.lon();
93 }
94
95 /**
96 * @return <code>true</code> if this is within the given bounding box.
97 */
98 public boolean isWithin(Bounds b) {
99 return lat() >= b.min.lat() && lat() <= b.max.lat() && lon() > b.min.lon() && lon() < b.max.lon();
100 }
101
102 /**
103 * Computes the distance between this lat/lon and another point on the earth.
104 * Uses spherical law of cosines formula, not Haversine.
105 * @param other the other point.
106 * @return distance in metres.
107 */
108 public double greatCircleDistance(LatLon other) {
109 return (Math.acos(
110 Math.sin(Math.toRadians(lat())) * Math.sin(Math.toRadians(other.lat())) +
111 Math.cos(Math.toRadians(lat()))*Math.cos(Math.toRadians(other.lat())) *
112 Math.cos(Math.toRadians(other.lon()-lon()))) * 6378135);
113 }
114
115 /**
116 * Returns the heading, in radians, that you have to use to get from
117 * this lat/lon to another.
118 *
119 * @param other the "destination" position
120 * @return heading
121 */
122 public double heading(LatLon other) {
123 double rv;
124 if (other.lat() == lat()) {
125 rv = (other.lon()>lon() ? Math.PI / 2 : Math.PI * 3 / 2);
126 } else {
127 rv = Math.atan((other.lon()-lon())/(other.lat()-lat()));
128 if (rv < 0) rv += Math.PI;
129 if (other.lon() < lon()) rv += Math.PI;
130 }
131 return rv;
132 }
133
134 /**
135 * Returns this lat/lon pair in human-readable format.
136 *
137 * @return String in the format "lat=1.23456°, lon=2.34567°"
138 */
139 public String toDisplayString() {
140 NumberFormat nf = NumberFormat.getInstance();
141 nf.setMaximumFractionDigits(5);
142 return "lat=" + nf.format(lat()) + "°, lon=" + nf.format(lon()) + "°";
143 }
144
145 public LatLon interpolate(LatLon ll2, double proportion) {
146 return new LatLon(this.x + proportion * (ll2.x - this.x),
147 this.y + proportion * (ll2.y - this.y));
148 }
149
150 public LatLon getCenter(LatLon ll2) {
151 return new LatLon((this.x + ll2.x)/2.0, (this.y + ll2.y)/2.0);
152 }
153
154 @Override public String toString() {
155 return "LatLon[lat="+lat()+",lon="+lon()+"]";
156 }
157}
Note: See TracBrowser for help on using the repository browser.