Changeset 3473 in josm
- Timestamp:
- 2010-08-26T23:56:47+02:00 (14 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/projection/Ellipsoid.java
r3083 r3473 8 8 package org.openstreetmap.josm.data.projection; 9 9 10 import org.openstreetmap.josm.data.coor.LatLon; 11 10 12 /** 11 13 * the reference ellipsoids … … 30 32 */ 31 33 public static final Ellipsoid WGS84 = new Ellipsoid(6378137.0, 6356752.3142); 34 35 /** 36 * Bessel 1841 ellipsoid 37 */ 38 public static final Ellipsoid Bessel1841 = new Ellipsoid(6377397.155, 6356078.962822); 32 39 33 40 /** … … 164 171 return lati1; 165 172 } 173 174 /** 175 * convert cartesian coordinates to ellipsoidal coordinates 176 * 177 * @param XYZ the coordinates in meters (X, Y, Z) 178 * @return The corresponding latitude and longitude in degrees 179 */ 180 public LatLon cart2LatLon(double[] XYZ) { 181 return cart2LatLon(XYZ, 1e-11); 182 } 183 public LatLon cart2LatLon(double[] XYZ, double epsilon) { 184 double norm = Math.sqrt(XYZ[0] * XYZ[0] + XYZ[1] * XYZ[1]); 185 double lg = 2.0 * Math.atan(XYZ[1] / (XYZ[0] + norm)); 186 double lt = Math.atan(XYZ[2] / (norm * (1.0 - (a * e2 / Math.sqrt(XYZ[0] * XYZ[0] + XYZ[1] * XYZ[1] + XYZ[2] * XYZ[2]))))); 187 double delta = 1.0; 188 while (delta > epsilon) { 189 double s2 = Math.sin(lt); 190 s2 *= s2; 191 double l = Math.atan((XYZ[2] / norm) 192 / (1.0 - (a * e2 * Math.cos(lt) / (norm * Math.sqrt(1.0 - e2 * s2))))); 193 delta = Math.abs(l - lt); 194 lt = l; 195 } 196 return new LatLon(Math.toDegrees(lt), Math.toDegrees(lg)); 197 } 198 199 /** 200 * convert ellipsoidal coordinates to cartesian coordinates 201 * 202 * @param coord The Latitude and longitude in degrees 203 * @return the corresponding (X, Y Z) cartesian coordinates in meters. 204 */ 205 public double[] latLon2Cart(LatLon coord) { 206 double phi = Math.toRadians(coord.lat()); 207 double lambda = Math.toRadians(coord.lon()); 208 209 double Rn = a / Math.sqrt(1 - e2 * Math.pow(Math.sin(phi), 2)); 210 double[] XYZ = new double[3]; 211 XYZ[0] = Rn * Math.cos(phi) * Math.cos(lambda); 212 XYZ[1] = Rn * Math.cos(phi) * Math.sin(lambda); 213 XYZ[2] = Rn * (1 - e2) * Math.sin(phi); 214 215 return XYZ; 216 } 166 217 } -
trunk/src/org/openstreetmap/josm/data/projection/SwissGrid.java
r3083 r3473 1 1 //License: GPL. For details, see LICENSE file. 2 3 2 package org.openstreetmap.josm.data.projection; 4 3 5 4 import static org.openstreetmap.josm.tools.I18n.tr; 6 5 6 import java.util.Collection; 7 import java.util.Collections; 8 import javax.swing.Box; 9 import javax.swing.JPanel; 10 7 11 import org.openstreetmap.josm.data.Bounds; 8 12 import org.openstreetmap.josm.data.coor.EastNorth; 9 13 import org.openstreetmap.josm.data.coor.LatLon; 14 import org.openstreetmap.josm.gui.widgets.HtmlPanel; 15 import org.openstreetmap.josm.tools.GBC; 10 16 11 17 /** 12 * Projection for the SwissGrid , see http://de.wikipedia.org/wiki/Swiss_Grid.18 * Projection for the SwissGrid CH1903 / L03, see http://de.wikipedia.org/wiki/Swiss_Grid. 13 19 * 14 20 * Calculations are based on formula from 15 21 * http://www.swisstopo.admin.ch/internet/swisstopo/en/home/topics/survey/sys/refsys/switzerland.parsysrelated1.37696.downloadList.12749.DownloadFile.tmp/ch1903wgs84en.pdf 16 22 * 23 * August 2010 update to this formula (rigorous formulas) 24 * http://www.swisstopo.admin.ch/internet/swisstopo/en/home/topics/survey/sys/refsys/switzerland.parsysrelated1.37696.downloadList.97912.DownloadFile.tmp/swissprojectionen.pdf 17 25 */ 18 public class SwissGrid implements Projection { 26 public class SwissGrid implements Projection, ProjectionSubPrefs { 27 28 private static final double dX = 674.374; 29 private static final double dY = 15.056; 30 private static final double dZ = 405.346; 31 32 private static final double phi0 = Math.toRadians(46.0 + 57.0 / 60 + 8.66 / 3600); 33 private static final double lambda0 = Math.toRadians(7.0 + 26.0 / 60 + 22.50 / 3600); 34 private static final double R = Ellipsoid.Bessel1841.a * Math.sqrt(1 - Ellipsoid.Bessel1841.e2) / (1 - (Ellipsoid.Bessel1841.e2 * Math.pow(Math.sin(phi0), 2))); 35 private static final double alpha = Math.sqrt(1 + (Ellipsoid.Bessel1841.eb2 * Math.pow(Math.cos(phi0), 4))); 36 private static final double b0 = Math.asin(Math.sin(phi0) / alpha); 37 private static final double K = Math.log(Math.tan(Math.PI / 4 + b0 / 2)) - alpha 38 * Math.log(Math.tan(Math.PI / 4 + phi0 / 2)) + alpha * Ellipsoid.Bessel1841.e / 2 39 * Math.log((1 + Ellipsoid.Bessel1841.e * Math.sin(phi0)) / (1 - Ellipsoid.Bessel1841.e * Math.sin(phi0))); 40 41 private static final double xTrans = 200000; 42 private static final double yTrans = 600000; 43 44 private static final double DELTA_PHI = 1e-11; 45 46 private LatLon correctEllipoideGSR80toBressel1841(LatLon coord) { 47 double[] XYZ = Ellipsoid.WGS84.latLon2Cart(coord); 48 XYZ[0] -= dX; 49 XYZ[1] -= dY; 50 XYZ[2] -= dZ; 51 return Ellipsoid.Bessel1841.cart2LatLon(XYZ); 52 } 53 54 private LatLon correctEllipoideBressel1841toGRS80(LatLon coord) { 55 double[] XYZ = Ellipsoid.Bessel1841.latLon2Cart(coord); 56 XYZ[0] += dX; 57 XYZ[1] += dY; 58 XYZ[2] += dZ; 59 return Ellipsoid.WGS84.cart2LatLon(XYZ); 60 } 61 19 62 /** 20 63 * @param wgs WGS84 lat/lon (ellipsoid GRS80) (in degree) 21 64 * @return eastnorth projection in Swiss National Grid (ellipsoid Bessel) 22 65 */ 66 @Override 23 67 public EastNorth latlon2eastNorth(LatLon wgs) { 24 double phi = 3600d * wgs.lat(); 25 double lambda = 3600d * wgs.lon(); 68 LatLon coord = correctEllipoideGSR80toBressel1841(wgs); 69 double phi = Math.toRadians(coord.lat()); 70 double lambda = Math.toRadians(coord.lon()); 26 71 27 double phiprime = (phi - 169028.66d) / 10000d; 28 double lambdaprime = (lambda - 26782.5d) / 10000d; 72 double S = alpha * Math.log(Math.tan(Math.PI / 4 + phi / 2)) - alpha * Ellipsoid.Bessel1841.e / 2 73 * Math.log((1 + Ellipsoid.Bessel1841.e * Math.sin(phi)) / (1 - Ellipsoid.Bessel1841.e * Math.sin(phi))) + K; 74 double b = 2 * (Math.atan(Math.exp(S)) - Math.PI / 4); 75 double l = alpha * (lambda - lambda0); 29 76 30 // precompute squares for lambdaprime and phiprime 31 // 32 double lambdaprime_2 = Math.pow(lambdaprime,2); 33 double phiprime_2 = Math.pow(phiprime,2); 77 double lb = Math.atan2(Math.sin(l), Math.sin(b0) * Math.tan(b) + Math.cos(b0) * Math.cos(l)); 78 double bb = Math.asin(Math.cos(b0) * Math.sin(b) - Math.sin(b0) * Math.cos(b) * Math.cos(l)); 34 79 35 double north = 36 200147.07d 37 + 308807.95d * phiprime 38 + 3745.25d * lambdaprime_2 39 + 76.63d * phiprime_2 40 - 194.56d * lambdaprime_2 * phiprime 41 + 119.79d * Math.pow(phiprime,3); 80 double y = R * lb; 81 double x = R / 2 * Math.log((1 + Math.sin(bb)) / (1 - Math.sin(bb))); 42 82 43 double east = 44 600072.37d 45 + 211455.93d * lambdaprime 46 - 10938.51d * lambdaprime * phiprime 47 - 0.36d * lambdaprime * phiprime_2 48 - 44.54d * Math.pow(lambdaprime,3); 49 50 return new EastNorth(east, north); 83 return new EastNorth(y + yTrans, x + xTrans); 51 84 } 52 85 … … 55 88 * @return LatLon WGS84 (in degree) 56 89 */ 90 @Override 91 public LatLon eastNorth2latlon(EastNorth xy) { 92 double x = xy.north() - xTrans; 93 double y = xy.east() - yTrans; 57 94 58 public LatLon eastNorth2latlon(EastNorth xy) { 59 double yp = (xy.east() - 600000d) / 1000000d; 60 double xp = (xy.north() - 200000d) / 1000000d; 95 double lb = y / R; 96 double bb = 2 * (Math.atan(Math.exp(x / R)) - Math.PI / 4); 61 97 62 // precompute squares of xp and yp 63 // 64 double xp_2 = Math.pow(xp,2); 65 double yp_2 = Math.pow(yp,2); 98 double b = Math.asin(Math.cos(b0) * Math.sin(bb) + Math.sin(b0) * Math.cos(bb) * Math.cos(lb)); 99 double l = Math.atan2(Math.sin(lb), Math.cos(b0) * Math.cos(lb) - Math.sin(b0) * Math.tan(bb)); 66 100 67 // lambda = latitude, phi = longitude 68 double lmbp = 2.6779094d 69 + 4.728982d * yp 70 + 0.791484d * yp * xp 71 + 0.1306d * yp * xp_2 72 - 0.0436d * Math.pow(yp,3); 101 double lambda = lambda0 + l / alpha; 102 double phi = b; 103 double S = 0; 73 104 74 double phip = 16.9023892d 75 + 3.238272d * xp 76 - 0.270978d * yp_2 77 - 0.002528d * xp_2 78 - 0.0447d * yp_2 * xp 79 - 0.0140d * Math.pow(xp,3); 105 double prevPhi = -1000; 106 int iteration = 0; 107 // iteration to finds S and phi 108 while (Math.abs(phi - prevPhi) > DELTA_PHI) { 109 if (++iteration > 30) { 110 throw new RuntimeException("Two many iterations"); 111 } 112 prevPhi = phi; 113 S = 1 / alpha * (Math.log(Math.tan(Math.PI / 4 + b / 2)) - K) + Ellipsoid.Bessel1841.e 114 * Math.log(Math.tan(Math.PI / 4 + Math.asin(Ellipsoid.Bessel1841.e * Math.sin(phi)) / 2)); 115 phi = 2 * Math.atan(Math.exp(S)) - Math.PI / 2; 116 } 80 117 81 double lmb = lmbp * 100.0d / 36.0d; 82 double phi = phip * 100.0d / 36.0d; 83 84 return new LatLon(phi,lmb); 118 LatLon coord = correctEllipoideBressel1841toGRS80(new LatLon(Math.toDegrees(phi), Math.toDegrees(lambda))); 119 return coord; 85 120 } 86 121 87 @Override public String toString() { 122 @Override 123 public String toString() { 88 124 return tr("Swiss Grid (Switzerland)"); 89 125 } 90 126 127 @Override 91 128 public String toCode() { 92 129 return "EPSG:21781"; … … 98 135 } 99 136 137 @Override 100 138 public String getCacheDirectoryName() { 101 139 return "swissgrid"; 102 140 } 103 141 104 public Bounds getWorldBoundsLatLon() 105 { 106 return new Bounds( 107 new LatLon(45.7, 5.7), 108 new LatLon(47.9, 10.6)); 142 @Override 143 public Bounds getWorldBoundsLatLon() { 144 return new Bounds(new LatLon(45.7, 5.7), new LatLon(47.9, 10.6)); 109 145 } 110 146 147 @Override 111 148 public double getDefaultZoomInPPD() { 112 149 // This will set the scale bar to about 100 m 113 150 return 1.01; 114 151 } 152 153 @Override 154 public void setupPreferencePanel(JPanel p) { 155 p.add(new HtmlPanel("<i>CH1903 / LV03 (without local corrections)</i>"), GBC.eol().fill(GBC.HORIZONTAL)); 156 p.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.BOTH)); 157 } 158 159 @Override 160 public void setPreferences(Collection<String> args) { 161 } 162 163 @Override 164 public Collection<String> getPreferences(JPanel p) { 165 return Collections.singletonList("CH1903"); 166 } 167 168 @Override 169 public Collection<String> getPreferencesFromCode(String code) { 170 if ("EPSG:21781".equals(code)) 171 return Collections.singletonList("CH1903"); 172 return null; 173 } 115 174 } -
trunk/src/org/openstreetmap/josm/data/projection/UTM_France_DOM.java
r3343 r3473 348 348 */ 349 349 private LatLon cart2LatLon(double X, double Y, double Z, Ellipsoid ell) { 350 double norm = Math.sqrt(X * X + Y * Y); 351 double lg = 2.0 * Math.atan(Y / (X + norm)); 352 double lt = Math.atan(Z / (norm * (1.0 - (ell.a * ell.e2 / Math.sqrt(X * X + Y * Y + Z * Z))))); 353 double delta = 1.0; 354 while (delta > epsilon) { 355 double s2 = Math.sin(lt); 356 s2 *= s2; 357 double l = Math.atan((Z / norm) 358 / (1.0 - (ell.a * ell.e2 * Math.cos(lt) / (norm * Math.sqrt(1.0 - ell.e2 * s2))))); 359 delta = Math.abs(l - lt); 360 lt = l; 361 } 362 double s2 = Math.sin(lt); 363 s2 *= s2; 364 // h = norm / Math.cos(lt) - ell.a / Math.sqrt(1.0 - ell.e2 * s2); 365 return new LatLon(lt, lg); 350 double[] XYZ = {X, Y, Z}; 351 LatLon coord = ell.cart2LatLon(XYZ, epsilon); 352 return new LatLon(Math.toRadians(coord.lat()), Math.toRadians(coord.lon())); 366 353 } 367 354 -
trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java
r3461 r3473 29 29 import org.openstreetmap.josm.data.projection.ProjectionSubPrefs; 30 30 import org.openstreetmap.josm.gui.NavigatableComponent; 31 import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;32 31 import org.openstreetmap.josm.tools.GBC; 33 32 … … 108 107 * This is the panel holding all projection preferences 109 108 */ 110 private JPanel projPanel = new VerticallyScrollablePanel();109 private JPanel projPanel = new JPanel(new GridBagLayout()); 111 110 112 111 /**
Note:
See TracChangeset
for help on using the changeset viewer.