Ticket #5551: projection-patch.diff
| File projection-patch.diff, 29.2 KB (added by , 15 years ago) |
|---|
-
src/org/openstreetmap/josm/data/projection/Projection.java
18 18 public static Projection[] allProjections = new Projection[]{ 19 19 new Epsg4326(), 20 20 new Mercator(), 21 new TransverseMercatorLV(), 21 22 new LambertEST(), // Still needs proper default zoom 22 23 new Lambert(), // Still needs proper default zoom 23 24 new Puwg(), -
src/org/openstreetmap/josm/data/projection/TransverseMercator.java
1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.data.projection; 3 4 /** 5 * This is a base class to do projections based on Transverse Mercator projection. 6 * 7 * @author Dirk Stöcker 8 * code based on JavaScript from Chuck Taylor 9 * 10 * NOTE: Uses polygon approximation to translate to WGS84. 11 */ 12 import org.openstreetmap.josm.data.coor.EastNorth; 13 import org.openstreetmap.josm.data.coor.LatLon; 14 15 public abstract class TransverseMercator implements Projection { 16 17 private final static double UTMScaleFactor = 0.9996; 18 19 private double UTMCentralMeridianRad = 0; 20 private double offsetEastMeters = 500000; 21 private double offsetNorthMeters = 0; 22 23 24 protected void setProjectionParameters(double centralMeridianDegress, double offsetEast, double offsetNorth) 25 { 26 UTMCentralMeridianRad = Math.toRadians(centralMeridianDegress); 27 offsetEastMeters = offsetEast; 28 offsetNorthMeters = offsetNorth; 29 } 30 31 /* 32 * ArcLengthOfMeridian 33 * 34 * Computes the ellipsoidal distance from the equator to a point at a 35 * given latitude. 36 * 37 * Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., 38 * GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. 39 * 40 * Inputs: 41 * phi - Latitude of the point, in radians. 42 * 43 * Globals: 44 * Ellipsoid.GRS80.a - Ellipsoid model major axis. 45 * Ellipsoid.GRS80.b - Ellipsoid model minor axis. 46 * 47 * Returns: 48 * The ellipsoidal distance of the point from the equator, in meters. 49 * 50 */ 51 private double ArcLengthOfMeridian(double phi) 52 { 53 /* Precalculate n */ 54 double n = (Ellipsoid.GRS80.a - Ellipsoid.GRS80.b) / (Ellipsoid.GRS80.a + Ellipsoid.GRS80.b); 55 56 /* Precalculate alpha */ 57 double alpha = ((Ellipsoid.GRS80.a + Ellipsoid.GRS80.b) / 2.0) 58 * (1.0 + (Math.pow (n, 2.0) / 4.0) + (Math.pow (n, 4.0) / 64.0)); 59 60 /* Precalculate beta */ 61 double beta = (-3.0 * n / 2.0) + (9.0 * Math.pow (n, 3.0) / 16.0) 62 + (-3.0 * Math.pow (n, 5.0) / 32.0); 63 64 /* Precalculate gamma */ 65 double gamma = (15.0 * Math.pow (n, 2.0) / 16.0) 66 + (-15.0 * Math.pow (n, 4.0) / 32.0); 67 68 /* Precalculate delta */ 69 double delta = (-35.0 * Math.pow (n, 3.0) / 48.0) 70 + (105.0 * Math.pow (n, 5.0) / 256.0); 71 72 /* Precalculate epsilon */ 73 double epsilon = (315.0 * Math.pow (n, 4.0) / 512.0); 74 75 /* Now calculate the sum of the series and return */ 76 return alpha 77 * (phi + (beta * Math.sin (2.0 * phi)) 78 + (gamma * Math.sin (4.0 * phi)) 79 + (delta * Math.sin (6.0 * phi)) 80 + (epsilon * Math.sin (8.0 * phi))); 81 } 82 83 84 /* 85 * FootpointLatitude 86 * 87 * Computes the footpoint latitude for use in converting transverse 88 * Mercator coordinates to ellipsoidal coordinates. 89 * 90 * Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., 91 * GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. 92 * 93 * Inputs: 94 * y - The UTM northing coordinate, in meters. 95 * 96 * Returns: 97 * The footpoint latitude, in radians. 98 * 99 */ 100 private double FootpointLatitude(double y) 101 { 102 /* Precalculate n (Eq. 10.18) */ 103 double n = (Ellipsoid.GRS80.a - Ellipsoid.GRS80.b) / (Ellipsoid.GRS80.a + Ellipsoid.GRS80.b); 104 105 /* Precalculate alpha_ (Eq. 10.22) */ 106 /* (Same as alpha in Eq. 10.17) */ 107 double alpha_ = ((Ellipsoid.GRS80.a + Ellipsoid.GRS80.b) / 2.0) 108 * (1 + (Math.pow (n, 2.0) / 4) + (Math.pow (n, 4.0) / 64)); 109 110 /* Precalculate y_ (Eq. 10.23) */ 111 double y_ = y / alpha_; 112 113 /* Precalculate beta_ (Eq. 10.22) */ 114 double beta_ = (3.0 * n / 2.0) + (-27.0 * Math.pow (n, 3.0) / 32.0) 115 + (269.0 * Math.pow (n, 5.0) / 512.0); 116 117 /* Precalculate gamma_ (Eq. 10.22) */ 118 double gamma_ = (21.0 * Math.pow (n, 2.0) / 16.0) 119 + (-55.0 * Math.pow (n, 4.0) / 32.0); 120 121 /* Precalculate delta_ (Eq. 10.22) */ 122 double delta_ = (151.0 * Math.pow (n, 3.0) / 96.0) 123 + (-417.0 * Math.pow (n, 5.0) / 128.0); 124 125 /* Precalculate epsilon_ (Eq. 10.22) */ 126 double epsilon_ = (1097.0 * Math.pow (n, 4.0) / 512.0); 127 128 /* Now calculate the sum of the series (Eq. 10.21) */ 129 return y_ + (beta_ * Math.sin (2.0 * y_)) 130 + (gamma_ * Math.sin (4.0 * y_)) 131 + (delta_ * Math.sin (6.0 * y_)) 132 + (epsilon_ * Math.sin (8.0 * y_)); 133 } 134 135 /* 136 * MapLatLonToXY 137 * 138 * Converts a latitude/longitude pair to x and y coordinates in the 139 * Transverse Mercator projection. Note that Transverse Mercator is not 140 * the same as UTM; a scale factor is required to convert between them. 141 * 142 * Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., 143 * GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. 144 * 145 * Inputs: 146 * phi - Latitude of the point, in radians. 147 * lambda - Longitude of the point, in radians. 148 * lambda0 - Longitude of the central meridian to be used, in radians. 149 * 150 * Outputs: 151 * xy - A 2-element array containing the x and y coordinates 152 * of the computed point. 153 * 154 * Returns: 155 * The function does not return a value. 156 * 157 */ 158 public EastNorth mapLatLonToXY(double phi, double lambda, double lambda0) 159 { 160 /* Precalculate ep2 */ 161 double ep2 = (Math.pow (Ellipsoid.GRS80.a, 2.0) - Math.pow (Ellipsoid.GRS80.b, 2.0)) / Math.pow (Ellipsoid.GRS80.b, 2.0); 162 163 /* Precalculate nu2 */ 164 double nu2 = ep2 * Math.pow (Math.cos (phi), 2.0); 165 166 /* Precalculate N */ 167 double N = Math.pow (Ellipsoid.GRS80.a, 2.0) / (Ellipsoid.GRS80.b * Math.sqrt (1 + nu2)); 168 169 /* Precalculate t */ 170 double t = Math.tan (phi); 171 double t2 = t * t; 172 173 /* Precalculate l */ 174 double l = lambda - lambda0; 175 176 /* Precalculate coefficients for l**n in the equations below 177 so a normal human being can read the expressions for easting 178 and northing 179 -- l**1 and l**2 have coefficients of 1.0 */ 180 double l3coef = 1.0 - t2 + nu2; 181 182 double l4coef = 5.0 - t2 + 9 * nu2 + 4.0 * (nu2 * nu2); 183 184 double l5coef = 5.0 - 18.0 * t2 + (t2 * t2) + 14.0 * nu2 185 - 58.0 * t2 * nu2; 186 187 double l6coef = 61.0 - 58.0 * t2 + (t2 * t2) + 270.0 * nu2 188 - 330.0 * t2 * nu2; 189 190 double l7coef = 61.0 - 479.0 * t2 + 179.0 * (t2 * t2) - (t2 * t2 * t2); 191 192 double l8coef = 1385.0 - 3111.0 * t2 + 543.0 * (t2 * t2) - (t2 * t2 * t2); 193 194 return new EastNorth( 195 /* Calculate easting (x) */ 196 N * Math.cos (phi) * l 197 + (N / 6.0 * Math.pow (Math.cos (phi), 3.0) * l3coef * Math.pow (l, 3.0)) 198 + (N / 120.0 * Math.pow (Math.cos (phi), 5.0) * l5coef * Math.pow (l, 5.0)) 199 + (N / 5040.0 * Math.pow (Math.cos (phi), 7.0) * l7coef * Math.pow (l, 7.0)), 200 /* Calculate northing (y) */ 201 ArcLengthOfMeridian (phi) 202 + (t / 2.0 * N * Math.pow (Math.cos (phi), 2.0) * Math.pow (l, 2.0)) 203 + (t / 24.0 * N * Math.pow (Math.cos (phi), 4.0) * l4coef * Math.pow (l, 4.0)) 204 + (t / 720.0 * N * Math.pow (Math.cos (phi), 6.0) * l6coef * Math.pow (l, 6.0)) 205 + (t / 40320.0 * N * Math.pow (Math.cos (phi), 8.0) * l8coef * Math.pow (l, 8.0))); 206 } 207 208 /* 209 * MapXYToLatLon 210 * 211 * Converts x and y coordinates in the Transverse Mercator projection to 212 * a latitude/longitude pair. Note that Transverse Mercator is not 213 * the same as UTM; a scale factor is required to convert between them. 214 * 215 * Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., 216 * GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. 217 * 218 * Inputs: 219 * x - The easting of the point, in meters. 220 * y - The northing of the point, in meters. 221 * lambda0 - Longitude of the central meridian to be used, in radians. 222 * 223 * Outputs: 224 * philambda - A 2-element containing the latitude and longitude 225 * in radians. 226 * 227 * Returns: 228 * The function does not return a value. 229 * 230 * Remarks: 231 * The local variables Nf, nuf2, tf, and tf2 serve the same purpose as 232 * N, nu2, t, and t2 in MapLatLonToXY, but they are computed with respect 233 * to the footpoint latitude phif. 234 * 235 * x1frac, x2frac, x2poly, x3poly, etc. are to enhance readability and 236 * to optimize computations. 237 * 238 */ 239 public LatLon mapXYToLatLon(double x, double y, double lambda0) 240 { 241 /* Get the value of phif, the footpoint latitude. */ 242 double phif = FootpointLatitude (y); 243 244 /* Precalculate ep2 */ 245 double ep2 = (Math.pow (Ellipsoid.GRS80.a, 2.0) - Math.pow (Ellipsoid.GRS80.b, 2.0)) 246 / Math.pow (Ellipsoid.GRS80.b, 2.0); 247 248 /* Precalculate cos (phif) */ 249 double cf = Math.cos (phif); 250 251 /* Precalculate nuf2 */ 252 double nuf2 = ep2 * Math.pow (cf, 2.0); 253 254 /* Precalculate Nf and initialize Nfpow */ 255 double Nf = Math.pow (Ellipsoid.GRS80.a, 2.0) / (Ellipsoid.GRS80.b * Math.sqrt (1 + nuf2)); 256 double Nfpow = Nf; 257 258 /* Precalculate tf */ 259 double tf = Math.tan (phif); 260 double tf2 = tf * tf; 261 double tf4 = tf2 * tf2; 262 263 /* Precalculate fractional coefficients for x**n in the equations 264 below to simplify the expressions for latitude and longitude. */ 265 double x1frac = 1.0 / (Nfpow * cf); 266 267 Nfpow *= Nf; /* now equals Nf**2) */ 268 double x2frac = tf / (2.0 * Nfpow); 269 270 Nfpow *= Nf; /* now equals Nf**3) */ 271 double x3frac = 1.0 / (6.0 * Nfpow * cf); 272 273 Nfpow *= Nf; /* now equals Nf**4) */ 274 double x4frac = tf / (24.0 * Nfpow); 275 276 Nfpow *= Nf; /* now equals Nf**5) */ 277 double x5frac = 1.0 / (120.0 * Nfpow * cf); 278 279 Nfpow *= Nf; /* now equals Nf**6) */ 280 double x6frac = tf / (720.0 * Nfpow); 281 282 Nfpow *= Nf; /* now equals Nf**7) */ 283 double x7frac = 1.0 / (5040.0 * Nfpow * cf); 284 285 Nfpow *= Nf; /* now equals Nf**8) */ 286 double x8frac = tf / (40320.0 * Nfpow); 287 288 /* Precalculate polynomial coefficients for x**n. 289 -- x**1 does not have a polynomial coefficient. */ 290 double x2poly = -1.0 - nuf2; 291 double x3poly = -1.0 - 2 * tf2 - nuf2; 292 double x4poly = 5.0 + 3.0 * tf2 + 6.0 * nuf2 - 6.0 * tf2 * nuf2 - 3.0 * (nuf2 *nuf2) - 9.0 * tf2 * (nuf2 * nuf2); 293 double x5poly = 5.0 + 28.0 * tf2 + 24.0 * tf4 + 6.0 * nuf2 + 8.0 * tf2 * nuf2; 294 double x6poly = -61.0 - 90.0 * tf2 - 45.0 * tf4 - 107.0 * nuf2 + 162.0 * tf2 * nuf2; 295 double x7poly = -61.0 - 662.0 * tf2 - 1320.0 * tf4 - 720.0 * (tf4 * tf2); 296 double x8poly = 1385.0 + 3633.0 * tf2 + 4095.0 * tf4 + 1575 * (tf4 * tf2); 297 298 return new LatLon( 299 /* Calculate latitude */ 300 Math.toDegrees( 301 phif + x2frac * x2poly * (x * x) 302 + x4frac * x4poly * Math.pow (x, 4.0) 303 + x6frac * x6poly * Math.pow (x, 6.0) 304 + x8frac * x8poly * Math.pow (x, 8.0)), 305 Math.toDegrees( 306 /* Calculate longitude */ 307 lambda0 + x1frac * x 308 + x3frac * x3poly * Math.pow (x, 3.0) 309 + x5frac * x5poly * Math.pow (x, 5.0) 310 + x7frac * x7poly * Math.pow (x, 7.0))); 311 } 312 313 @Override 314 public EastNorth latlon2eastNorth(LatLon p) { 315 EastNorth a = mapLatLonToXY(Math.toRadians(p.lat()), Math.toRadians(p.lon()), UTMCentralMeridianRad); 316 return new EastNorth(a.east() * UTMScaleFactor + offsetEastMeters, a.north() * UTMScaleFactor + offsetNorthMeters); 317 } 318 319 @Override 320 public LatLon eastNorth2latlon(EastNorth p) { 321 return mapXYToLatLon((p.east() - offsetEastMeters)/UTMScaleFactor, (p.north() - offsetNorthMeters)/UTMScaleFactor, UTMCentralMeridianRad); 322 } 323 324 @Override 325 public double getDefaultZoomInPPD() { 326 // this will set the map scaler to about 1000 m 327 return 10; 328 } 329 } -
src/org/openstreetmap/josm/data/projection/TransverseMercatorLV.java
1 // License: GPL. For details, see LICENSE file. 2 package org.openstreetmap.josm.data.projection; 3 4 /** 5 * LKS-92/ Latvia TM projection. Based on data from spatialreference.org. 6 * http://spatialreference.org/ref/epsg/3059/ 7 * 8 * @author Viesturs Zarins 9 */ 10 import static org.openstreetmap.josm.tools.I18n.tr; 11 12 import org.openstreetmap.josm.data.Bounds; 13 import org.openstreetmap.josm.data.coor.LatLon; 14 15 public class TransverseMercatorLV extends TransverseMercator { 16 17 public TransverseMercatorLV() 18 { 19 setProjectionParameters(24, 500000, -6000000); 20 } 21 22 @Override public String toString() { 23 return tr("LKS-92/ Latvia TM"); 24 } 25 26 private int epsgCode() { 27 return 3059; 28 } 29 30 @Override 31 public String toCode() { 32 return "EPSG:"+ epsgCode(); 33 } 34 35 @Override 36 public int hashCode() { 37 return toCode().hashCode(); 38 } 39 40 public String getCacheDirectoryName() { 41 return "epsg"+ epsgCode(); 42 } 43 44 45 @Override 46 public Bounds getWorldBoundsLatLon() { 47 return new Bounds( 48 new LatLon(-90.0, -180.0), 49 new LatLon(90.0, 180.0)); 50 } 51 52 } -
src/org/openstreetmap/josm/data/projection/UTM.java
15 15 import javax.swing.JRadioButton; 16 16 17 17 import org.openstreetmap.josm.data.Bounds; 18 import org.openstreetmap.josm.data.coor.EastNorth;19 18 import org.openstreetmap.josm.data.coor.LatLon; 20 19 import org.openstreetmap.josm.tools.GBC; 21 20 22 21 /** 23 * Directly use latitude / longitude values as x/y.24 22 * 25 23 * @author Dirk Stöcker 26 24 * code based on JavaScript from Chuck Taylor 27 25 */ 28 public class UTM implements Projection,ProjectionSubPrefs {26 public class UTM extends TransverseMercator implements ProjectionSubPrefs { 29 27 30 28 private static final int DEFAULT_ZONE = 30; 31 29 private int zone = DEFAULT_ZONE; … … 36 34 37 35 private boolean offset = false; 38 36 39 private final static double UTMScaleFactor = 0.9996; 40 41 /* Ellipsoid model constants (WGS84) - TODO Use Elliposid class here too */ 42 //final private double sm_EccSquared = 6.69437999013e-03; 43 44 /* 45 * ArcLengthOfMeridian 46 * 47 * Computes the ellipsoidal distance from the equator to a point at a 48 * given latitude. 49 * 50 * Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J., 51 * GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994. 52 * 53 * Inputs: 54 * phi - Latitude of the point, in radians. 55 * 56 * Globals: 57 * Ellipsoid.GRS80.a - Ellipsoid model major axis. 58 * Ellipsoid.GRS80.b - Ellipsoid model minor axis. 59 * 60 * Returns: 61 * The ellipsoidal distance of the point from the equator, in meters. 62 * 63 */ 64 private double ArcLengthOfMeridian(double phi) 37 public UTM() 65 38 { 66 /* Precalculate n */ 67 double n = (Ellipsoid.GRS80.a - Ellipsoid.GRS80.b) / (Ellipsoid.GRS80.a + Ellipsoid.GRS80.b); 68 69 /* Precalculate alpha */ 70 double alpha = ((Ellipsoid.GRS80.a + Ellipsoid.GRS80.b) / 2.0) 71 * (1.0 + (Math.pow (n, 2.0) / 4.0) + (Math.pow (n, 4.0) / 64.0)); 72 73 /* Precalculate beta */ 74 double beta = (-3.0 * n / 2.0) + (9.0 * Math.pow (n, 3.0) / 16.0) 75 + (-3.0 * Math.pow (n, 5.0) / 32.0); 76 77 /* Precalculate gamma */ 78 double gamma = (15.0 * Math.pow (n, 2.0) / 16.0) 79 + (-15.0 * Math.pow (n, 4.0) / 32.0); 80 81 /* Precalculate delta */ 82 double delta = (-35.0 * Math.pow (n, 3.0) / 48.0) 83 + (105.0 * Math.pow (n, 5.0) / 256.0); 84 85 /* Precalculate epsilon */ 86 double epsilon = (315.0 * Math.pow (n, 4.0) / 512.0); 87 88 /* Now calculate the sum of the series and return */ 89 return alpha 90 * (phi + (beta * Math.sin (2.0 * phi)) 91 + (gamma * Math.sin (4.0 * phi)) 92 + (delta * Math.sin (6.0 * phi)) 93 + (epsilon * Math.sin (8.0 * phi))); 39 updateParameters(); 94 40 } 95 41 42 96 43 /* 97 44 * UTMCentralMeridian 98 45 * … … 107 54 * Range of the central meridian is the radian equivalent of [-177,+177]. 108 55 * 109 56 */ 110 private double UTMCentralMeridian(int zone)111 {112 return Math.toRadians(-183.0 + (zone * 6.0));113 }114 57 private double UTMCentralMeridianDeg(int zone) 115 58 { 116 59 return -183.0 + (zone * 6.0); 117 60 } 118 61 119 /*120 * FootpointLatitude121 *122 * Computes the footpoint latitude for use in converting transverse123 * Mercator coordinates to ellipsoidal coordinates.124 *125 * Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,126 * GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.127 *128 * Inputs:129 * y - The UTM northing coordinate, in meters.130 *131 * Returns:132 * The footpoint latitude, in radians.133 *134 */135 private double FootpointLatitude(double y)136 {137 /* Precalculate n (Eq. 10.18) */138 double n = (Ellipsoid.GRS80.a - Ellipsoid.GRS80.b) / (Ellipsoid.GRS80.a + Ellipsoid.GRS80.b);139 140 /* Precalculate alpha_ (Eq. 10.22) */141 /* (Same as alpha in Eq. 10.17) */142 double alpha_ = ((Ellipsoid.GRS80.a + Ellipsoid.GRS80.b) / 2.0)143 * (1 + (Math.pow (n, 2.0) / 4) + (Math.pow (n, 4.0) / 64));144 145 /* Precalculate y_ (Eq. 10.23) */146 double y_ = y / alpha_;147 148 /* Precalculate beta_ (Eq. 10.22) */149 double beta_ = (3.0 * n / 2.0) + (-27.0 * Math.pow (n, 3.0) / 32.0)150 + (269.0 * Math.pow (n, 5.0) / 512.0);151 152 /* Precalculate gamma_ (Eq. 10.22) */153 double gamma_ = (21.0 * Math.pow (n, 2.0) / 16.0)154 + (-55.0 * Math.pow (n, 4.0) / 32.0);155 156 /* Precalculate delta_ (Eq. 10.22) */157 double delta_ = (151.0 * Math.pow (n, 3.0) / 96.0)158 + (-417.0 * Math.pow (n, 5.0) / 128.0);159 160 /* Precalculate epsilon_ (Eq. 10.22) */161 double epsilon_ = (1097.0 * Math.pow (n, 4.0) / 512.0);162 163 /* Now calculate the sum of the series (Eq. 10.21) */164 return y_ + (beta_ * Math.sin (2.0 * y_))165 + (gamma_ * Math.sin (4.0 * y_))166 + (delta_ * Math.sin (6.0 * y_))167 + (epsilon_ * Math.sin (8.0 * y_));168 }169 170 /*171 * MapLatLonToXY172 *173 * Converts a latitude/longitude pair to x and y coordinates in the174 * Transverse Mercator projection. Note that Transverse Mercator is not175 * the same as UTM; a scale factor is required to convert between them.176 *177 * Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,178 * GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.179 *180 * Inputs:181 * phi - Latitude of the point, in radians.182 * lambda - Longitude of the point, in radians.183 * lambda0 - Longitude of the central meridian to be used, in radians.184 *185 * Outputs:186 * xy - A 2-element array containing the x and y coordinates187 * of the computed point.188 *189 * Returns:190 * The function does not return a value.191 *192 */193 public EastNorth mapLatLonToXY(double phi, double lambda, double lambda0)194 {195 /* Precalculate ep2 */196 double ep2 = (Math.pow (Ellipsoid.GRS80.a, 2.0) - Math.pow (Ellipsoid.GRS80.b, 2.0)) / Math.pow (Ellipsoid.GRS80.b, 2.0);197 198 /* Precalculate nu2 */199 double nu2 = ep2 * Math.pow (Math.cos (phi), 2.0);200 201 /* Precalculate N */202 double N = Math.pow (Ellipsoid.GRS80.a, 2.0) / (Ellipsoid.GRS80.b * Math.sqrt (1 + nu2));203 204 /* Precalculate t */205 double t = Math.tan (phi);206 double t2 = t * t;207 208 /* Precalculate l */209 double l = lambda - lambda0;210 211 /* Precalculate coefficients for l**n in the equations below212 so a normal human being can read the expressions for easting213 and northing214 -- l**1 and l**2 have coefficients of 1.0 */215 double l3coef = 1.0 - t2 + nu2;216 217 double l4coef = 5.0 - t2 + 9 * nu2 + 4.0 * (nu2 * nu2);218 219 double l5coef = 5.0 - 18.0 * t2 + (t2 * t2) + 14.0 * nu2220 - 58.0 * t2 * nu2;221 222 double l6coef = 61.0 - 58.0 * t2 + (t2 * t2) + 270.0 * nu2223 - 330.0 * t2 * nu2;224 225 double l7coef = 61.0 - 479.0 * t2 + 179.0 * (t2 * t2) - (t2 * t2 * t2);226 227 double l8coef = 1385.0 - 3111.0 * t2 + 543.0 * (t2 * t2) - (t2 * t2 * t2);228 229 return new EastNorth(230 /* Calculate easting (x) */231 N * Math.cos (phi) * l232 + (N / 6.0 * Math.pow (Math.cos (phi), 3.0) * l3coef * Math.pow (l, 3.0))233 + (N / 120.0 * Math.pow (Math.cos (phi), 5.0) * l5coef * Math.pow (l, 5.0))234 + (N / 5040.0 * Math.pow (Math.cos (phi), 7.0) * l7coef * Math.pow (l, 7.0)),235 /* Calculate northing (y) */236 ArcLengthOfMeridian (phi)237 + (t / 2.0 * N * Math.pow (Math.cos (phi), 2.0) * Math.pow (l, 2.0))238 + (t / 24.0 * N * Math.pow (Math.cos (phi), 4.0) * l4coef * Math.pow (l, 4.0))239 + (t / 720.0 * N * Math.pow (Math.cos (phi), 6.0) * l6coef * Math.pow (l, 6.0))240 + (t / 40320.0 * N * Math.pow (Math.cos (phi), 8.0) * l8coef * Math.pow (l, 8.0)));241 }242 243 /*244 * MapXYToLatLon245 *246 * Converts x and y coordinates in the Transverse Mercator projection to247 * a latitude/longitude pair. Note that Transverse Mercator is not248 * the same as UTM; a scale factor is required to convert between them.249 *250 * Reference: Hoffmann-Wellenhof, B., Lichtenegger, H., and Collins, J.,251 * GPS: Theory and Practice, 3rd ed. New York: Springer-Verlag Wien, 1994.252 *253 * Inputs:254 * x - The easting of the point, in meters.255 * y - The northing of the point, in meters.256 * lambda0 - Longitude of the central meridian to be used, in radians.257 *258 * Outputs:259 * philambda - A 2-element containing the latitude and longitude260 * in radians.261 *262 * Returns:263 * The function does not return a value.264 *265 * Remarks:266 * The local variables Nf, nuf2, tf, and tf2 serve the same purpose as267 * N, nu2, t, and t2 in MapLatLonToXY, but they are computed with respect268 * to the footpoint latitude phif.269 *270 * x1frac, x2frac, x2poly, x3poly, etc. are to enhance readability and271 * to optimize computations.272 *273 */274 public LatLon mapXYToLatLon(double x, double y, double lambda0)275 {276 /* Get the value of phif, the footpoint latitude. */277 double phif = FootpointLatitude (y);278 279 /* Precalculate ep2 */280 double ep2 = (Math.pow (Ellipsoid.GRS80.a, 2.0) - Math.pow (Ellipsoid.GRS80.b, 2.0))281 / Math.pow (Ellipsoid.GRS80.b, 2.0);282 283 /* Precalculate cos (phif) */284 double cf = Math.cos (phif);285 286 /* Precalculate nuf2 */287 double nuf2 = ep2 * Math.pow (cf, 2.0);288 289 /* Precalculate Nf and initialize Nfpow */290 double Nf = Math.pow (Ellipsoid.GRS80.a, 2.0) / (Ellipsoid.GRS80.b * Math.sqrt (1 + nuf2));291 double Nfpow = Nf;292 293 /* Precalculate tf */294 double tf = Math.tan (phif);295 double tf2 = tf * tf;296 double tf4 = tf2 * tf2;297 298 /* Precalculate fractional coefficients for x**n in the equations299 below to simplify the expressions for latitude and longitude. */300 double x1frac = 1.0 / (Nfpow * cf);301 302 Nfpow *= Nf; /* now equals Nf**2) */303 double x2frac = tf / (2.0 * Nfpow);304 305 Nfpow *= Nf; /* now equals Nf**3) */306 double x3frac = 1.0 / (6.0 * Nfpow * cf);307 308 Nfpow *= Nf; /* now equals Nf**4) */309 double x4frac = tf / (24.0 * Nfpow);310 311 Nfpow *= Nf; /* now equals Nf**5) */312 double x5frac = 1.0 / (120.0 * Nfpow * cf);313 314 Nfpow *= Nf; /* now equals Nf**6) */315 double x6frac = tf / (720.0 * Nfpow);316 317 Nfpow *= Nf; /* now equals Nf**7) */318 double x7frac = 1.0 / (5040.0 * Nfpow * cf);319 320 Nfpow *= Nf; /* now equals Nf**8) */321 double x8frac = tf / (40320.0 * Nfpow);322 323 /* Precalculate polynomial coefficients for x**n.324 -- x**1 does not have a polynomial coefficient. */325 double x2poly = -1.0 - nuf2;326 double x3poly = -1.0 - 2 * tf2 - nuf2;327 double x4poly = 5.0 + 3.0 * tf2 + 6.0 * nuf2 - 6.0 * tf2 * nuf2 - 3.0 * (nuf2 *nuf2) - 9.0 * tf2 * (nuf2 * nuf2);328 double x5poly = 5.0 + 28.0 * tf2 + 24.0 * tf4 + 6.0 * nuf2 + 8.0 * tf2 * nuf2;329 double x6poly = -61.0 - 90.0 * tf2 - 45.0 * tf4 - 107.0 * nuf2 + 162.0 * tf2 * nuf2;330 double x7poly = -61.0 - 662.0 * tf2 - 1320.0 * tf4 - 720.0 * (tf4 * tf2);331 double x8poly = 1385.0 + 3633.0 * tf2 + 4095.0 * tf4 + 1575 * (tf4 * tf2);332 333 return new LatLon(334 /* Calculate latitude */335 Math.toDegrees(336 phif + x2frac * x2poly * (x * x)337 + x4frac * x4poly * Math.pow (x, 4.0)338 + x6frac * x6poly * Math.pow (x, 6.0)339 + x8frac * x8poly * Math.pow (x, 8.0)),340 Math.toDegrees(341 /* Calculate longitude */342 lambda0 + x1frac * x343 + x3frac * x3poly * Math.pow (x, 3.0)344 + x5frac * x5poly * Math.pow (x, 5.0)345 + x7frac * x7poly * Math.pow (x, 7.0)));346 }347 348 public EastNorth latlon2eastNorth(LatLon p) {349 EastNorth a = mapLatLonToXY(Math.toRadians(p.lat()), Math.toRadians(p.lon()), UTMCentralMeridian(getzone()));350 return new EastNorth(a.east() * UTMScaleFactor + getEastOffset(), a.north() * UTMScaleFactor + getNorthOffset());351 }352 353 public LatLon eastNorth2latlon(EastNorth p) {354 return mapXYToLatLon((p.east()-getEastOffset())/UTMScaleFactor, (p.north()-getNorthOffset())/UTMScaleFactor, UTMCentralMeridian(getzone()));355 }356 357 62 @Override public String toString() { 358 63 return tr("UTM"); 359 64 } 360 65 66 private void updateParameters() { 67 setProjectionParameters(this.UTMCentralMeridianDeg(getzone()), getEastOffset(), getNorthOffset()); 68 } 69 361 70 public int getzone() 362 71 { 363 72 return zone; … … 403 112 new LatLon(5.0, UTMCentralMeridianDeg(getzone())+5.0)); 404 113 } 405 114 406 public double getDefaultZoomInPPD() {407 // this will set the map scaler to about 1000 m408 return 10;409 }410 411 115 public void setupPreferencePanel(JPanel p) { 412 116 //Zone 413 117 JComboBox zonecb = new JComboBox(); … … 509 213 offset = array[2].equals("offset"); 510 214 } 511 215 } 216 217 updateParameters(); 512 218 } 513 219 220 221 514 222 public Collection<String> getPreferencesFromCode(String code) 515 223 { 516 224 boolean offset = code.startsWith("EPSG:3258") || code.startsWith("EPSG:3259");
