Changeset 3635 in josm
- Timestamp:
- 2010-10-24T09:34:21+02:00 (14 years ago)
- Location:
- trunk/src/org/openstreetmap/josm/data/projection
- Files:
-
- 2 added
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/projection/Projection.java
r3168 r3635 17 17 */ 18 18 public static Projection[] allProjections = new Projection[]{ 19 // global projections 19 20 new Epsg4326(), 20 21 new Mercator(), 22 new UTM(), 23 // regional - alphabetical order by country name 21 24 new LambertEST(), // Still needs proper default zoom 22 25 new Lambert(), // Still needs proper default zoom 26 new LambertCC9Zones(), // Still needs proper default zoom 27 new UTM_France_DOM(), 28 new TransverseMercatorLV(), 23 29 new Puwg(), 24 30 new SwissGrid(), 25 new UTM(),26 new UTM_France_DOM(),27 new LambertCC9Zones() // Still needs proper default zoom28 31 }; 29 32 -
trunk/src/org/openstreetmap/josm/data/projection/UTM.java
r3477 r3635 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; … … 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) 65 { 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))); 37 public UTM() 38 { 39 updateParameters(); 94 40 } 95 41 … … 108 54 * 109 55 */ 110 private double UTMCentralMeridian(int zone)111 {112 return Math.toRadians(-183.0 + (zone * 6.0));113 }114 56 private double UTMCentralMeridianDeg(int zone) 115 57 { 116 58 return -183.0 + (zone * 6.0); 117 }118 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 59 } 356 60 357 61 @Override public String toString() { 358 62 return tr("UTM"); 63 } 64 65 private void updateParameters() { 66 setProjectionParameters(this.UTMCentralMeridianDeg(getzone()), getEastOffset(), getNorthOffset()); 359 67 } 360 68 … … 402 110 new LatLon(-85.0, UTMCentralMeridianDeg(getzone())-5.0), 403 111 new LatLon(5.0, UTMCentralMeridianDeg(getzone())+5.0)); 404 }405 406 public double getDefaultZoomInPPD() {407 // this will set the map scaler to about 1000 m408 return 10;409 112 } 410 113 … … 510 213 } 511 214 } 215 updateParameters(); 512 216 } 513 217
Note:
See TracChangeset
for help on using the changeset viewer.