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

Last change on this file since 2512 was 2512, checked in by stoecker, 14 years ago

i18n updated, fixed files to reduce problems when applying patches, fix #4017

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