Changeset d0fc203 in tol
- Timestamp:
- Jan 2, 2010, 12:31:12 PM (17 years ago)
- Branches:
- 1941-docker-image-to-test, devel, master
- Children:
- a8dd8b9
- Parents:
- 59e155b
- File:
-
- 1 edited
-
tol_pkg/GisTools/GisTools.tol (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
tol_pkg/GisTools/GisTools.tol
r59e155b rd0fc203 18 18 Set _.autodoc.authors = [[ 19 19 "vdebuen@tol-project.org" ]]; 20 21 22 23 ////////////////////////////////////////////////////////////////////////////// 24 //Abstract class to handle with Universal Transverse Mercator System 25 //http://www.uwgb.edu/dutchs/UsefulData/UTMFormulas.HTM 26 Class @UTMFormula 27 ////////////////////////////////////////////////////////////////////////////// 28 { 29 //Convertingfactor from decimal degrees to radians 30 Static Real deg2rad = Pi/180; 31 32 //////////////////////////////////////////////////////////////////////////// 33 //UTM Datum defining 34 //////////////////////////////////////////////////////////////////////////// 35 //Datum name 36 Text _.name; 37 //Equatorial Radius, meters 38 Real _.a; 39 //Polar Radius, meters 40 Real _.b; 41 //Geographic zone of application 42 Text _.use; 43 44 //scale along central meridian of zone. Even though itŽs a constant, 45 //we retain it as a separate symbol to keep the numerical 46 //coefficients simpler, also to allow for systems that might use 47 //a different Mercator projection. 48 Real _.k0 = 0.9996; 49 //eccentricity of the earthŽs elliptical cross-section. 50 Real _.e = ?; 51 //auxiliar transformed eccentricity. 52 Real _.e.2 = ?; 53 Real _.e_1 = ?; 54 //auxiliar ratio of difference and sum of elliptic radius 55 Real _.n = ?; 56 //auxiliar variables used to calculate Meridional Arc 57 Real _.A = ?; 58 Real _.B = ?; 59 Real _.C = ?; 60 Real _.D = ?; 61 Real _.E = ?; 62 //auxiliar variables used to calculate Footprint Latitude 63 Real _.J1 = ?; 64 Real _.J2 = ?; 65 Real _.J3 = ?; 66 Real _.J4 = ?; 67 68 //////////////////////////////////////////////////////////////////////////// 69 Real initialice(Real void) 70 //////////////////////////////////////////////////////////////////////////// 71 { 72 Real e2 = 1-(_.b/_.a)^2; 73 Real _.e := Sqrt(e2); 74 Real e4 = _.e^4; 75 Real e6 = _.e^6; 76 Real _.e.2 := e2/(1-e2); 77 Real _.n := (_.a-_.b)/(_.a+_.b); 78 Real _.e_1 := (1-Sqrt((1-e2)))/(1+Sqrt((1-e2))); 79 //Calculating the arc length of an ellipse involves functions called 80 //elliptic integrals, which donŽt reduce to neat closed formulas. 81 //So they have to be represented as series. 82 /* */ 83 //Army form 84 Real n23 = _.n^2-_.n^3; 85 Real n45 = _.n^4-_.n^5; 86 Real _.A := +_.a* (1-_.n + (5/4)*n23 + (81/64)*n45); 87 Real _.B := -_.a*((3/2) *_.n* (1-_.n + (7/8)*n23 + (55/64)*n45)); 88 Real _.C := +_.a*((15/16) *_.n^2* (1-_.n + (3/4)*n23)); 89 Real _.D := -_.a*((35/48) *_.n^3* (1-_.n + (11/16)*n23)); 90 Real _.E := +_.a*((315/512)*_.n^4* (1-_.n)); 91 /* * / 92 //The USGS gives this form, which may be more appealing to some. 93 Real _.A := +_.a*(1- e2/4 -3*e4/64 - 5*e6/256 ); 94 Real _.B := -_.a*( 3*e2/8 +3*e4/32 +45*e6/1024); 95 Real _.C := +_.a*( 15*e4/256 +45*e6/1024); 96 Real _.D := -_.a*( 35*e6/3072); 97 Real _.E := 0; 98 /* */ 99 //Auxiliar variables to calculate Footprint Latitude 100 Real E1 = _.e_1; 101 Real E2 = _.e_1^2; 102 Real E3 = _.e_1^3; 103 Real E4 = _.e_1^4; 104 Real _.J1 := 3*E1/2 - 27*E3/32; 105 Real _.J2 := 21*E2/16 - 55*E4/32; 106 Real _.J3 := 151*E3/96; 107 Real _.J4 := 1097*E4/512; 108 109 True 110 }; 111 //////////////////////////////////////////////////////////////////////////// 112 Static @UTMFormula New(Text name, Real a, Real b, Text use) 113 //////////////////////////////////////////////////////////////////////////// 114 { 115 @UTMFormula aux = [[ 116 Text _.name = name; 117 Text _.use = use; 118 Real _.a = a; 119 Real _.b = b 120 ]]; 121 Real aux::initialice(?); 122 Eval(name+"=aux") 123 }; 124 125 //////////////////////////////////////////////////////////////////////////// 126 Static Set datum = Copy(Empty); 127 Static Real BuildDatum(Real void) 128 //////////////////////////////////////////////////////////////////////////// 129 { 130 Set datum := [[ 131 @UTMFormula::New("NAD83", 6378137, 6356752.3142, "Global"); 132 @UTMFormula::New("WGS84", 6378137, 6356752.3142, "Global"); 133 @UTMFormula::New("GRS80", 6378137, 6356752.3141, "US"); 134 @UTMFormula::New("WGS72", 6378135, 6356750.5, "NASA, DOD"); 135 @UTMFormula::New("Australian.1965", 6378160, 6356774.7, "Australia"); 136 @UTMFormula::New("Krasovsky.1940", 6378245, 6356863.0, "Soviet Union"); 137 @UTMFormula::New("International.1924", 6378388, 6356911.9, "Global except as listed"); 138 @UTMFormula::New("Hayford.1909", 6378388, 6356911.9, "Global except as listed"); 139 @UTMFormula::New("Clake.1880", 6378249.1, 6356514.9, "France, Africa"); 140 @UTMFormula::New("Clarke.1866", 6378206.4, 6356583.8, "North America"); 141 @UTMFormula::New("Airy.1830", 6377563.4, 6356256.9, "Great Britain"); 142 @UTMFormula::New("Bessel.1841", 6377397.2, 6356079.0, "Central Europe, Chile, Indonesia"); 143 @UTMFormula::New("Everest.1830", 6377276.3, 6356075.4, "South Asia") ]]; 144 Real SetIndexByName(datum); 145 True 146 }; 147 148 149 //////////////////////////////////////////////////////////////////////////// 150 Static Text _.autodoc.member.get.zone.deg= "Returns UTM zone of longitude " 151 "in degrees"; 152 Static VMatrix get.zone.deg(Real long) 153 //////////////////////////////////////////////////////////////////////////// 154 { 155 If(long<0,Floor((180+long)/6)+1,Floor(long/6)+31) 156 }; 157 158 //////////////////////////////////////////////////////////////////////////// 159 Static Text _.autodoc.member.get.zone.rad = "Returns UTM zone of longitude " 160 "in radians"; 161 Static VMatrix get.zone.rad(Real long) 162 //////////////////////////////////////////////////////////////////////////// 163 { 164 @UTMFormula::get.zone.deg(long/deg2rad) 165 }; 166 167 //////////////////////////////////////////////////////////////////////////// 168 Static Text _.autodoc.member.get.zoneCentralMeridian.deg= 169 "Returns central meridian of UTM zone for given longitude in degrees"; 170 Static VMatrix get.zoneCentralMeridian.deg(Real long) 171 //////////////////////////////////////////////////////////////////////////// 172 { 173 6*@UTMFormula::get.zone.deg(long)-183 174 }; 175 176 //////////////////////////////////////////////////////////////////////////// 177 Static Text _.autodoc.member.get.zoneCentralMeridian.rad = 178 "Returns entral meridian of UTM zone for given longitude in radians"; 179 Static VMatrix get.zoneCentralMeridian.rad(Real long) 180 //////////////////////////////////////////////////////////////////////////// 181 { 182 @UTMFormula::get.zoneCentralMeridian.deg(long/deg2rad) 183 }; 184 185 //////////////////////////////////////////////////////////////////////////// 186 Static Text _.autodoc.member.rad2utm = "Formulas for converting " 187 "coordinates of latitude and longitude in radians to UTM"; 188 VMatrix rad2utm( 189 VMatrix lonlat, //Matrix with two columns, first one is longitud, second 190 //one is latitude, both meassured in in radians 191 Real zone) //UTM zone 192 //////////////////////////////////////////////////////////////////////////// 193 { 194 //Central meridian of zone 195 Real long0 = (6*zone-183)*deg2rad; 196 //longitude of points 197 VMatrix long = ASin(Sin(SubCol(lonlat,[[1]]))); 198 //latitude of points 199 VMatrix lat = ASin(Sin(SubCol(lonlat,[[2]]))); 200 Real e2 = _.e^2; 201 VMatrix e2sinlat2_1 = -(Sin(lat)^2)*e2+1; 202 //This is the radius of curvature of the earth in the meridian plane. 203 VMatrix rho = (e2sinlat2_1^(-3/2))*(_.a*(1-e2)); 204 //This is the radius of curvature of the earth perpendicular to the 205 //meridian plane. It is also the distance from the point in question 206 //to the polar axis, measured perpendicular to the earthŽs surface. 207 VMatrix nu = (e2sinlat2_1^(-1/2))*_.a; 208 VMatrix p = long-long0; 209 VMatrix k0nu = nu*_.k0; 210 VMatrix sinlat = Sin(lat); 211 VMatrix sin2lat = Sin(lat*2); 212 VMatrix sin4lat = Sin(lat*4); 213 VMatrix sin6lat = Sin(lat*6); 214 VMatrix sin8lat = Sin(lat*8); 215 VMatrix coslat = Cos(lat); 216 VMatrix coslat2 = coslat^2; 217 VMatrix coslat3 = coslat^3; 218 VMatrix coslat4 = coslat^4; 219 VMatrix tanlat = Tan(lat); 220 VMatrix tanlat2 = tanlat^2; 221 VMatrix tanlat3 = tanlat^3; 222 VMatrix S = 223 lat*_.A + 224 sin2lat*_.B + 225 sin4lat*_.C + 226 sin6lat*_.D + 227 sin8lat*_.E; 228 VMatrix K1 = S*_.k0; 229 VMatrix K2 = sin2lat$*k0nu/4; 230 VMatrix K3 = 231 (sinlat$*coslat3$*(k0nu/24))$* 232 (-tanlat2 + coslat2*(9*_.e.2) + coslat4*(4*_.e.2^2) + 5); 233 VMatrix K4 = coslat$*k0nu; 234 VMatrix K5 = (coslat3$*k0nu/6)$* 235 (-tanlat2 + coslat2*_.e.2 +1); 236 //northing of points 237 VMatrix y = (K1 + K2$*p^2 + K3$*p^4); 238 //easting of points 239 VMatrix x = (K4$*p + K5$*p^3)+500000; 240 x|IfVMat(LT(lat,lat*0),y+1.E+7,y) 241 }; 242 243 //////////////////////////////////////////////////////////////////////////// 244 Static Text _.autodoc.member.deg2utm = "Formulas for converting " 245 "coordinates of latitude and longitude in degrees to UTM"; 246 VMatrix deg2utm( 247 VMatrix lonlat, //Matrix with two columns, first one is longitud, second 248 //one is latitude, both meassured in degrees 249 Real zone) //UTM zone 250 //////////////////////////////////////////////////////////////////////////// 251 { 252 rad2utm(lonlat*deg2rad,zone) 253 }; 254 255 //////////////////////////////////////////////////////////////////////////// 256 Static Text _.autodoc.member.utm2rad = "Formulas for converting " 257 "UTM coordinates to latitude and longitude in radians"; 258 VMatrix utm2rad( 259 VMatrix xy, //Matrix with two columns 260 Real zone) //UTM zone 261 //////////////////////////////////////////////////////////////////////////// 262 { 263 //Central meridian of zone 264 Real long0 = (6*zone-183)*deg2rad; 265 //easting of points 266 VMatrix x = SubCol(xy,[[1]])-500000; 267 //northing of points 268 VMatrix y = SubCol(xy,[[2]]); 269 Real e2 = _.e^2; 270 Real e4 = _.e^4; 271 Real e6 = _.e^6; 272 //WriteLn("TRACE x="<<VMat2Mat(x)); 273 //WriteLn("TRACE y="<<VMat2Mat(y)); 274 //Calculate the Meridional Arc 275 VMatrix M = y/_.k0; 276 //WriteLn("TRACE M="<<VMat2Mat(M)); 277 //Calculating Footprint Latitude 278 VMatrix mu = M/(_.a*(1- e2/4 -3*e4/64 - 5*e6/256)); 279 //WriteLn("TRACE mu="<<VMat2Mat(mu)); 280 VMatrix fp = 281 mu + 282 Sin(mu*2)*_.J1 + 283 Sin(mu*4)*_.J2 + 284 Sin(mu*6)*_.J3 + 285 Sin(mu*8)*_.J4; 286 //WriteLn("TRACE fp="<<VMat2Mat(fp)); 287 VMatrix sinfp = Sin(fp); 288 VMatrix cosfp = Cos(fp); 289 VMatrix tanfp = sinfp$/cosfp; 290 VMatrix C1 = (cosfp^2)*_.e.2; 291 //WriteLn("TRACE C1="<<VMat2Mat(C1)); 292 VMatrix T1 = tanfp^2; 293 //WriteLn("TRACE T1="<<VMat2Mat(T1)); 294 VMatrix sinfp2e21 = -(sinfp^2)*_.e^2+1; 295 VMatrix R1 = sinfp2e21^(-3/2)*(_.a*(1-_.e^2)); 296 //WriteLn("TRACE R1="<<VMat2Mat(R1)); 297 VMatrix N1 = sinfp2e21^(-1/2)*_.a; 298 //WriteLn("TRACE N1="<<VMat2Mat(N1)); 299 VMatrix D = x$/(N1*_.k0); 300 //WriteLn("TRACE D="<<VMat2Mat(D)); 301 VMatrix Q1 = N1$*tanfp$/R1; 302 //WriteLn("TRACE Q1="<<VMat2Mat(Q1)); 303 VMatrix Q2 = (D^2)/2; 304 //WriteLn("TRACE Q2="<<VMat2Mat(Q2)); 305 VMatrix Q3 = (T1* 3 + C1* 10 - C1^2*4 +(5- 9*_.e.2))$*D^4/24; 306 //WriteLn("TRACE Q3="<<VMat2Mat(Q3)); 307 VMatrix Q4 = (T1*90 + C1*298 + T1^2*45 - C1^2*3 +(61-252*_.e.2))$*D^6/720; 308 //WriteLn("TRACE Q4="<<VMat2Mat(Q4)); 309 VMatrix Q5 = D; 310 //WriteLn("TRACE Q5="<<VMat2Mat(Q5)); 311 VMatrix Q6 = (T1*2 + C1 + 1)$*D^3/6; 312 //WriteLn("TRACE Q6="<<VMat2Mat(Q6)); 313 VMatrix Q7 = (T1*28 - C1*2 + T1^2*24 - C1^2*3 +(5 + 8*_.e.2))$*D^5/120; 314 //WriteLn("TRACE Q7="<<VMat2Mat(Q7)); 315 VMatrix lat = fp - Q1$*(Q2 - Q3 + Q4); 316 //WriteLn("TRACE lat="<<VMat2Mat(lat)); 317 VMatrix long = (Q5 - Q6 + Q7)$/cosfp+long0; 318 //WriteLn("TRACE long="<<VMat2Mat(long)); 319 long | lat 320 }; 321 //////////////////////////////////////////////////////////////////////////// 322 Static Text _.autodoc.member.utm2deg = "Formulas for converting " 323 "UTM coordinates to latitude and longitude in degrees"; 324 VMatrix utm2deg( 325 VMatrix xy, //Matrix with two columns 326 Real zone) //UTM zone 327 //////////////////////////////////////////////////////////////////////////// 328 { 329 utm2rad(xy,zone)/deg2rad 330 } 331 }; 332 333 334 Real _UTMFormula.BuildDatum = @UTMFormula::BuildDatum(?); 20 335 21 336 ////////////////////////////////////////////////////////////////////////////// … … 127 442 }; 128 443 444 129 445 ////////////////////////////////////////////////////////////////////////////// 130 446 //Abstract class to inherite bidimensional interpolating classes. … … 162 478 //////////////////////////////////////////////////////////////////////////// 163 479 Static Text _.autodoc.member.eval = 164 "Evaluates the first interpolation function at point x,y. It 's useful in "480 "Evaluates the first interpolation function at point x,y. ItŽs useful in " 165 481 "the scalar case, when _.F has just one column (_.n==1)"; 166 482 Real eval(@Point2D p) … … 326 642 327 643 644
Note: See TracChangeset
for help on using the changeset viewer.
