Changeset c46a7b2 in tol
- Timestamp:
- Jan 5, 2010, 7:18:01 PM (17 years ago)
- Branches:
- 1941-docker-image-to-test, devel, master
- Children:
- a693055
- Parents:
- 36977fc
- Location:
- tol_pkg/GisTools
- Files:
-
- 4 added
- 1 edited
-
GisTools.tol (modified) (1 diff)
-
Interp2D.tol (added)
-
KML.tol (added)
-
Point2D.tol (added)
-
UTMFormula.tol (added)
Legend:
- Unmodified
- Added
- Removed
-
tol_pkg/GisTools/GisTools.tol
r36977fc rc46a7b2 19 19 "vdebuen@tol-project.org" ]]; 20 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 initialize(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::initialize(?); 122 Eval(name+"=aux") 123 }; 124 125 //////////////////////////////////////////////////////////////////////////// 126 Static Set _datum = Copy(Empty); 127 Static Set Datum(Real void) 128 //////////////////////////////////////////////////////////////////////////// 129 { 130 If(Card(_datum),_datum, { 131 Set _datum := [[ 132 @UTMFormula::New("NAD83", 6378137, 6356752.3142, "Global"); 133 @UTMFormula::New("WGS84", 6378137, 6356752.3142, "Global"); 134 @UTMFormula::New("GRS80", 6378137, 6356752.3141, "US"); 135 @UTMFormula::New("WGS72", 6378135, 6356750.5, "NASA, DOD"); 136 @UTMFormula::New("Australian.1965", 6378160, 6356774.7, "Australia"); 137 @UTMFormula::New("Krasovsky.1940", 6378245, 6356863.0, "Soviet Union"); 138 @UTMFormula::New("International.1924", 6378388, 6356911.9, "Global except as listed"); 139 @UTMFormula::New("Hayford.1909", 6378388, 6356911.9, "Global except as listed"); 140 @UTMFormula::New("Clake.1880", 6378249.1, 6356514.9, "France, Africa"); 141 @UTMFormula::New("Clarke.1866", 6378206.4, 6356583.8, "North America"); 142 @UTMFormula::New("Airy.1830", 6377563.4, 6356256.9, "Great Britain"); 143 @UTMFormula::New("Bessel.1841", 6377397.2, 6356079.0, "Central Europe, Chile, Indonesia"); 144 @UTMFormula::New("Everest.1830", 6377276.3, 6356075.4, "South Asia") ]]; 145 Real SetIndexByName(_datum); 146 _datum}) 147 }; 148 149 //////////////////////////////////////////////////////////////////////////// 150 Static @UTMFormula GetDatum(Text name) 151 //////////////////////////////////////////////////////////////////////////// 152 { 153 Set dtm = Datum(0); 154 dtm[name] 155 }; 156 157 //////////////////////////////////////////////////////////////////////////// 158 Static Text _.autodoc.member.get.zone.deg= "Returns UTM zone of longitude " 159 "in degrees"; 160 Static VMatrix get.zone.deg(Real long) 161 //////////////////////////////////////////////////////////////////////////// 162 { 163 If(long<0,Floor((180+long)/6)+1,Floor(long/6)+31) 164 }; 165 166 //////////////////////////////////////////////////////////////////////////// 167 Static Text _.autodoc.member.get.zone.rad = "Returns UTM zone of longitude " 168 "in radians"; 169 Static VMatrix get.zone.rad(Real long) 170 //////////////////////////////////////////////////////////////////////////// 171 { 172 @UTMFormula::get.zone.deg(long/deg2rad) 173 }; 174 175 //////////////////////////////////////////////////////////////////////////// 176 Static Text _.autodoc.member.get.zoneCentralMeridian.deg= 177 "Returns central meridian of UTM zone for given longitude in degrees"; 178 Static VMatrix get.zoneCentralMeridian.deg(Real long) 179 //////////////////////////////////////////////////////////////////////////// 180 { 181 6*@UTMFormula::get.zone.deg(long)-183 182 }; 183 184 //////////////////////////////////////////////////////////////////////////// 185 Static Text _.autodoc.member.get.zoneCentralMeridian.rad = 186 "Returns entral meridian of UTM zone for given longitude in radians"; 187 Static VMatrix get.zoneCentralMeridian.rad(Real long) 188 //////////////////////////////////////////////////////////////////////////// 189 { 190 @UTMFormula::get.zoneCentralMeridian.deg(long/deg2rad) 191 }; 192 193 //////////////////////////////////////////////////////////////////////////// 194 Static Text _.autodoc.member.rad2utm = "Formulas for converting " 195 "coordinates of latitude and longitude in radians to UTM"; 196 VMatrix rad2utm( 197 VMatrix lonlat, //Matrix with two columns, first one is longitud, second 198 //one is latitude, both meassured in in radians 199 VMatrix lonZone) //UTM longitud zone 200 //////////////////////////////////////////////////////////////////////////// 201 { 202 //Central meridian of zone 203 VMatrix long0 = (lonZone*6-183)*deg2rad; 204 //longitude of points 205 VMatrix long = SubCol(lonlat,[[1]]); 206 //latitude of points 207 VMatrix lat = SubCol(lonlat,[[2]]); 208 Real e2 = _.e^2; 209 VMatrix e2sinlat2_1 = -(Sin(lat)^2)*e2+1; 210 //This is the radius of curvature of the earth in the meridian plane. 211 VMatrix rho = (e2sinlat2_1^(-3/2))*(_.a*(1-e2)); 212 //This is the radius of curvature of the earth perpendicular to the 213 //meridian plane. It is also the distance from the point in question 214 //to the polar axis, measured perpendicular to the earthŽs surface. 215 VMatrix nu = (e2sinlat2_1^(-1/2))*_.a; 216 VMatrix p = long-long0; 217 VMatrix k0nu = nu*_.k0; 218 VMatrix sinlat = Sin(lat); 219 VMatrix sin2lat = Sin(lat*2); 220 VMatrix sin4lat = Sin(lat*4); 221 VMatrix sin6lat = Sin(lat*6); 222 VMatrix sin8lat = Sin(lat*8); 223 VMatrix coslat = Cos(lat); 224 VMatrix coslat2 = coslat^2; 225 VMatrix coslat3 = coslat^3; 226 VMatrix coslat4 = coslat^4; 227 VMatrix tanlat = Tan(lat); 228 VMatrix tanlat2 = tanlat^2; 229 VMatrix tanlat3 = tanlat^3; 230 VMatrix S = 231 lat*_.A + 232 sin2lat*_.B + 233 sin4lat*_.C + 234 sin6lat*_.D + 235 sin8lat*_.E; 236 VMatrix K1 = S*_.k0; 237 VMatrix K2 = sin2lat$*k0nu/4; 238 VMatrix K3 = 239 (sinlat$*coslat3$*(k0nu/24))$* 240 (-tanlat2 + coslat2*(9*_.e.2) + coslat4*(4*_.e.2^2) + 5); 241 VMatrix K4 = coslat$*k0nu; 242 VMatrix K5 = (coslat3$*k0nu/6)$* 243 (-tanlat2 + coslat2*_.e.2 +1); 244 //northing of points 245 VMatrix y = (K1 + K2$*p^2 + K3$*p^4); 246 //easting of points 247 VMatrix x = (K4$*p + K5$*p^3)+500000; 248 x|IfVMat(LT(lat,lat*0),y+1.E+7,y) 249 }; 250 251 //////////////////////////////////////////////////////////////////////////// 252 Static Text _.autodoc.member.deg2utm = "Formulas for converting " 253 "coordinates of latitude and longitude in degrees to UTM"; 254 VMatrix deg2utm( 255 VMatrix lonlat, //Matrix with two columns, first one is longitud, second 256 //one is latitude, both meassured in degrees 257 VMatrix lonZone) //UTM longitud zone 258 //////////////////////////////////////////////////////////////////////////// 259 { 260 rad2utm(lonlat*deg2rad,lonZone) 261 }; 262 263 //////////////////////////////////////////////////////////////////////////// 264 Static Text _.autodoc.member.utm2rad = "Formulas for converting " 265 "UTM coordinates to latitude and longitude in radians"; 266 VMatrix utm2rad( 267 VMatrix xy, //Matrix with two columns 268 VMatrix lonZone, //UTM longitud zone 269 VMatrix latZone) //UTM latitud zone 270 //////////////////////////////////////////////////////////////////////////// 271 { 272 //WriteLn("TRACE zone="<<zone); 273 //Central meridian of zone 274 VMatrix long0 = (lonZone*6-183)*deg2rad; 275 //WriteLn("TRACE long0="<<long0); 276 //easting of points 277 VMatrix x = SubCol(xy,[[1]])-500000; 278 //northing of points 279 VMatrix isSouthern = LT(latZone,latZone*0); 280 VMatrix y = 281 { 282 VMatrix aux = SubCol(xy,[[2]]); 283 IfVMat(isSouthern,-aux+1.E+7,aux) 284 }; 285 Real e2 = _.e^2; 286 Real e4 = _.e^4; 287 Real e6 = _.e^6; 288 //WriteLn("TRACE x="<<VMat2Mat(x)); 289 //WriteLn("TRACE y="<<VMat2Mat(y)); 290 //Calculate the Meridional Arc 291 VMatrix M = y/_.k0; 292 //WriteLn("TRACE M="<<VMat2Mat(M)); 293 //Calculating Footprint Latitude 294 VMatrix mu = M/(_.a*(1- e2/4 -3*e4/64 - 5*e6/256)); 295 //WriteLn("TRACE mu="<<VMat2Mat(mu)); 296 VMatrix fp = 297 mu + 298 Sin(mu*2)*_.J1 + 299 Sin(mu*4)*_.J2 + 300 Sin(mu*6)*_.J3 + 301 Sin(mu*8)*_.J4; 302 //WriteLn("TRACE fp="<<VMat2Mat(fp)); 303 VMatrix sinfp = Sin(fp); 304 VMatrix cosfp = Cos(fp); 305 VMatrix tanfp = Tan(fp); 306 VMatrix C1 = (cosfp^2)*_.e.2; 307 //WriteLn("TRACE C1="<<VMat2Mat(C1)); 308 VMatrix T1 = tanfp^2; 309 //WriteLn("TRACE T1="<<VMat2Mat(T1)); 310 VMatrix sinfp2e21 = -(sinfp^2)*_.e^2+1; 311 VMatrix R1 = sinfp2e21^(-3/2)*(_.a*(1-_.e^2)); 312 //WriteLn("TRACE R1="<<VMat2Mat(R1)); 313 VMatrix N1 = sinfp2e21^(-1/2)*_.a; 314 //WriteLn("TRACE N1="<<VMat2Mat(N1)); 315 VMatrix D = x$/(N1*_.k0); 316 //WriteLn("TRACE D="<<VMat2Mat(D)); 317 VMatrix Q1 = N1$*tanfp$/R1; 318 //WriteLn("TRACE Q1="<<VMat2Mat(Q1)); 319 VMatrix Q2 = (D^2)/2; 320 //WriteLn("TRACE Q2="<<VMat2Mat(Q2)); 321 VMatrix Q3 = (T1* 3 + C1* 10 - C1^2*4 +(5- 9*_.e.2))$*D^4/24; 322 //WriteLn("TRACE Q3="<<VMat2Mat(Q3)); 323 VMatrix Q4 = (T1*90 + C1*298 + T1^2*45 - C1^2*3 +(61-252*_.e.2))$*D^6/720; 324 //WriteLn("TRACE Q4="<<VMat2Mat(Q4)); 325 VMatrix Q5 = D; 326 //WriteLn("TRACE Q5="<<VMat2Mat(Q5)); 327 VMatrix Q6 = (T1*2 + C1 + 1)$*D^3/6; 328 //WriteLn("TRACE Q6="<<VMat2Mat(Q6)); 329 VMatrix Q7 = (T1*28 - C1*2 + T1^2*24 - C1^2*3 +(5 + 8*_.e.2))$*D^5/120; 330 //WriteLn("TRACE Q7="<<VMat2Mat(Q7)); 331 VMatrix lat = fp - Q1$*(Q2 - Q3 + Q4); 332 //WriteLn("TRACE lat="<<VMat2Mat(lat)); 333 VMatrix long = (Q5 - Q6 + Q7)$/cosfp+long0; 334 //WriteLn("TRACE long="<<VMat2Mat(long)); 335 long | IfVMat(isSouthern,-lat,lat) 336 }; 337 //////////////////////////////////////////////////////////////////////////// 338 Static Text _.autodoc.member.utm2deg = "Formulas for converting " 339 "UTM coordinates to latitude and longitude in degrees"; 340 VMatrix utm2deg( 341 VMatrix xy, //Matrix with two columns 342 VMatrix lonZone, //UTM longitud zone 343 VMatrix latZone) //UTM latitud zone 344 //////////////////////////////////////////////////////////////////////////// 345 { 346 utm2rad(xy,lonZone,latZone)/deg2rad 347 } 348 }; 349 350 ////////////////////////////////////////////////////////////////////////////// 351 //Abstract class to handle with a bidimensional point. 352 Class @Point2D 353 ////////////////////////////////////////////////////////////////////////////// 354 { 355 //////////////////////////////////////////////////////////////////////////// 356 Static Text _.autodoc.member.numberOfPoints = 357 "Returns the number of stored points"; 358 Real numberOfPoints(Real void); 359 //////////////////////////////////////////////////////////////////////////// 360 361 //////////////////////////////////////////////////////////////////////////// 362 Static Text _.autodoc.member.x = 363 "Returns the first coordinate of the k-th point"; 364 Real x(Real k); 365 //////////////////////////////////////////////////////////////////////////// 366 367 //////////////////////////////////////////////////////////////////////////// 368 Static Text _.autodoc.member.y = 369 "Returns the second coordinate of the k-th point"; 370 Real y(Real k) 371 //////////////////////////////////////////////////////////////////////////// 372 }; 373 374 ////////////////////////////////////////////////////////////////////////////// 375 //Class to handle with just one bidimensional point that 376 //isnŽt externally stored 377 Class @Point2D.Simple : @Point2D 378 ////////////////////////////////////////////////////////////////////////////// 379 { 380 Real _.x; 381 Real _.y; 382 383 //Just one point is stored 384 Real numberOfPoints(Real void) { 1 }; 385 //Argument k is unused 386 Real x(Real k) { _.x }; 387 //Argument k is unused 388 Real y(Real k) { _.y }; 389 //////////////////////////////////////////////////////////////////////////// 390 Static Text _.autodoc.member.New = "Creates an instance of @Point2D.Simple"; 391 Static @Point2D.Simple New(Real x, Real y) 392 //////////////////////////////////////////////////////////////////////////// 393 { 394 @Point2D.Simple new = [[ 395 Real _.x = x; 396 Real _.y = y ]]; 397 new 398 }; 399 //////////////////////////////////////////////////////////////////////////// 400 Static Text _.autodoc.member.FromRow = "Creates an instance of " 401 "@Point2D.Simple using the 2 first columns of selected row of given matrix"; 402 Static @Point2D.Simple FromRow(VMatrix M, Real numRow) 403 //////////////////////////////////////////////////////////////////////////// 404 { 405 @Point2D.Simple new = [[ 406 Real _.x = VMatDat(M,numRow,1); 407 Real _.y = VMatDat(M,numRow,2) ]]; 408 new 409 }; 410 //////////////////////////////////////////////////////////////////////////// 411 Static Text _.autodoc.member.FromCol = "Creates an instance of " 412 "@Point2D.Simple using the 2 first rows of selected column of given matrix"; 413 Static @Point2D.Simple FromCol(VMatrix M, Real numCol) 414 //////////////////////////////////////////////////////////////////////////// 415 { 416 @Point2D.Simple new = [[ 417 Real _.x = VMatDat(M,1,numCol); 418 Real _.y = VMatDat(M,2,numRow) ]]; 419 new 420 } 421 }; 422 423 ////////////////////////////////////////////////////////////////////////////// 424 //Class to store al large set of points as rows of a matrix with 2 columns. 425 Class @Point2D.Stored 426 ////////////////////////////////////////////////////////////////////////////// 427 { 428 VMatrix _.xy; 429 430 Real numberOfPoints(Real void) { VRows(_.xy) }; 431 Real x(Real k) { VMatDat(_.xy,k,1) }; 432 Real y(Real k) { VMatDat(_.xy,k,1) }; 433 434 @Point2D.Simple center(Real void) 435 { 436 Real m = VRows(_.xy); 437 VMatrix c = Rand(m,1,1/m,1/m)*_.xy; 438 @Point2D.Simple::New(VMatDat(c,1,1), VMatDat(c,1,2)) 439 }; 440 441 //////////////////////////////////////////////////////////////////////////// 442 Static Text _.autodoc.member.New = "Creates an instance of @Point2D.Stored"; 443 Static @Point2D.Stored New(VMatrix xy) 444 //////////////////////////////////////////////////////////////////////////// 445 { 446 If(VColumns(xy)>2, 447 WriteLn("[@Point2D.Stored::New] Only 2 first of "<<VColumns(xy)+ 448 " columns of argument xy will be used","W")); 449 If(VColumns(xy)<2, 450 WriteLn("[@Point2D.Stored::New] Almost 2 columns instead of "<< 451 VColumns(xy)+" are needed for argument xy","E")); 452 @Point2D.Stored new = [[ 453 VMatrix _.xy = xy ]]; 454 new 455 } 456 }; 457 458 459 ////////////////////////////////////////////////////////////////////////////// 460 //Abstract class to inherite bidimensional interpolating classes. 461 Class @Interp2D 462 ////////////////////////////////////////////////////////////////////////////// 463 { 464 //Bidimensional points in cartesian coordinates. Dim: _.m x 2 465 @Point2D.Stored _.P; 466 //Tarjet data to be interpolated, Dim : _.m x _.n 467 VMatrix _.F; 468 469 //////////////////////////////////////////////////////////////////////////// 470 //Auxiliar members 471 //////////////////////////////////////////////////////////////////////////// 472 //Number of interpolation points 473 Real _.m = ?; 474 //Number of independent interpolation functions. 475 //When _.n==1 itŽs called the scalar interpolating case 476 //When _.n>=2 itŽs called the vectorial interpolating case 477 Real _.n = ?; 478 479 //////////////////////////////////////////////////////////////////////////// 480 Static Text _.autodoc.member.build = 481 "Initializes all members which are needed to build the interpolating " 482 "methods"; 483 Real build(Real void); 484 //////////////////////////////////////////////////////////////////////////// 485 486 //////////////////////////////////////////////////////////////////////////// 487 Static Text _.autodoc.member.eval.vector = 488 "Evaluates all interpolation function at point x,y"; 489 VMatrix eval.vector(@Point2D p); 490 //////////////////////////////////////////////////////////////////////////// 491 492 //////////////////////////////////////////////////////////////////////////// 493 Static Text _.autodoc.member.eval = 494 "Evaluates the first interpolation function at point x,y. ItŽs useful in " 495 "the scalar case, when _.F has just one column (_.n==1)"; 496 Real eval(@Point2D p) 497 //////////////////////////////////////////////////////////////////////////// 498 { 499 VMatDat(eval.vector(p),1,1) 500 } 501 }; 502 503 ////////////////////////////////////////////////////////////////////////////// 504 //Abstract class to inherite bidimensional weighted interpolating classes. 505 Class @Interp2D.Gravit : @Interp2D 506 ////////////////////////////////////////////////////////////////////////////// 507 { 508 //In order to be more efficient, the points farther of this distance will 509 //be skipped due its weight is almost null 510 Real _.maxDistance; 511 512 //////////////////////////////////////////////////////////////////////////// 513 //Auxiliar members 514 //////////////////////////////////////////////////////////////////////////// 515 Set _.point.idx = Copy(Empty); 516 Set _.x.range = Copy(Empty); 517 VMatrix _.x.class = Rand(0,0,0,0); 518 Set _.y.range = Copy(Empty); 519 VMatrix _.y.class = Rand(0,0,0,0); 520 VMatrix _.grid.map = Rand(0,0,0,0); 521 Set _.grid = Copy(Empty); 522 523 //////////////////////////////////////////////////////////////////////////// 524 Real build(Real void) 525 //////////////////////////////////////////////////////////////////////////// 526 { 527 Real _.m := VRows(_.P::_.xy); 528 Real _.n := VRows(_.F); 529 If(VColumns(_.P::_.xy)!=2, 530 WriteLn("Interp2D.Gravit::_.P::_.xy must have 2 columns instead " 531 "of "<<VColumns(_.P::_.xy))); 532 If(VRows(_.F)!=_.m, 533 WriteLn("Interp2D.Gravit::_.xy must have 2 columns instead of " 534 <<VColumns(_.P::_.xy))); 535 536 Set _.point.idx := Range(1,_.m,1); 537 VMatrix x = SubCol(_.P::_.xy,[[1]]); 538 VMatrix y = SubCol(_.P::_.xy,[[2]]); 539 Set _.x.range := Range(VMatMin(x),VMatMax(x),_.maxDistance); 540 Set _.y.range := Range(VMatMin(y),VMatMax(y),_.maxDistance); 541 VMatrix _.x.class := MatQuery::ClassifyRowsByRank(x,_.x.range); 542 VMatrix _.y.class := MatQuery::ClassifyRowsByRank(y,_.y.range); 543 Set xy.class = Classify(_.point.idx, Real(Real a, Real b) 544 { 545 Real x.cmp = Compare(VMatDat(_.x.class,a,1),VMatDat(_.x.class,b,1)); 546 If(x.cmp, x.cmp, 547 Real y.cmp = Compare(VMatDat(_.y.class,a,1),VMatDat(_.y.class,b,1))) 548 }); 549 Set _.grid := For(1,Card(_.x.range)+1,Set(Real i) 550 { 551 For(1,Card(_.y.range)+1,Set(Real j) 552 { 553 Copy(Empty) 554 }) 555 }); 556 VMatrix _.grid.map := Group("ConcatRows",EvalSet(xy.class, VMatrix(Set cl) 557 { 558 Real k = cl[1]; 559 Real x.class = VMatDat(_.x.class,k,1); 560 Real y.class = VMatDat(_.y.class,k,1); 561 Set _.grid[x.class][y.class] := cl; 562 SetRow([[x.class,y.class]]) 563 })); 564 True 565 }; 566 567 //////////////////////////////////////////////////////////////////////////// 568 Static Text _.autodoc.member.get.distance = 569 "Evaluates the weight between a given point p and each point of a 2 " 570 "columns matrix of coordinates"; 571 VMatrix get.distance(@Point2D p, VMatrix xy) 572 //////////////////////////////////////////////////////////////////////////// 573 { 574 Real m = VRows(xy); 575 VMatrix p.x = Rand(m,1,p::x(1),p::x(1)); 576 VMatrix p.y = Rand(m,1,p::y(1),p::y(1)); 577 VMatrix x = SubCol(xy,[[1]]); 578 VMatrix y = SubCol(xy,[[2]]); 579 RPow(RPow(x-p.x,2)+RPow(y-p.y,2),0.5) 580 }; 581 582 //////////////////////////////////////////////////////////////////////////// 583 NameBlock evaluate(@Point2D p) 584 //////////////////////////////////////////////////////////////////////////// 585 {[[ 586 VMatrix p.x = Rand(1,1,p::x(1),p::x(1)); 587 VMatrix p.y = Rand(1,1,p::y(1),p::y(1)); 588 VMatrix p.xy = p.x | p.y; 589 Real p.x.class = VMatDat(MatQuery::ClassifyRowsByRank(p.x,_.x.range),1,1); 590 Real p.y.class = VMatDat(MatQuery::ClassifyRowsByRank(p.y,_.y.range),1,1); 591 Real i.min = Max(1,p.x.class-1); 592 Real i.max = Min(Card(_.x.range)+1,p.x.class+1); 593 Real j.min = Max(1,p.y.class-1); 594 Real j.max = Min(Card(_.y.range)+1,p.y.class+1); 595 Set p.candidates = BinGroup("<<",For(i.min, i.max, Set(Real i) 596 { 597 BinGroup("<<",For(j.min, j.max, Set(Real j) 598 { 599 _.grid[i][j] 600 })) 601 })); 602 VMatrix xy.candidates = SubRow(_.P::_.xy, p.candidates); 603 VMatrix d.candidates = get.distance(p,xy.candidates); 604 Set neighborhood = MatQuery::SelectRowsInInterval(d.candidates, 605 False, 0, _.maxDistance, True); 606 Matrix d = VMat2Mat(SubRow(d.candidates, neighborhood)); 607 VMatrix v = Mat2VMat(RPow(d,2)); 608 VMatrix w = v/VMatSum(v); 609 VMatrix f = Tra(w) * SubRow(SubRow(_.F,p.candidates),neighborhood) 610 ]]}; 611 //////////////////////////////////////////////////////////////////////////// 612 VMatrix eval.vector(@Point2D p) 613 //////////////////////////////////////////////////////////////////////////// 614 { 615 VMatrix p.x = Rand(1,1,p::x(1),p::x(1)); 616 VMatrix p.y = Rand(1,1,p::y(1),p::y(1)); 617 VMatrix p.xy = p.x | p.y; 618 Real p.x.class = VMatDat(MatQuery::ClassifyRowsByRank(p.x,_.x.range),1,1); 619 Real p.y.class = VMatDat(MatQuery::ClassifyRowsByRank(p.y,_.y.range),1,1); 620 Real i.min = Max(1,p.x.class-1); 621 Real i.max = Min(Card(_.x.range)+1,p.x.class+1); 622 Real j.min = Max(1,p.y.class-1); 623 Real j.max = Min(Card(_.y.range)+1,p.y.class+1); 624 Set p.candidates = BinGroup("<<",For(i.min, i.max, Set(Real i) 625 { 626 BinGroup("<<",For(j.min, j.max, Set(Real j) 627 { 628 _.grid[i][j] 629 })) 630 })); 631 VMatrix xy.candidates = SubRow(_.P::_.xy, p.candidates); 632 VMatrix d.candidates = get.distance(p,xy.candidates); 633 Set neighborhood = MatQuery::SelectRowsInInterval(d.candidates, 634 False, 0, _.maxDistance, True); 635 Matrix d = VMat2Mat(SubRow(d.candidates, neighborhood),1); 636 VMatrix v = Mat2VMat(RPow(d,2)); 637 VMatrix w = v/VMatSum(v); 638 w * SubRow(SubRow(_.F,p.candidates),neighborhood) 639 }; 640 641 Static Text _.autodoc.member.New = "Creates an instance of " 642 "@Interp2D.Gravit"; 643 644 Static @Interp2D.Gravit New(VMatrix XY, VMatrix F, Real maxDistance) 645 { 646 @Interp2D.Gravit new = 647 [[ 648 @Point2D.Stored _.P = @Point2D.Stored::New(XY); 649 VMatrix _.F = F; 650 Real _.maxDistance = maxDistance 651 ]] 652 } 653 } 21 #Embed "UTMFormula.tol"; 22 #Embed "KML.tol"; 23 #Embed "Point2D.tol"; 24 #Embed "Interp2D.tol" 654 25 655 26 ]]; 656 657 658 659 660
Note: See TracChangeset
for help on using the changeset viewer.
