rd_nap_to_etrs 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,1535 +0,0 @@
1
- /*
2
- **--------------------------------------------------------------
3
- ** RDNAPTRANS(TM)2008
4
- **
5
- ** Authors: Jochem Lesparre, Joop van Buren, Marc Crombaghs, Frank Dentz, Arnoud Pol, Sander Oude Elberink
6
- ** http://www.rdnap.nl
7
- ** Based on RDNAPTRANS2004
8
- ** Ruby bindings added by: Benjamin ter Kuile
9
- ** Main changes:
10
- ** - 7 similarity transformation parameters
11
- ** - 0.0088 offset in the transformation between ellipsoidal height (h) and orthometric heights (NAP)
12
- ** - coordinates are computed also outside the validity regions of the grid files x2c.grd, y2c.grd and nlgeo04.grd
13
- **--------------------------------------------------------------
14
- */
15
-
16
- /*
17
- **--------------------------------------------------------------
18
- ** Include statements and namespace
19
- **--------------------------------------------------------------
20
- */
21
- #include <ruby.h>
22
- #include <iostream>
23
- #include <iomanip>
24
- #include <cmath>
25
- #include <string>
26
- #include <fstream>
27
- #include <cstdlib>
28
- using namespace std;
29
-
30
- /*
31
- **--------------------------------------------------------------
32
- ** Static data declarations
33
- ** Mathematical constant pi = 3.14...
34
- **--------------------------------------------------------------
35
- */
36
- const double PI = 2.0 * asin(1.0);
37
- /*
38
- **--------------------------------------------------------------
39
- ** Continuation of static data declarations
40
- ** Geographic NL-Bessel coordinates of Amersfoort (pivot point and projection base point)
41
- ** phi latitude in decimal degrees
42
- ** lambda longitude in decimal degrees
43
- ** h ellipsoidal height in meters
44
- ** Source of constants:
45
- ** Hk.J. Heuvelink, "De stereografische kaartprojectie in hare toepassing bij de Rijksdriehoeksmeting". Delft: Rijkscommissie voor Graadmeting en Waterpassing, 1918.
46
- ** HTW, "Handleiding voor de Technische Werkzaamheden van het Kadaster". Apeldoorn: Kadaster, 1996.
47
- **--------------------------------------------------------------
48
- */
49
- const double PHI_AMERSFOORT_BESSEL = 52.0+ 9.0/60.0+22.178/3600.0;
50
- const double LAMBDA_AMERSFOORT_BESSEL = 5.0+23.0/60.0+15.500/3600.0;
51
- const double H_AMERSFOORT_BESSEL = 0.0;
52
- /*
53
- **--------------------------------------------------------------
54
- ** Continuation of static data declarations
55
- ** Parameters of ellipsoids Bessel1841 and GRS80
56
- ** a half major axis in meters
57
- ** inv_f inverse flattening
58
- ** Source of constants: HTW, "Handleiding voor de Technische Werkzaamheden van het Kadaster". Apeldoorn: Kadaster, 1996.
59
- **--------------------------------------------------------------
60
- */
61
- const double A_BESSEL = 6377397.155;
62
- const double INV_F_BESSEL = 299.1528128;
63
- const double A_ETRS = 6378137;
64
- const double INV_F_ETRS = 298.257222101;
65
- /*
66
- **--------------------------------------------------------------
67
- ** Continuation of static data declarations
68
- ** Transformation parameters relative to pivot point Amersfoort. Note: Do NOT confuse with parameters for the center of the ellipsoid!
69
- ** tx translation in direction of x axis in meters
70
- ** ty translation in direction of y axis in meters
71
- ** tz translation in direction of z axis in meters
72
- ** alpha rotation around x axis in radials
73
- ** beta rotation around y axis in radials
74
- ** gamma rotation around z axis in radials
75
- ** delta scale parameter (scale = 1 + delta)
76
- ** Source of constants: A. de Bruijne, J. van Buren, A. Kösters and H. van der Marel, "De geodetische referentiestelsels van Nederland; Definitie en vastlegging van ETRS89, RD en NAP en hun onderlinge relatie". Delft: Nederlandse Commissie voor Geodesie (NCG), to be published in 2005.
77
- **--------------------------------------------------------------
78
- */
79
- const double TX_BESSEL_ETRS = 593.0248;
80
- const double TY_BESSEL_ETRS = 25.9984;
81
- const double TZ_BESSEL_ETRS = 478.7459;
82
- const double ALPHA_BESSEL_ETRS = 1.9342e-6;
83
- const double BETA_BESSEL_ETRS = -1.6677e-6;
84
- const double GAMMA_BESSEL_ETRS = 9.1019e-6;
85
- const double DELTA_BESSEL_ETRS = 4.0725e-6;
86
-
87
- const double TX_ETRS_BESSEL = -593.0248;
88
- const double TY_ETRS_BESSEL = -25.9984;
89
- const double TZ_ETRS_BESSEL = -478.7459;
90
- const double ALPHA_ETRS_BESSEL = -1.9342e-6;
91
- const double BETA_ETRS_BESSEL = 1.6677e-6;
92
- const double GAMMA_ETRS_BESSEL = -9.1019e-6;
93
- const double DELTA_ETRS_BESSEL = -4.0725e-6;
94
- /*
95
- **--------------------------------------------------------------
96
- ** Continuation of static data declarations
97
- ** Parameters of RD projection
98
- ** scale scale factor (k in some notations)
99
- ** this factor was first defined by Hk.J. Heuvelink as pow(10,-400e-7), nowadays we define it as exactly 0.9999079
100
- ** x_amersfoort false Easting
101
- ** y_amersfoort false Northing
102
- ** Source of constants:
103
- ** G. Bakker, J.C. de Munck and G.L. Strang van Hees, "Radio Positioning at Sea". Delft University of Technology, 1995.
104
- ** G. Strang van Hees, "Globale en lokale geodetische systemen". Delft: Nederlandse Commissie voor Geodesie (NCG), 1997.
105
- **--------------------------------------------------------------
106
- */
107
- const double SCALE_RD = 0.9999079;
108
- const double X_AMERSFOORT_RD = 155000;
109
- const double Y_AMERSFOORT_RD = 463000;
110
- /*
111
- **--------------------------------------------------------------
112
- ** Continuation of static data declarations
113
- ** Names of grd files
114
- **
115
- ** Grd files are binary grid files in the format of the program Surfer(R)
116
- ** The header contains information on the number of grid points, bounding box and extreme values.
117
- **
118
- ** RD-corrections in x and y
119
- **
120
- ** -8000 meters < RD Easting (stepsize 1 km) < 301000 meters
121
- ** 288000 meters < RD Northing (stepsize 1 km) < 630000 meters
122
- **
123
- ** Geoid model NLGEO2004
124
- **
125
- ** 50.525 degrees < ETRS89 latitude (stepsize 0.050000 degrees) < 53.675 degrees
126
- ** 3.20833 degrees < ETRS89 longitude (stepsize 0.083333 degrees) < 7.45833 degrees
127
- **
128
- ** Alternative notation:
129
- ** 50° 31' 30" < ETRS89_latitude (stepsize 0° 3' 0") < 53° 40' 30"
130
- ** 3° 12' 30" < ETRS89_longitude (stepsize 0° 5' 0") < 7° 27' 30"
131
- **
132
- ** The stepsizes correspond to about 5,5 km x 5,5 km in the Netherlands.
133
- **--------------------------------------------------------------
134
- */
135
- const string GRID_FILE_DX = "x2c.grd";
136
- const string GRID_FILE_DY = "y2c.grd";
137
- const string GRID_FILE_GEOID = "nlgeo04.grd";
138
- /*
139
- **--------------------------------------------------------------
140
- ** Continuation of static data declarations
141
- ** Precision parameters for iterations (respectively in meters and degrees)
142
- **--------------------------------------------------------------
143
- */
144
- const double PRECISION = 0.0001;
145
- const double DEG_PRECISION = PRECISION/40e6*360;
146
- /*
147
- **--------------------------------------------------------------
148
- ** Continuation of static data declarations
149
- ** Mean difference between NAP and ellipsoidal Bessel height. This is only used for getting from x, y in RD to phi, lambda in ETRS89.
150
- **--------------------------------------------------------------
151
- */
152
- const double MEAN_GEOID_HEIGHT_BESSEL = 0.0;
153
-
154
- /*
155
- **--------------------------------------------------------------
156
- ** Functions
157
- **--------------------------------------------------------------
158
- */
159
-
160
- /*
161
- **--------------------------------------------------------------
162
- ** Function name: deg_sin
163
- ** Description: sine for angles in degrees
164
- **
165
- ** Parameter Type In/Out Req/Opt Default
166
- ** alpha double in req none
167
- **
168
- ** Additional explanation of the meaning of parameters
169
- ** none
170
- **
171
- ** Return value: (besides the standard return values)
172
- ** sin(alpha)
173
- **--------------------------------------------------------------
174
- */
175
- double deg_sin(double alpha)
176
- {
177
- return sin(alpha/180.0*PI);
178
- }
179
-
180
- /*
181
- **--------------------------------------------------------------
182
- ** Function name: deg_cos
183
- ** Description: cosine for angles in degrees
184
- **
185
- ** Parameter Type In/Out Req/Opt Default
186
- ** alpha double in req none
187
- **
188
- ** Additional explanation of the meaning of parameters
189
- ** none
190
- **
191
- ** Return value: (besides the standard return values)
192
- ** cos(alpha)
193
- **--------------------------------------------------------------
194
- */
195
- double deg_cos(double alpha)
196
- {
197
- return cos(alpha/180.0*PI);
198
- }
199
-
200
- /*
201
- **--------------------------------------------------------------
202
- ** Function name: deg_tan
203
- ** Description: tangent for angles in degrees
204
- **
205
- ** Parameter Type In/Out Req/Opt Default
206
- ** alpha double in req none
207
- **
208
- ** Additional explanation of the meaning of parameters
209
- ** none
210
- **
211
- ** Return value: (besides the standard return values)
212
- ** tan(alpha)
213
- **--------------------------------------------------------------
214
- */
215
- double deg_tan(double alpha)
216
- {
217
- return tan(alpha/180.0*PI);
218
- }
219
-
220
- /*
221
- **--------------------------------------------------------------
222
- ** Function name: deg_asin
223
- ** Description: inverse sine for angles in degrees
224
- **
225
- ** Parameter Type In/Out Req/Opt Default
226
- ** a double in req none
227
- **
228
- ** Additional explanation of the meaning of parameters
229
- ** none
230
- **
231
- ** Return value: (besides the standard return values)
232
- ** asin(a)
233
- **--------------------------------------------------------------
234
- */
235
- double deg_asin(double a)
236
- {
237
- return (asin(a)*180.0/PI);
238
- }
239
-
240
- /*
241
- **--------------------------------------------------------------
242
- ** Function name: deg_atan
243
- ** Description: inverse tangent for angles in degrees
244
- **
245
- ** Parameter Type In/Out Req/Opt Default
246
- ** a double in req none
247
- **
248
- ** Additional explanation of the meaning of parameters
249
- ** none
250
- **
251
- ** Return value: (besides the standard return values)
252
- ** atan(a)
253
- **--------------------------------------------------------------
254
- */
255
- double deg_atan(double a)
256
- {
257
- return (atan(a)*180.0/PI);
258
- }
259
-
260
- /*
261
- **--------------------------------------------------------------
262
- ** Function name: atanh
263
- ** Description: inverse hyperbolic tangent
264
- **
265
- ** Parameter Type In/Out Req/Opt Default
266
- ** a double in req none
267
- **
268
- ** Additional explanation of the meaning of parameters
269
- ** none
270
- **
271
- ** Return value: (besides the standard return values)
272
- ** atanh(a)
273
- **--------------------------------------------------------------
274
- */
275
- double atanh(double a)
276
- {
277
- return (0.5*log((1.0+a)/(1.0-a)));
278
- }
279
-
280
- /*
281
- **--------------------------------------------------------------
282
- ** Function name: deg_min_sec2decimal
283
- ** Description: converts from degrees, minutes and seconds to decimal degrees
284
- **
285
- ** Parameter Type In/Out Req/Opt Default
286
- ** deg double in req none
287
- ** min double in req none
288
- ** sec double in req none
289
- ** dec_deg double out - none
290
- **
291
- ** Additional explanation of the meaning of parameters
292
- ** All parameters are doubles, so one can also enter decimal minutes or degrees.
293
- ** Note: Nonsense input is accepted too.
294
- **
295
- ** Return value: (besides the standard return values)
296
- ** none
297
- **--------------------------------------------------------------
298
- */
299
- void deg_min_sec2decimal(double deg, double min, double sec, double& dec_deg)
300
- {
301
- dec_deg = (deg+min/60.0+sec/3600.0);
302
- }
303
-
304
- /*
305
- **--------------------------------------------------------------
306
- ** Function name: decimal2deg_min_sec
307
- ** Description: converts from decimal degrees to degrees, minutes and seconds
308
- **
309
- ** Parameter Type In/Out Req/Opt Default
310
- ** dec_deg double in req none
311
- ** deg int out - none
312
- ** min int out - none
313
- ** sec double out - none
314
- **
315
- ** Additional explanation of the meaning of parameters
316
- ** none
317
- **
318
- ** Return value: (besides the standard return values)
319
- ** none
320
- **--------------------------------------------------------------
321
- */
322
- void decimal2deg_min_sec(double dec_deg, int& deg, int& min, double& sec)
323
- {
324
- deg = int(dec_deg);
325
- min = int((dec_deg-deg)*60.0);
326
- sec = ((dec_deg-deg)*60.0-min)*60.0;
327
- }
328
-
329
- /*
330
- **--------------------------------------------------------------
331
- ** Function name: geographic2cartesian
332
- ** Description: from geographic coordinates to cartesian coordinates
333
- **
334
- ** Parameter Type In/Out Req/Opt Default
335
- ** phi double in req none
336
- ** lambda double in req none
337
- ** h double in req none
338
- ** a double in req none
339
- ** inv_f double in req none
340
- ** x double out - none
341
- ** y double out - none
342
- ** z double out - none
343
- **
344
- ** Additional explanation of the meaning of parameters
345
- ** phi latitude in degrees
346
- ** lambda longitude in degrees
347
- ** h ellipsoidal height
348
- ** a half major axis of the ellisoid
349
- ** inv_f inverse flattening of the ellipsoid
350
- ** x, y, z output of cartesian coordinates
351
- **
352
- ** Return value: (besides the standard return values)
353
- ** none
354
- **--------------------------------------------------------------
355
- */
356
- void geographic2cartesian(double phi, double lambda, double h,
357
- double a, double inv_f,
358
- double& x, double& y, double& z )
359
- {
360
- /*
361
- **--------------------------------------------------------------
362
- ** Source: G. Bakker, J.C. de Munck and G.L. Strang van Hees, "Radio Positioning at Sea". Delft University of Technology, 1995.
363
- **--------------------------------------------------------------
364
- */
365
-
366
- /*
367
- **--------------------------------------------------------------
368
- ** Explanation of the meaning of variables:
369
- ** f flattening of the ellipsoid
370
- ** ee first eccentricity squared (e squared in some notations)
371
- ** n second (East West) principal radius of curvature (N in some notations)
372
- **--------------------------------------------------------------
373
- */
374
- double f = 1.0/inv_f;
375
- double ee = f*(2.0-f);
376
- double n = a/sqrt(1.0-ee*pow(deg_sin(phi),2));
377
- x = (n+h)*deg_cos(phi)*deg_cos(lambda);
378
- y = (n+h)*deg_cos(phi)*deg_sin(lambda);
379
- z = (n*(1.0-ee)+h)*deg_sin(phi);
380
- }
381
-
382
- /*
383
- **--------------------------------------------------------------
384
- ** Function name: cartesian2geographic
385
- ** Description: from cartesian coordinates to geographic coordinates
386
- **
387
- ** Parameter Type In/Out Req/Opt Default
388
- ** x double in req none
389
- ** y double in req none
390
- ** z double in req none
391
- ** a double in req none
392
- ** inv_f double in req none
393
- ** phi double out - none
394
- ** lambda double out - none
395
- ** h double out - none
396
- **
397
- ** Additional explanation of the meaning of parameters
398
- ** x, y, z input of cartesian coordinates
399
- ** a half major axis of the ellisoid
400
- ** inv_f inverse flattening of the ellipsoid
401
- ** phi output latitude in degrees
402
- ** lambda output longitude in degrees
403
- ** h output ellipsoidal height
404
- **
405
- ** Return value: (besides the standard return values)
406
- ** none
407
- **--------------------------------------------------------------
408
- */
409
- void cartesian2geographic(double x, double y, double z,
410
- double a, double inv_f,
411
- double& phi, double& lambda, double& h )
412
- {
413
- /*
414
- **--------------------------------------------------------------
415
- ** Source: G. Bakker, J.C. de Munck and G.L. Strang van Hees, "Radio Positioning at Sea". Delft University of Technology, 1995.
416
- **--------------------------------------------------------------
417
- */
418
-
419
- /*
420
- **--------------------------------------------------------------
421
- ** Explanation of the meaning of variables:
422
- ** f flattening of the ellipsoid
423
- ** ee first eccentricity squared (e squared in some notations)
424
- ** rho distance to minor axis
425
- ** n second (East West) principal radius of curvature (N in some notations)
426
- **--------------------------------------------------------------
427
- */
428
- double f = 1.0/inv_f;
429
- double ee = f*(2.0-f);
430
- double rho = sqrt(x*x+y*y);
431
- double n;
432
-
433
- /*
434
- **--------------------------------------------------------------
435
- ** Iterative calculation of phi
436
- **--------------------------------------------------------------
437
- */
438
- phi=0;
439
- double previous;
440
- double diff=90;
441
- while (diff>DEG_PRECISION)
442
- {
443
- previous = phi;
444
- n = a/sqrt(1.0-ee*pow(deg_sin(phi),2));
445
- phi = deg_atan(z/rho+n*ee*deg_sin(phi)/rho);
446
- diff = fabs(phi-previous);
447
- }
448
-
449
- /*
450
- **--------------------------------------------------------------
451
- ** Calculation of lambda and h
452
- **--------------------------------------------------------------
453
- */
454
- lambda = deg_atan(y/x);
455
- h = rho*deg_cos(phi)+z*deg_sin(phi)-n*(1.0-ee*pow(deg_sin(phi),2));
456
- }
457
-
458
- /*
459
- **--------------------------------------------------------------
460
- ** Function name: sim_trans
461
- ** Description: 3 dimensional similarity transformation (7 parameters) around another pivot point "a" than the origin
462
- **
463
- ** Parameter Type In/Out Req/Opt Default
464
- ** x_in double in req none
465
- ** y_in double in req none
466
- ** z_in double in req none
467
- ** tx double in req none
468
- ** ty double in req none
469
- ** tz double in req none
470
- ** alpha double in req none
471
- ** beta double in req none
472
- ** gamma double in req none
473
- ** delta double in req none
474
- ** xa double in req none
475
- ** ya double in req none
476
- ** za double in req none
477
- ** x_out double out - none
478
- ** y_out double out - none
479
- ** z_out double out - none
480
- **
481
- ** Additional explanation of the meaning of parameters
482
- ** x_in, y_in, z_in input coordinates
483
- ** tx translation in direction of x axis
484
- ** ty translation in direction of y axis
485
- ** tz translation in direction of z axis
486
- ** alpha rotation around x axis in radials
487
- ** beta rotation around y axis in radials
488
- ** gamma rotation around z axis in radials
489
- ** delta scale parameter (scale = 1 + delta)
490
- ** xa, ya, za coordinates of pivot point a (in case of rotation around the center of the ellipsoid these parameters are zero)
491
- ** x_out, y_out, z_out output coordinates
492
- **
493
- ** Return value: (besides the standard return values)
494
- ** none
495
- **--------------------------------------------------------------
496
- */
497
- void sim_trans(double x_in, double y_in, double z_in,
498
- double tx, double ty, double tz,
499
- double alpha, double beta, double gamma,
500
- double delta,
501
- double xa, double ya, double za,
502
- double& x_out, double& y_out, double& z_out)
503
-
504
- {
505
- /*
506
- **--------------------------------------------------------------
507
- ** Source: HTW, "Handleiding voor de Technische Werkzaamheden van het Kadaster". Apeldoorn: Kadaster, 1996.
508
- **--------------------------------------------------------------
509
- */
510
-
511
- /*
512
- **--------------------------------------------------------------
513
- ** Calculate the elements of the rotation_matrix:
514
- **
515
- ** a b c
516
- ** d e f
517
- ** g h i
518
- **
519
- **--------------------------------------------------------------
520
- */
521
- double a = cos(gamma)*cos(beta);
522
- double b = cos(gamma)*sin(beta)*sin(alpha)+sin(gamma)*cos(alpha);
523
- double c = -cos(gamma)*sin(beta)*cos(alpha)+sin(gamma)*sin(alpha);
524
- double d = -sin(gamma)*cos(beta);
525
- double e = -sin(gamma)*sin(beta)*sin(alpha)+cos(gamma)*cos(alpha);
526
- double f = sin(gamma)*sin(beta)*cos(alpha)+cos(gamma)*sin(alpha);
527
- double g = sin(beta);
528
- double h = -cos(beta)*sin(alpha);
529
- double i = cos(beta)*cos(alpha);
530
-
531
- /*
532
- **--------------------------------------------------------------
533
- ** Calculate the elements of the vector input_point:
534
- ** point_2 = input_point - pivot_point
535
- **--------------------------------------------------------------
536
- */
537
- double x = x_in-xa;
538
- double y = y_in-ya;
539
- double z = z_in-za;
540
-
541
- /*
542
- **--------------------------------------------------------------
543
- ** Calculate the elements of the output vector:
544
- ** output_point = scale * rotation_matrix * point_2 + translation_vector + pivot_point
545
- **--------------------------------------------------------------
546
- */
547
- x_out = (1.0+delta)*(a*x+b*y+c*z)+tx+xa;
548
- y_out = (1.0+delta)*(d*x+e*y+f*z)+ty+ya;
549
- z_out = (1.0+delta)*(g*x+h*y+i*z)+tz+za;
550
- }
551
-
552
- /*
553
- **--------------------------------------------------------------
554
- ** Function name: rd_projection
555
- ** Description: stereographic double projection
556
- **
557
- ** Parameter Type In/Out Req/Opt Default
558
- ** phi double in req none
559
- ** lambda double in req none
560
- ** x_rd double out - none
561
- ** y_rd double out - none
562
- **
563
- ** Additional explanation of the meaning of parameters
564
- ** phi input Bessel latitude in degrees
565
- ** lambda input Bessel longitude in degrees
566
- ** x_rd, rd_y output RD coordinates
567
- **
568
- ** Return value: (besides the standard return values)
569
- ** none
570
- **--------------------------------------------------------------
571
- */
572
- void rd_projection(double phi, double lambda,
573
- double& x_rd, double& y_rd)
574
- {
575
- /*
576
- **--------------------------------------------------------------
577
- ** Source: G. Bakker, J.C. de Munck and G.L. Strang van Hees, "Radio Positioning at Sea". Delft University of Technology, 1995.
578
- ** G. Strang van Hees, "Globale en lokale geodetische systemen". Delft: Nederlandse Commissie voor Geodesie (NCG), 1997.
579
- **--------------------------------------------------------------
580
- */
581
-
582
- /*
583
- **--------------------------------------------------------------
584
- ** Explanation of the meaning of constants:
585
- ** f flattening of the ellipsoid
586
- ** ee first eccentricity squared (e squared in some notations)
587
- ** e first eccentricity
588
- ** eea second eccentricity squared (e' squared in some notations)
589
- **
590
- ** phi_amersfoort_sphere latitude of projection base point Amersfoort on sphere in degrees
591
- ** lambda_amersfoort_sphere longitude of projection base point Amersfoort on sphere in degrees
592
- **
593
- ** r1 first (North South) principal radius of curvature in Amersfoort (M in some notations)
594
- ** r2 second (East West) principal radius of curvature in Amersfoort (N in some notations)
595
- ** r_sphere radius of sphere
596
- **
597
- ** n constant of Gaussian projection n = 1.000475...
598
- ** q_amersfoort isometric latitude of Amersfoort on ellipsiod
599
- ** w_amersfoort isometric latitude of Amersfoort on sphere
600
- ** m constant of Gaussian projection m = 0.003773... (also named c in some notations)
601
- **--------------------------------------------------------------
602
- */
603
- const double f=1/INV_F_BESSEL;
604
- const double ee=f*(2-f);
605
- const double e=sqrt(ee);
606
- const double eea = ee/(1.0-ee);
607
-
608
- const double phi_amersfoort_sphere = deg_atan(deg_tan(PHI_AMERSFOORT_BESSEL)/sqrt(1+eea*pow(deg_cos(PHI_AMERSFOORT_BESSEL),2)));
609
- const double lambda_amersfoort_sphere = LAMBDA_AMERSFOORT_BESSEL;
610
-
611
- const double r1 = A_BESSEL*(1-ee)/pow(sqrt(1-ee*pow(deg_sin(PHI_AMERSFOORT_BESSEL),2)),3);
612
- const double r2 = A_BESSEL/sqrt(1.0-ee*pow(deg_sin(PHI_AMERSFOORT_BESSEL),2));
613
- const double r_sphere = sqrt(r1*r2);
614
-
615
- const double n = sqrt(1+eea*pow(deg_cos(PHI_AMERSFOORT_BESSEL),4));
616
- const double q_amersfoort = atanh(deg_sin(PHI_AMERSFOORT_BESSEL))-e*atanh(e*deg_sin(PHI_AMERSFOORT_BESSEL));
617
- const double w_amersfoort = log(deg_tan(45+0.5*phi_amersfoort_sphere));
618
- const double m = w_amersfoort-n*q_amersfoort;
619
-
620
- /*
621
- **--------------------------------------------------------------
622
- ** Explanation of the meaning of variables:
623
- ** q isometric latitude on ellipsiod
624
- ** w isometric latitude on sphere
625
- ** phi_sphere latitide on sphere in degrees
626
- ** delta_lambda_sphere difference in longitude on sphere with Amersfoort in degrees
627
- ** psi distance angle from Amersfoort on sphere
628
- ** alpha azimuth from Amersfoort
629
- ** r distance from Amersfoort in projection plane
630
- **--------------------------------------------------------------
631
- */
632
- double q = atanh(deg_sin(phi))-e*atanh(e*deg_sin(phi));
633
- double w = n*q+m;
634
- double phi_sphere = 2*deg_atan(exp(w))-90;
635
- double delta_lambda_sphere = n*(lambda-lambda_amersfoort_sphere);
636
- double sin_half_psi_squared = pow(deg_sin(0.5*(phi_sphere-phi_amersfoort_sphere)),2)+pow(deg_sin(0.5*delta_lambda_sphere),2)*deg_cos(phi_sphere)*deg_cos(phi_amersfoort_sphere);
637
- double sin_half_psi = sqrt(sin_half_psi_squared);
638
- double cos_half_psi = sqrt(1-sin_half_psi_squared);
639
- double tan_half_psi = sin_half_psi/cos_half_psi;
640
- double sin_psi = 2*sin_half_psi*cos_half_psi;
641
- double cos_psi = 1-2*sin_half_psi_squared;
642
- double sin_alpha = deg_sin(delta_lambda_sphere)*(deg_cos(phi_sphere)/sin_psi);
643
- double cos_alpha = (deg_sin(phi_sphere)-deg_sin(phi_amersfoort_sphere)*cos_psi)/(deg_cos(phi_amersfoort_sphere)*sin_psi);
644
- double r = 2*SCALE_RD*r_sphere*tan_half_psi;
645
-
646
- x_rd = r*sin_alpha+X_AMERSFOORT_RD;
647
- y_rd = r*cos_alpha+Y_AMERSFOORT_RD;
648
- }
649
-
650
- /*
651
- **--------------------------------------------------------------
652
- ** Function name: inv_rd_projection
653
- ** Description: inverse stereographic double projection
654
- **
655
- ** Parameter Type In/Out Req/Opt Default
656
- ** x_rd double in req none
657
- ** y_rd double in req none
658
- ** phi double out - none
659
- ** lambda double out - none
660
- **
661
- ** Additional explanation of the meaning of parameters
662
- ** x_rd, rd_y input RD coordinates
663
- ** phi output Bessel latitude in degrees
664
- ** lambda output Bessel longitude in degrees
665
- **
666
- ** Return value: (besides the standard return values)
667
- ** none
668
- **--------------------------------------------------------------
669
- */
670
- void inv_rd_projection(double x_rd, double y_rd,
671
- double& phi, double& lambda)
672
- {
673
- /*
674
- **--------------------------------------------------------------
675
- ** Source: G. Bakker, J.C. de Munck and G.L. Strang van Hees, "Radio Positioning at Sea". Delft University of Technology, 1995.
676
- ** G. Strang van Hees, "Globale en lokale geodetische systemen". Delft: Nederlandse Commissie voor Geodesie (NCG), 1997.
677
- **--------------------------------------------------------------
678
- */
679
-
680
- /*
681
- **--------------------------------------------------------------
682
- ** Explanation of the meaning of constants:
683
- ** f flattening of the ellipsoid
684
- ** ee first eccentricity squared (e squared in some notations)
685
- ** e first eccentricity
686
- ** eea second eccentricity squared (e' squared in some notations)
687
- **
688
- ** phi_amersfoort_sphere latitude of projection base point Amersfoort on sphere in degrees
689
- **
690
- ** r1 first (North South) principal radius of curvature in Amersfoort (M in some notations)
691
- ** r2 second (East West) principal radius of curvature in Amersfoort (N in some notations)
692
- ** r_sphere radius of sphere
693
- **
694
- ** n constant of Gaussian projection n = 1.000475...
695
- ** q_amersfoort isometric latitude of Amersfoort on ellipsiod
696
- ** w_amersfoort isometric latitude of Amersfoort on sphere
697
- ** m constant of Gaussian projection m = 0.003773... (also named c in some notations)
698
- **--------------------------------------------------------------
699
- */
700
- const double f = 1/INV_F_BESSEL;
701
- const double ee = f*(2-f);
702
- const double e = sqrt(ee);
703
- const double eea = ee/(1.0-ee);
704
-
705
- const double phi_amersfoort_sphere = deg_atan(deg_tan(PHI_AMERSFOORT_BESSEL)/sqrt(1+eea*pow(deg_cos(PHI_AMERSFOORT_BESSEL),2)));
706
-
707
- const double r1 = A_BESSEL*(1-ee)/pow(sqrt(1-ee*pow(deg_sin(PHI_AMERSFOORT_BESSEL),2)),3);
708
- const double r2 = A_BESSEL/sqrt(1.0-ee*pow(deg_sin(PHI_AMERSFOORT_BESSEL),2));
709
- const double r_sphere = sqrt(r1*r2);
710
-
711
- const double n = sqrt(1+eea*pow(deg_cos(PHI_AMERSFOORT_BESSEL),4));
712
- const double q_amersfoort = atanh(deg_sin(PHI_AMERSFOORT_BESSEL))-e*atanh(e*deg_sin(PHI_AMERSFOORT_BESSEL));
713
- const double w_amersfoort = log(deg_tan(45+0.5*phi_amersfoort_sphere));
714
- const double m = w_amersfoort-n*q_amersfoort;
715
-
716
- /*
717
- **--------------------------------------------------------------
718
- ** Explanation of the meaning of variables:
719
- ** r distance from Amersfoort in projection plane
720
- ** alpha azimuth from Amersfoort
721
- ** psi distance angle from Amersfoort on sphere in degrees
722
- ** phi_sphere latitide on sphere in degrees
723
- ** delta_lambda_sphere difference in longitude on sphere with Amersfoort in degrees
724
- ** w isometric latitude on sphere
725
- ** q isometric latitude on ellipsiod
726
- **--------------------------------------------------------------
727
- */
728
- double r = sqrt(pow(x_rd-X_AMERSFOORT_RD,2)+pow(y_rd-Y_AMERSFOORT_RD,2));
729
- double sin_alpha = (x_rd-X_AMERSFOORT_RD)/r;
730
- if (r<PRECISION) sin_alpha = 0;
731
- double cos_alpha = (y_rd-Y_AMERSFOORT_RD)/r;
732
- if (r<PRECISION) cos_alpha = 1;
733
- double psi = 2*deg_atan(r/(2*SCALE_RD*r_sphere));
734
- double phi_sphere = deg_asin(cos_alpha*deg_cos(phi_amersfoort_sphere)*deg_sin(psi)+deg_sin(phi_amersfoort_sphere)*deg_cos(psi));
735
- double delta_lambda_sphere = deg_asin((sin_alpha*deg_sin(psi))/deg_cos(phi_sphere));
736
-
737
- lambda = delta_lambda_sphere/n+LAMBDA_AMERSFOORT_BESSEL;
738
-
739
- double w = atanh(deg_sin(phi_sphere));
740
- double q = (w-m)/n;
741
-
742
- /*
743
- **--------------------------------------------------------------
744
- ** Iterative calculation of phi
745
- **--------------------------------------------------------------
746
- */
747
- phi=0;
748
- double previous;
749
- double diff=90;
750
- while (diff>DEG_PRECISION)
751
- {
752
- previous = phi;
753
- phi = 2*deg_atan(exp(q+0.5*e*log((1+e*deg_sin(phi))/(1-e*deg_sin(phi)))))-90;
754
- diff = fabs(phi-previous);
755
- }
756
- }
757
-
758
- /*
759
- **--------------------------------------------------------------
760
- ** Function name: read_grd_file_header
761
- ** Description: reads the header of a grd file
762
- **
763
- ** Parameter Type In/Out Req/Opt Default
764
- ** filename string in req none
765
- ** size_x short int out - none
766
- ** size_y short int out - none
767
- ** min_x double out - none
768
- ** max_x double out - none
769
- ** min_y double out - none
770
- ** max_y double out - none
771
- ** min_value double out - none
772
- ** max_value double out - none
773
- **
774
- ** Additional explanation of the meaning of parameters
775
- ** filename name of the to be read binary file
776
- ** size_x number of grid values in x direction (row)
777
- ** size_y number of grid values in y direction (col)
778
- ** min_x minimum of x
779
- ** max_x maximum of x
780
- ** min_y minimum of y
781
- ** max_y maximum of x
782
- ** min_value minimum value in grid (besides the error values)
783
- ** max_value maximum value in grid (besides the error values)
784
- **
785
- ** Return value: (besides the standard return values)
786
- ** none
787
- **--------------------------------------------------------------
788
- */
789
- int read_grd_file_header(string filename,
790
- short int& size_x, short int& size_y,
791
- double& min_x, double& max_x,
792
- double& min_y, double& max_y,
793
- double& min_value, double& max_value)
794
- {
795
- /*
796
- **--------------------------------------------------------------
797
- ** Grd files are binary grid files in the format of the program Surfer(R)
798
- **--------------------------------------------------------------
799
- */
800
-
801
- fstream file(filename.c_str(), ios::in | ios::binary);
802
-
803
- /*
804
- **--------------------------------------------------------------
805
- ** Read file id
806
- **--------------------------------------------------------------
807
- */
808
- char id[5];
809
- for (int i=0; i<4; i=i+1)
810
- {
811
- file.seekg(i, ios::beg);
812
- file.read((char *)(&id[i]), 1);
813
- }
814
- id[4] = '\0';
815
- string id_string = string(id);
816
-
817
- /*
818
- **--------------------------------------------------------------
819
- ** Checks
820
- **--------------------------------------------------------------
821
- */
822
- if (!file)
823
- {
824
- cerr<<filename<<" does not exist"<<endl;
825
- return -1;
826
- }
827
-
828
- if (id_string!="DSBB")
829
- {
830
- cerr<<filename<<" is not a valid grd file"<<endl;
831
- return -1;
832
- }
833
-
834
- if (sizeof(short int)!=2)
835
- {
836
- cerr<<"Error: The number of bytes of a short integer in your compiler is "<<sizeof(short int)<<" and not 2 as in the file "<<filename<<endl;
837
- return -1;
838
- }
839
-
840
- if (sizeof(double)!=8)
841
- {
842
- cerr<<"Error: The number of bytes of a double in your compiler is "<<sizeof(double)<<" and not 8 as in the file "<<filename<<endl;
843
- return -1;
844
- }
845
-
846
- /*
847
- **--------------------------------------------------------------
848
- ** Read output parameters
849
- **--------------------------------------------------------------
850
- */
851
- file.seekg(4, ios::beg);
852
- file.read((char *)(&size_x), 2);
853
-
854
- file.seekg(6, ios::beg);
855
- file.read((char *)(&size_y), 2);
856
-
857
-
858
- file.seekg(8, ios::beg);
859
- file.read((char *)(&min_x), 8);
860
-
861
- file.seekg(16, ios::beg);
862
- file.read((char *)(&max_x), 8);
863
-
864
- file.seekg(24, ios::beg);
865
- file.read((char *)(&min_y), 8);
866
-
867
- file.seekg(32, ios::beg);
868
- file.read((char *)(&max_y), 8);
869
-
870
- file.seekg(40, ios::beg);
871
- file.read((char *)(&min_value), 8);
872
-
873
- file.seekg(48, ios::beg);
874
- file.read((char *)(&max_value), 8);
875
-
876
- return 0;
877
- }
878
-
879
- /*
880
- **--------------------------------------------------------------
881
- ** Function name: read_grd_file_body
882
- ** Description: reads a value from a grd file
883
- **
884
- ** Parameter Type In/Out Req/Opt Default
885
- ** filename string in req none
886
- ** number long int in req none
887
- ** value float out - none
888
- **
889
- ** Additional explanation of the meaning of parameters
890
- ** filename name of the grd file to be read
891
- ** record_number number defining the position in the file
892
- ** record_value output of the read value
893
- **
894
- ** Return value: (besides the standard return values)
895
- ** none
896
- **--------------------------------------------------------------
897
- */
898
- int read_grd_file_body(string filename, long int record_number, float& record_value)
899
- {
900
- const int record_length = 4;
901
- const int header_length = 56;
902
-
903
- /*
904
- **--------------------------------------------------------------
905
- ** Read
906
- ** Grd files are binary grid files in the format of the program Surfer(R)
907
- ** The first "header_length" bytes are the header of the file
908
- ** The body of the file consists of records of "record_length" bytes
909
- ** The records have a "record_number", starting with 0,1,2,...
910
- **--------------------------------------------------------------
911
- */
912
- fstream file(filename.c_str(), ios::in | ios::binary);
913
- file.seekg(header_length+record_number*record_length, ios::beg);
914
- file.read((char *)(&record_value), record_length);
915
-
916
- /*
917
- **--------------------------------------------------------------
918
- ** Checks
919
- **--------------------------------------------------------------
920
- */
921
- if (!file)
922
- {
923
- cerr<<filename<<" does not exist"<<endl;
924
- return -1;
925
- }
926
-
927
- if (sizeof(record_value)!=record_length)
928
- {
929
- cerr<<"Error: The number of bytes of a float in your compiler is "<<sizeof(record_value)<<" and not "<<record_length<<" as in the file "<<filename<<endl;
930
- return -1;
931
- }
932
- return 0;
933
- }
934
-
935
- /*
936
- **--------------------------------------------------------------
937
- ** Function name: grid_interpolation
938
- ** Description: grid interpolation using Overhauser splines
939
- **
940
- ** Parameter Type In/Out Req/Opt Default
941
- ** x double in req none
942
- ** y double in req none
943
- ** grd_file string in req none
944
- ** value double out - none
945
- **
946
- ** Additional explanation of the meaning of parameters
947
- ** x, y coordinates of the point for which a interpolated value is desired
948
- ** grd_file name of the grd file to be read
949
- ** record_value output of the interpolated value
950
- **
951
- ** Return value: (besides the standard return values)
952
- ** none
953
- **--------------------------------------------------------------
954
- */
955
- int grid_interpolation(double x, double y, string grd_file, double& value)
956
- {
957
- int error;
958
- short int i, size_x, size_y;
959
- double min_x, max_x, min_y, max_y, min_value, max_value;
960
- long int record_number[16];
961
- float record_value[16];
962
- double ddx, ddy;
963
- double f[4], g[4];
964
- double gfac[16];
965
- double step_size_x, step_size_y;
966
-
967
- /*
968
- **--------------------------------------------------------------
969
- ** Explanation of the meaning of variables:
970
- ** size_x number of grid values in x direction (row)
971
- ** size_y number of grid values in y direction (col)
972
- ** min_x minimum of x
973
- ** max_x maximum of x
974
- ** min_y minimum of y
975
- ** max_y maximum of x
976
- ** min_value minimum value in grid (besides the error values)
977
- ** max_value maximum value in grid (besides the error values)
978
- **--------------------------------------------------------------
979
- */
980
- error = read_grd_file_header(grd_file, size_x, size_y, min_x, max_x, min_y, max_y, min_value, max_value);
981
- if (error!=0) return -1;
982
-
983
- step_size_x = (max_x-min_x)/(size_x-1);
984
- step_size_y = (max_y-min_y)/(size_y-1);
985
-
986
- /*
987
- **--------------------------------------------------------------
988
- ** Check for location safely inside the bounding box of grid
989
- **--------------------------------------------------------------
990
- */
991
- if (x<=(min_x+step_size_x) || x>=(max_x-step_size_x) ||
992
- y<=(min_y+step_size_y) || y>=(max_y-step_size_y))
993
- {
994
- cerr<<"Outside bounding box of "<<grd_file<<endl;
995
- if (grd_file=="x2c.grd") {error=1; value=0.0;}
996
- if (grd_file=="y2c.grd") {error=2; value=0.0;}
997
- if (grd_file=="nlgeo04.grd") error=3;
998
- return error;
999
- }
1000
-
1001
- /*
1002
- **--------------------------------------------------------------
1003
- ** The selected grid points are situated around point X like this:
1004
- **
1005
- ** 12 13 14 15
1006
- **
1007
- ** 8 9 10 11
1008
- ** X
1009
- ** 4 5 6 7
1010
- **
1011
- ** 0 1 2 3
1012
- **
1013
- ** ddx and ddy (in parts of the grid interval) are defined relative to grid point 9, respectively to the right and down.
1014
- **--------------------------------------------------------------
1015
- */
1016
- ddx = (x-min_x)/step_size_x-floor((x-min_x)/step_size_x);
1017
- ddy = 1-((y-min_y)/step_size_y-floor((y-min_y)/step_size_y));
1018
-
1019
- /*
1020
- **--------------------------------------------------------------
1021
- ** Calculate the record numbers of the selected grid points
1022
- ** The records are numbered from lower left corner to the uper right corner starting with 0:
1023
- **
1024
- ** size_x*(size_y-1) . . size_x*size_y-1
1025
- ** . .
1026
- ** . .
1027
- ** 0 . . . . . . size_x-1
1028
- **--------------------------------------------------------------
1029
- */
1030
- record_number[5] = int((x-min_x)/step_size_x + floor((y-min_y)/step_size_y)*size_x);
1031
- record_number[0] = record_number[5]-size_x-1;
1032
- record_number[1] = record_number[5]-size_x ;
1033
- record_number[2] = record_number[5]-size_x+1;
1034
- record_number[3] = record_number[5]-size_x+2;
1035
- record_number[4] = record_number[5]-1;
1036
- record_number[6] = record_number[5]+1;
1037
- record_number[7] = record_number[5]+2;
1038
- record_number[8] = record_number[5]+size_x-1;
1039
- record_number[9] = record_number[5]+size_x;
1040
- record_number[10] = record_number[5]+size_x+1;
1041
- record_number[11] = record_number[5]+size_x+2;
1042
- record_number[12] = record_number[5]+2*size_x-1;
1043
- record_number[13] = record_number[5]+2*size_x;
1044
- record_number[14] = record_number[5]+2*size_x+1;
1045
- record_number[15] = record_number[5]+2*size_x+2;
1046
-
1047
- /*
1048
- **--------------------------------------------------------------
1049
- ** Read the record values of the selected grid point
1050
- ** Outside the validity area the records have a very large value (circa 1.7e38).
1051
- **--------------------------------------------------------------
1052
- */
1053
- for (int i=0; i<16; i=i+1)
1054
- {
1055
- error = read_grd_file_body(grd_file, record_number[i], record_value[i]);
1056
- if (error!=0) return -1;
1057
- if (record_value[i]>max_value+PRECISION || record_value[i]<min_value-PRECISION)
1058
- {
1059
- cerr<<"Outside validity area of "<<grd_file<<endl;
1060
- if (grd_file=="x2c.grd") {error=1; value=0.0;}
1061
- if (grd_file=="y2c.grd") {error=2; value=0.0;}
1062
- if (grd_file=="nlgeo04.grd") error=3;
1063
- return error;
1064
- }
1065
- }
1066
-
1067
- /*
1068
- **--------------------------------------------------------------
1069
- ** Calculation of the multiplication factors
1070
- **--------------------------------------------------------------
1071
- */
1072
- f[0] = -0.5*ddx+ddx*ddx-0.5*ddx*ddx*ddx;
1073
- f[1] = 1.0-2.5*ddx*ddx+1.5*ddx*ddx*ddx;
1074
- f[2] = 0.5*ddx+2.0*ddx*ddx-1.5*ddx*ddx*ddx;
1075
- f[3] = -0.5*ddx*ddx+0.5*ddx*ddx*ddx;
1076
- g[0] = -0.5*ddy+ddy*ddy-0.5*ddy*ddy*ddy;
1077
- g[1] = 1.0-2.5*ddy*ddy+1.5*ddy*ddy*ddy;
1078
- g[2] = 0.5*ddy+2.0*ddy*ddy-1.5*ddy*ddy*ddy;
1079
- g[3] = -0.5*ddy*ddy+0.5*ddy*ddy*ddy;
1080
-
1081
- gfac[12] = f[0]*g[0];
1082
- gfac[8] = f[0]*g[1];
1083
- gfac[4] = f[0]*g[2];
1084
- gfac[0] = f[0]*g[3];
1085
- gfac[13] = f[1]*g[0];
1086
- gfac[9] = f[1]*g[1];
1087
- gfac[5] = f[1]*g[2];
1088
- gfac[1] = f[1]*g[3];
1089
- gfac[14] = f[2]*g[0];
1090
- gfac[10] = f[2]*g[1];
1091
- gfac[6] = f[2]*g[2];
1092
- gfac[2] = f[2]*g[3];
1093
- gfac[15] = f[3]*g[0];
1094
- gfac[11] = f[3]*g[1];
1095
- gfac[7] = f[3]*g[2];
1096
- gfac[3] = f[3]*g[3];
1097
-
1098
- /*
1099
- **--------------------------------------------------------------
1100
- ** Calculation of the interpolated value
1101
- ** Applying the multiplication factors on the selected grid values
1102
- **--------------------------------------------------------------
1103
- */
1104
- value=0.0;
1105
- for (i=0; i<16; i=i+1)
1106
- {
1107
- value=value+gfac[i]*record_value[i];
1108
- }
1109
-
1110
- return 0;
1111
- }
1112
-
1113
- /*
1114
- **--------------------------------------------------------------
1115
- ** Function name: rd_correction
1116
- ** Description: apply the modelled distortions in the RD coordinate system
1117
- **
1118
- ** Parameter Type In/Out Req/Opt Default
1119
- ** x_pseudo_rd double in req none
1120
- ** y_pseudo_rd double in req none
1121
- ** x_rd double out - none
1122
- ** y_rd double out - none
1123
- **
1124
- ** Additional explanation of the meaning of parameters
1125
- ** x_pseudo_rd, y_pseudo_rd input coordinates in undistorted pseudo RD
1126
- ** x_rd, y_rd output coordinates in real RD
1127
- **
1128
- ** Return value: (besides the standard return values)
1129
- ** none
1130
- **--------------------------------------------------------------
1131
- */
1132
- int rd_correction(double x_pseudo_rd, double y_pseudo_rd,
1133
- double& x_rd, double& y_rd)
1134
- {
1135
- int error;
1136
- double dx, dy;
1137
-
1138
- error = grid_interpolation(x_pseudo_rd, y_pseudo_rd, GRID_FILE_DX, dx);
1139
- error = grid_interpolation(x_pseudo_rd, y_pseudo_rd, GRID_FILE_DY, dy);
1140
- x_rd=x_pseudo_rd-dx;
1141
- y_rd=y_pseudo_rd-dy;
1142
- return error;
1143
- }
1144
-
1145
- /*
1146
- **--------------------------------------------------------------
1147
- ** Function name: inv_rd_correction
1148
- ** Description: remove the modelled distortions in the RD coordinate system
1149
- **
1150
- ** Parameter Type In/Out Req/Opt Default
1151
- ** x_rd double in req none
1152
- ** y_rd double in req none
1153
- ** x_pseudo_rd double out - none
1154
- ** x_pseudo_rd double out - none
1155
- **
1156
- ** Additional explanation of the meaning of parameters
1157
- ** x_rd, y_rd input coordinates in real RD
1158
- ** x_pseudo_rd, y_pseudo_rd output coordinates in undistorted pseudo RD
1159
- **
1160
- ** Return value: (besides the standard return values)
1161
- ** none
1162
- **--------------------------------------------------------------
1163
- */
1164
- int inv_rd_correction(double x_rd, double y_rd,
1165
- double& x_pseudo_rd, double& y_pseudo_rd)
1166
- {
1167
- int error;
1168
- double dx, dy;
1169
-
1170
- /*
1171
- **--------------------------------------------------------------
1172
- ** The grid values are formally in pseudo RD. For the interpolation below the RD values are used. The intoduced error is certainly smaller than 0.0001 m for the X2c.grd and Y2c.grd.
1173
- **--------------------------------------------------------------
1174
- */
1175
- x_pseudo_rd=x_rd;
1176
- y_pseudo_rd=y_rd;
1177
- error = grid_interpolation(x_pseudo_rd, y_pseudo_rd, GRID_FILE_DX, dx);
1178
- error = grid_interpolation(x_pseudo_rd, y_pseudo_rd, GRID_FILE_DY, dy);
1179
- x_pseudo_rd=x_rd+dx;
1180
- y_pseudo_rd=y_rd+dy;
1181
- return error;
1182
- }
1183
-
1184
- /*
1185
- **--------------------------------------------------------------
1186
- ** Function name: etrs2rd
1187
- ** Description: convert ETRS89 coordinates to RD coordinates
1188
- **
1189
- ** Parameter Type In/Out Req/Opt Default
1190
- ** phi_etrs double in req none
1191
- ** lambda_etrs double in req none
1192
- ** h_etrs double in req none
1193
- ** x_rd double out - none
1194
- ** y_rd double out - none
1195
- **
1196
- ** Additional explanation of the meaning of parameters
1197
- ** phi_etrs, lambda_etrs, h_etrs input ETRS89 coordinates
1198
- ** x_rd, y_rd output RD coordinates
1199
- **
1200
- ** Return value: (besides the standard return values)
1201
- ** none
1202
- **--------------------------------------------------------------
1203
- */
1204
- int etrs2rd(double phi_etrs, double lambda_etrs, double h_etrs,
1205
- double& x_rd, double& y_rd, double& h_bessel)
1206
- {
1207
- int error;
1208
- double x_etrs, y_etrs, z_etrs;
1209
- double x_bessel, y_bessel, z_bessel;
1210
- double phi_bessel, lambda_bessel;
1211
- double x_pseudo_rd, y_pseudo_rd;
1212
-
1213
- double x_amersfoort_bessel;
1214
- double y_amersfoort_bessel;
1215
- double z_amersfoort_bessel;
1216
- double x_amersfoort_etrs;
1217
- double y_amersfoort_etrs;
1218
- double z_amersfoort_etrs;
1219
-
1220
- /*
1221
- **--------------------------------------------------------------
1222
- ** Calculate the cartesian ETRS89 coordinates of the pivot point Amersfoort
1223
- **--------------------------------------------------------------
1224
- */
1225
- geographic2cartesian(PHI_AMERSFOORT_BESSEL, LAMBDA_AMERSFOORT_BESSEL, H_AMERSFOORT_BESSEL,
1226
- A_BESSEL, INV_F_BESSEL,
1227
- x_amersfoort_bessel, y_amersfoort_bessel, z_amersfoort_bessel);
1228
- x_amersfoort_etrs = x_amersfoort_bessel+TX_BESSEL_ETRS;
1229
- y_amersfoort_etrs = y_amersfoort_bessel+TY_BESSEL_ETRS;
1230
- z_amersfoort_etrs = z_amersfoort_bessel+TZ_BESSEL_ETRS;
1231
-
1232
- /*
1233
- **--------------------------------------------------------------
1234
- ** Convert ETRS89 coordinates to RD coordinates
1235
- ** (To convert from degrees, minutes and seconds use the function deg_min_sec2decimal() here)
1236
- **--------------------------------------------------------------
1237
- */
1238
- geographic2cartesian(phi_etrs, lambda_etrs, h_etrs,
1239
- A_ETRS, INV_F_ETRS,
1240
- x_etrs, y_etrs, z_etrs);
1241
- sim_trans(x_etrs, y_etrs, z_etrs,
1242
- TX_ETRS_BESSEL, TY_ETRS_BESSEL, TZ_ETRS_BESSEL,
1243
- ALPHA_ETRS_BESSEL, BETA_ETRS_BESSEL, GAMMA_ETRS_BESSEL,
1244
- DELTA_ETRS_BESSEL,
1245
- x_amersfoort_etrs, y_amersfoort_etrs, z_amersfoort_etrs,
1246
- x_bessel, y_bessel, z_bessel);
1247
- cartesian2geographic(x_bessel, y_bessel, z_bessel,
1248
- A_BESSEL, INV_F_BESSEL,
1249
- phi_bessel, lambda_bessel, h_bessel);
1250
- rd_projection(phi_bessel, lambda_bessel, x_pseudo_rd, y_pseudo_rd);
1251
- error = rd_correction(x_pseudo_rd, y_pseudo_rd, x_rd, y_rd);
1252
- return error;
1253
- }
1254
-
1255
- /*
1256
- **--------------------------------------------------------------
1257
- ** Function name: rd2etrs
1258
- ** Description: convert RD coordinates to ETRS89 coordinates
1259
- **
1260
- ** Parameter Type In/Out Req/Opt Default
1261
- ** x_rd double in req none
1262
- ** y_rd double in req none
1263
- ** nap double in req none
1264
- ** phi_etrs double out - none
1265
- ** lambda_etrs double out - none
1266
- **
1267
- ** Additional explanation of the meaning of parameters
1268
- ** x_rd, y_rd, nap input RD and NAP coordinates
1269
- ** phi_etrs, lambda_etrs output ETRS89 coordinates
1270
- **
1271
- ** Return value: (besides the standard return values)
1272
- ** none
1273
- **--------------------------------------------------------------
1274
- */
1275
- int rd2etrs(double x_rd, double y_rd, double nap,
1276
- double& phi_etrs, double& lambda_etrs, double& h_etrs)
1277
- {
1278
- int error;
1279
- double x_pseudo_rd, y_pseudo_rd;
1280
- double phi_bessel, lambda_bessel, h_bessel;
1281
- double x_bessel, y_bessel, z_bessel;
1282
- double x_etrs, y_etrs, z_etrs;
1283
- double x_amersfoort_bessel;
1284
- double y_amersfoort_bessel;
1285
- double z_amersfoort_bessel;
1286
-
1287
- /*
1288
- **--------------------------------------------------------------
1289
- ** Calculate the cartesian Bessel coordinates of the pivot point Amersfoort
1290
- **--------------------------------------------------------------
1291
- */
1292
- geographic2cartesian(PHI_AMERSFOORT_BESSEL, LAMBDA_AMERSFOORT_BESSEL, H_AMERSFOORT_BESSEL,
1293
- A_BESSEL, INV_F_BESSEL,
1294
- x_amersfoort_bessel, y_amersfoort_bessel, z_amersfoort_bessel);
1295
-
1296
- /*
1297
- **--------------------------------------------------------------
1298
- ** Calculate appoximated value of ellipsoidal Bessel height
1299
- ** The error made by using a constant for de Bessel geoid height is max. circa 1 meter in the ellipsoidal height (for the NLGEO2004 geoid model). This intoduces an error in the phi, lambda position too, this error is nevertheless certainly smaller than 0.0001 m.
1300
- **--------------------------------------------------------------
1301
- */
1302
- h_bessel = nap + MEAN_GEOID_HEIGHT_BESSEL;
1303
-
1304
- /*
1305
- **--------------------------------------------------------------
1306
- ** Convert RD coordinates to ETRS89 coordinates
1307
- **--------------------------------------------------------------
1308
- */
1309
- error = inv_rd_correction(x_rd, y_rd,
1310
- x_pseudo_rd, y_pseudo_rd);
1311
- inv_rd_projection(x_pseudo_rd, y_pseudo_rd,
1312
- phi_bessel, lambda_bessel);
1313
- geographic2cartesian(phi_bessel, lambda_bessel, h_bessel,
1314
- A_BESSEL, INV_F_BESSEL,
1315
- x_bessel, y_bessel, z_bessel);
1316
- sim_trans(x_bessel, y_bessel, z_bessel,
1317
- TX_BESSEL_ETRS, TY_BESSEL_ETRS, TZ_BESSEL_ETRS,
1318
- ALPHA_BESSEL_ETRS, BETA_BESSEL_ETRS, GAMMA_BESSEL_ETRS,
1319
- DELTA_BESSEL_ETRS,
1320
- x_amersfoort_bessel, y_amersfoort_bessel, z_amersfoort_bessel,
1321
- x_etrs, y_etrs, z_etrs);
1322
- cartesian2geographic(x_etrs, y_etrs, z_etrs,
1323
- A_ETRS, INV_F_ETRS,
1324
- phi_etrs, lambda_etrs, h_etrs);
1325
- /*
1326
- **--------------------------------------------------------------
1327
- ** To convert to degrees, minutes and seconds use the function decimal2deg_min_sec() here
1328
- **--------------------------------------------------------------
1329
- */
1330
- return error;
1331
- }
1332
-
1333
- /*
1334
- **--------------------------------------------------------------
1335
- ** Function name: etrs2nap
1336
- ** Description: convert ellipsoidal ETRS89 height to NAP height
1337
- **
1338
- ** Parameter Type In/Out Req/Opt Default
1339
- ** phi double in req none
1340
- ** lambda double in req none
1341
- ** h double in req none
1342
- ** nap double out - none
1343
- **
1344
- ** Additional explanation of the meaning of parameters
1345
- ** phi, lambda, h input ETRS89 coordinates
1346
- ** nap output NAP height
1347
- **
1348
- ** Return value: (besides the standard return values) none
1349
- ** on error (outside geoid grid) nap is not compted here
1350
- ** instead in etrs2rdnap nap=h_bessel
1351
- **--------------------------------------------------------------
1352
- */
1353
- int etrs2nap(double phi, double lambda, double h,
1354
- double& nap)
1355
- {
1356
- /*
1357
- **--------------------------------------------------------------
1358
- ** Explanation of the meaning of variables:
1359
- ** n geoid height
1360
- ** on error (outside geoid grid) nap is not compted
1361
- ** instead in etrs2rdnap nap=h_bessel
1362
- **--------------------------------------------------------------
1363
- */
1364
- int error;
1365
- double n;
1366
- error = grid_interpolation(lambda, phi, GRID_FILE_GEOID, n);
1367
- if (error!=0) return error;
1368
- nap = h-n+0.0088;
1369
- return 0;
1370
- }
1371
-
1372
- /*
1373
- **--------------------------------------------------------------
1374
- ** Function name: nap2etrs
1375
- ** Description: convert NAP height to ellipsoidal ETRS89 height
1376
- **
1377
- ** Parameter Type In/Out Req/Opt Default
1378
- ** phi double in req none
1379
- ** lambda double in req none
1380
- ** nap double in req none
1381
- ** h double out - none
1382
- **
1383
- ** Additional explanation of the meaning of parameters
1384
- ** phi, lambda input ETRS89 position
1385
- ** nap input NAP height at position phi, lambda
1386
- ** h output ellipsoidal ETRS89 height
1387
- **
1388
- ** Return value: (besides the standard return values)
1389
- ** none
1390
- ** on error (outside geoid grid) h is not compted here
1391
- ** instead in rdnap2etrs h=h_etrs_sim (from similarity transformation)
1392
- **--------------------------------------------------------------
1393
- */
1394
- int nap2etrs(double phi, double lambda, double nap,
1395
- double& h)
1396
- {
1397
- /*
1398
- **--------------------------------------------------------------
1399
- ** Explanation of the meaning of variables:
1400
- ** n geoid height
1401
- **--------------------------------------------------------------
1402
- */
1403
- int error;
1404
- double n;
1405
- error = grid_interpolation(lambda, phi, GRID_FILE_GEOID, n);
1406
- if (error!=0) return error;
1407
- h = nap+n-0.0088;
1408
- return 0;
1409
- }
1410
-
1411
- /*
1412
- **--------------------------------------------------------------
1413
- ** Function name: etrs2rdnap
1414
- ** Description: convert ETRS89 coordinates to RD and NAP coordinates
1415
- **
1416
- ** Parameter Type In/Out Req/Opt Default
1417
- ** phi double in req none
1418
- ** lambda double in req none
1419
- ** h double in req none
1420
- ** x_rd double out - none
1421
- ** y_rd double out - none
1422
- ** nap double out - none
1423
- **
1424
- ** Additional explanation of the meaning of parameters
1425
- ** phi, lambda, h input ETRS89 coordinates
1426
- ** x_rd, y_rd, nap output RD and NAP coordinates
1427
- **
1428
- ** Return value: (besides the standard return values)
1429
- ** none
1430
- **--------------------------------------------------------------
1431
- */
1432
- int etrs2rdnap(double phi, double lambda, double h,
1433
- double& x_rd, double& y_rd, double& nap)
1434
- {
1435
- int error;
1436
- double h_bessel, h_geoid;
1437
- error = etrs2rd( phi, lambda, h, x_rd, y_rd, h_bessel);
1438
- error = etrs2nap(phi, lambda, h, h_geoid);
1439
- if (error==3) nap=h_bessel;
1440
- else nap=h_geoid;
1441
- return error;
1442
- }
1443
-
1444
- /*
1445
- **--------------------------------------------------------------
1446
- ** Function name: rdnap2etrs
1447
- ** Description: convert RD and NAP coordinates to ETRS89 coordinates
1448
- **
1449
- ** Parameter Type In/Out Req/Opt Default
1450
- ** x_rd double in req none
1451
- ** y_rd double in req none
1452
- ** nap double in req none
1453
- ** phi double out - none
1454
- ** lambda double out - none
1455
- ** h double out - none
1456
- **
1457
- ** Additional explanation of the meaning of parameters
1458
- ** x_rd, y_rd, nap input RD and NAP coordinates
1459
- ** phi, lambda, h output ETRS89 coordinates
1460
- **
1461
- ** Return value: (besides the standard return values)
1462
- ** none
1463
- **--------------------------------------------------------------
1464
- */
1465
- int rdnap2etrs(double x_rd, double y_rd, double nap,
1466
- double& phi, double& lambda, double& h)
1467
- {
1468
- int error;
1469
- double h_etrs_sim, h_etrs_geoid;
1470
- error = rd2etrs( x_rd, y_rd, nap, phi, lambda, h_etrs_sim);
1471
- error = nap2etrs(phi, lambda, nap, h_etrs_geoid);
1472
- if (error==3) h=h_etrs_sim;
1473
- else h=h_etrs_geoid;
1474
- return error;
1475
- }
1476
-
1477
- // Use this typedef to make the compiler happy when
1478
- // calling rb_define_method()
1479
- typedef VALUE (ruby_method)(...);
1480
-
1481
- extern "C" VALUE r_transpoint2008(VALUE point){
1482
- int error;
1483
- double x_rd, y_rd, nap, phi, lambda, h;
1484
- VALUE rb_x_rd, rb_y_rd, rb_nap;
1485
-
1486
- rb_x_rd = rb_iv_get(point, "@x");
1487
- rb_y_rd = rb_iv_get(point, "@y");
1488
- rb_nap = rb_iv_get(point, "@nap");
1489
- if(TYPE(rb_x_rd) == T_FLOAT or TYPE(rb_x_rd) == T_FIXNUM or TYPE(rb_x_rd) == T_BIGNUM){
1490
- x_rd = NUM2DBL(rb_x_rd);
1491
- }else{
1492
- rb_raise(rb_eArgError, "The x value of the point is not a number");
1493
- }
1494
- if(TYPE(rb_y_rd) == T_FLOAT or TYPE(rb_y_rd) == T_FIXNUM or TYPE(rb_y_rd) == T_BIGNUM){
1495
- y_rd = NUM2DBL(rb_y_rd);
1496
- }else{
1497
- rb_raise(rb_eArgError, "The y value of point is not a number");
1498
- }
1499
- if(TYPE(rb_nap) == T_FLOAT or TYPE(rb_nap) == T_FIXNUM or TYPE(rb_nap) == T_BIGNUM){
1500
- nap = NUM2DBL(rb_nap);
1501
- }else{
1502
- //rb_raise(rb_eArgError, "The nap value of point is not a number");
1503
- }
1504
- error = rdnap2etrs(x_rd, y_rd, nap, phi, lambda, h);
1505
- rb_iv_set(point, "@lat", rb_float_new(phi));
1506
- rb_iv_set(point, "@lng", rb_float_new(lambda));
1507
- rb_iv_set(point, "@h", rb_float_new(h));
1508
- //rb_iv_set(point, "@nap", rb_float_new(h));
1509
- return point;
1510
- }
1511
-
1512
- extern "C" VALUE r_trans2008(VALUE self, VALUE ary) {
1513
- long i;
1514
- long len = RARRAY_LEN(ary);
1515
- VALUE point;
1516
- if(TYPE(ary) != T_ARRAY) rb_raise(rb_eArgError, "Please supply an array of RdNapToEtrs::Point objects");
1517
-
1518
- for(i = 0; i < len; i++){
1519
- point = rb_ary_entry(ary, i);
1520
- r_transpoint2008(point);
1521
- }
1522
- return ary;
1523
- }
1524
-
1525
- VALUE mod_RdNapToEtrs;
1526
- VALUE cls_Point;
1527
- VALUE cls_Batch;
1528
-
1529
- extern "C" void Init_trans2008()
1530
- {
1531
- mod_RdNapToEtrs = rb_define_module("RdNapToEtrs");
1532
- cls_Point = rb_define_class_under(mod_RdNapToEtrs, "Point", rb_cObject);
1533
- cls_Batch = rb_define_class_under(mod_RdNapToEtrs, "Batch", rb_cObject);
1534
- rb_define_method(cls_Batch, "_trans2008", (ruby_method*) &r_trans2008, 1);
1535
- }