OpenCPN Partial API docs
Loading...
Searching...
No Matches
GeomagnetismHeader.h
1/* WMM Subroutine library was tested in the following environments
2 *
3 * 1. Red Hat Linux with GCC Compiler
4 * 2. MS Windows XP with CodeGear C++ compiler
5 * 3. Sun Solaris with GCC Compiler
6 *
7 *
8 * Revision Number: $Revision: 1437 $
9 * Last changed by: $Author: awoods $
10 * Last changed on: $Date: 2016-03-01 10:49:40 -0700 (Tue, 01 Mar 2016) $
11 *
12 *
13 */
14
15#ifndef _POSIX_C_SOURCE
16#define _POSIX_C_SOURCE
17#endif
18
19/*
20 #ifndef EPOCHRANGE
21 #define EPOCHRANGE (int)5
22 #endif
23*/
24
25#ifndef GEOMAGHEADER_H
26#define GEOMAGHEADER_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32#define READONLYMODE "r"
33#define MAXLINELENGTH (1024)
34#define NOOFPARAMS (15)
35#define NOOFCOEFFICIENTS (7)
36
37#define _DEGREE_NOT_FOUND (-2)
38#define CALCULATE_NUMTERMS(N) (N * (N + 1) / 2 + N)
39
40/*These error values come from the ISCWSA error model:
41 *http://www.copsegrove.com/Pages/MWDGeomagneticModels.aspx
42 */
43#define INCL_ERROR_BASE (0.20)
44#define DECL_ERROR_OFFSET_BASE (0.36)
45#define F_ERROR_BASE (130)
46#define DECL_ERROR_SLOPE_BASE (5000)
47#define WMM_ERROR_MULTIPLIER 1.21
48#define IGRF_ERROR_MULTIPLIER 1.21
49
50/*These error values are the NCEI error model
51 *
52 */
53#define WMM_UNCERTAINTY_F 145
54#define WMM_UNCERTAINTY_H 128
55#define WMM_UNCERTAINTY_X 131
56#define WMM_UNCERTAINTY_Y 94
57#define WMM_UNCERTAINTY_Z 157
58#define WMM_UNCERTAINTY_I 0.21
59#define WMM_UNCERTAINTY_D_OFFSET 0.26
60#define WMM_UNCERTAINTY_D_COEF 5625
61
62#ifndef M_PI
63#define M_PI ((2) * (acos(0.0)))
64#endif
65
66#define RAD2DEG(rad) ((rad) * (180.0L / M_PI))
67#define DEG2RAD(deg) ((deg) * (M_PI / 180.0L))
68#define ATanH(x) (0.5 * log((1 + x) / (1 - x)))
69
70#ifndef TRUE
71#define TRUE ((int)1)
72#endif
73#ifndef FALSE
74#define FALSE ((int)0)
75#endif
76
77#define MAG_PS_MIN_LAT_DEGREE \
78 -55 /* Minimum Latitude for Polar Stereographic projection in degrees */
79#define MAG_PS_MAX_LAT_DEGREE \
80 55 /* Maximum Latitude for Polar Stereographic projection in degrees */
81#define MAG_UTM_MIN_LAT_DEGREE \
82 -80.5 /* Minimum Latitude for UTM projection in degrees */
83#define MAG_UTM_MAX_LAT_DEGREE \
84 84.5 /* Maximum Latitude for UTM projection in degrees */
85
86#define MAG_GEO_POLE_TOLERANCE 1e-5
87#define MAG_USE_GEOID \
88 1 /* 1 Geoid - Ellipsoid difference should be corrected, 0 otherwise */
89
90#define LAT_BOUND_MIN -90
91#define LAT_BOUND_MAX 90
92#define LON_BOUND_MIN -180
93#define LON_BOUND_MAX 360
94#define ALT_BOUND_MIN -10
95#define NO_ALT_MAX -99999
96#define USER_GAVE_UP -1
97
98#define WGS84ON 1
99#define MSLON 2
100
101/*
102Data types and prototype declaration for
103World Magnetic Model (WMM) subroutines.
104
105July 28, 2009
106
107manoj.c.nair@noaa.gov*/
108
109#define MODEL_RELEASE_DATE "10 Dec 2019"
110#define VERSIONDATE_LARGE \
111 "$Date: 2019-12-10 10:40:43 -0700 (Tue, 10 Dec 2019) $"
112
113typedef enum {
114 DECLINATION,
115 INCLINATION,
116 HOR_INTENSITY,
117 TOTAL_INTENSITY,
118 X_COMPONENT,
119 Y_COMPONENT,
120 Z_COMPONENT,
121 ALL
122} MAGenum_Comp;
123
124typedef struct {
125 double EditionDate;
126 double epoch; /*Base time of Geomagnetic model epoch (yrs)*/
127 char ModelName[32];
128 double *Main_Field_Coeff_G; /* C - Gauss coefficients of main geomagnetic
129 model (nT) Index is (n * (n + 1) / 2 + m) */
130 double *Main_Field_Coeff_H; /* C - Gauss coefficients of main geomagnetic
131 model (nT) */
132 double *Secular_Var_Coeff_G; /* CD - Gauss coefficients of secular geomagnetic
133 model (nT/yr) */
134 double *Secular_Var_Coeff_H; /* CD - Gauss coefficients of secular geomagnetic
135 model (nT/yr) */
136 int nMax; /* Maximum degree of spherical harmonic model */
137 int nMaxSecVar; /* Maximum degree of spherical harmonic secular model */
138 int SecularVariationUsed; /* Whether or not the magnetic secular variation
139 vector will be needed by program*/
140 double CoefficientFileEndDate;
141
143
144typedef struct {
145 double a; /*semi-major axis of the ellipsoid*/
146 double b; /*semi-minor axis of the ellipsoid*/
147 double fla; /* flattening */
148 double epssq; /*first eccentricity squared */
149 double eps; /* first eccentricity */
150 double re; /* mean radius of ellipsoid*/
152
153typedef struct {
154 double lambda; /* longitude */
155 double phi; /* geodetic latitude */
156 double HeightAboveEllipsoid; /* height above the ellipsoid (HaE) */
157 double HeightAboveGeoid; /* (height above the EGM96 geoid model ) */
158 int UseGeoid;
160
161typedef struct {
162 double lambda; /* longitude*/
163 double phig; /* geocentric latitude*/
164 double r; /* distance from the center of the ellipsoid*/
166
167typedef struct {
168 int Year;
169 int Month;
170 int Day;
171 double DecimalYear; /* decimal years */
173
174typedef struct {
175 double *Pcup; /* Legendre Function */
176 double *dPcup; /* Derivative of Legendre fcn */
178
179typedef struct {
180 double Bx; /* North */
181 double By; /* East */
182 double Bz; /* Down */
184
185typedef struct {
186 double
187 *RelativeRadiusPower; /* [earth_reference_radius_km / sph. radius ]^n */
188 double *cos_mlambda; /*cp(m) - cosine of (m*spherical coord. longitude)*/
189 double *sin_mlambda; /* sp(m) - sine of (m*spherical coord. longitude) */
191
192typedef struct {
193 double Decl; /* 1. Angle between the magnetic field vector and true north,
194 positive east*/
195 double Incl; /*2. Angle between the magnetic field vector and the horizontal
196 plane, positive down*/
197 double F; /*3. Magnetic Field Strength*/
198 double H; /*4. Horizontal Magnetic Field Strength*/
199 double X; /*5. Northern component of the magnetic field vector*/
200 double Y; /*6. Eastern component of the magnetic field vector*/
201 double Z; /*7. Downward component of the magnetic field vector*/
202 double GV; /*8. The Grid Variation*/
203 double Decldot; /*9. Yearly Rate of change in declination*/
204 double Incldot; /*10. Yearly Rate of change in inclination*/
205 double Fdot; /*11. Yearly rate of change in Magnetic field strength*/
206 double Hdot; /*12. Yearly rate of change in horizontal field strength*/
207 double Xdot; /*13. Yearly rate of change in the northern component*/
208 double Ydot; /*14. Yearly rate of change in the eastern component*/
209 double Zdot; /*15. Yearly rate of change in the downward component*/
210 double GVdot; /*16. Yearly rate of change in grid variation*/
212
213typedef struct {
214 int NumbGeoidCols; /* 360 degrees of longitude at 15 minute spacing */
215 int NumbGeoidRows; /* 180 degrees of latitude at 15 minute spacing */
216 int NumbHeaderItems; /* min, max lat, min, max long, lat, long spacing*/
217 int ScaleFactor; /* 4 grid cells per degree at 15 minute spacing */
218 float *GeoidHeightBuffer;
219 int NumbGeoidElevs;
220 int Geoid_Initialized; /* indicates successful initialization */
221 int UseGeoid; /*Is the Geoid being used?*/
223
224typedef struct {
225 int UseGradient;
226 MAGtype_GeoMagneticElements GradPhi; /* phi */
227 MAGtype_GeoMagneticElements GradLambda; /* lambda */
230
231typedef struct {
232 char Longitude[40];
233 char Latitude[40];
235
236typedef struct {
237 double Easting; /* (X) in meters*/
238 double Northing; /* (Y) in meters */
239 int Zone; /*UTM Zone*/
240 char HemiSphere;
241 double CentralMeridian;
242 double ConvergenceOfMeridians;
243 double PointScale;
245
246enum PARAMS {
247 SHDF,
248 MODELNAME,
249 PUBLISHER,
250 RELEASEDATE,
251 DATACUTOFF,
252 MODELSTARTYEAR,
253 MODELENDYEAR,
254 EPOCH,
255 INTSTATICDEG,
256 INTSECVARDEG,
257 EXTSTATICDEG,
258 EXTSECVARDEG,
259 GEOMAGREFRAD,
260 NORMALIZATION,
261 SPATBASFUNC
262};
263
264enum COEFFICIENTS { IE, N, M, GNM, HNM, DGNM, DHNM };
265
266enum YYYYMMDD { YEAR, MONTH, DAY };
267
268/*Prototypes */
269
270/*Functions that should be Magnetic Model member functions*/
271
272/*Wrapper Functions*/
273int MAG_Geomag(MAGtype_Ellipsoid Ellip, MAGtype_CoordSpherical CoordSpherical,
274 MAGtype_CoordGeodetic CoordGeodetic,
275 MAGtype_MagneticModel *TimedMagneticModel,
276 MAGtype_GeoMagneticElements *GeoMagneticElements);
277
278void MAG_Gradient(MAGtype_Ellipsoid Ellip, MAGtype_CoordGeodetic CoordGeodetic,
279 MAGtype_MagneticModel *TimedMagneticModel,
280 MAGtype_Gradient *Gradient);
281
282int MAG_robustReadMagneticModel_Large(char *filename, char *filenameSV,
283 MAGtype_MagneticModel **MagneticModel);
284
285int MAG_robustReadMagModels(char *filename,
286 MAGtype_MagneticModel *(*magneticmodels)[1]);
287
288int MAG_SetDefaults(MAGtype_Ellipsoid *Ellip, MAGtype_Geoid *Geoid);
289
290/*User Interface*/
291
292void MAG_Error(int control);
293
294int MAG_GetUserGrid(MAGtype_CoordGeodetic *minimum,
295 MAGtype_CoordGeodetic *maximum, double *step_size,
296 double *a_step_size, double *step_time,
297 MAGtype_Date *StartDate, MAGtype_Date *EndDate,
298 int *ElementOption, int *PrintOption, char *OutputFile,
299 MAGtype_Geoid *Geoid);
300
301int MAG_GetUserInput(MAGtype_MagneticModel *MagneticModel, MAGtype_Geoid *Geoid,
302 MAGtype_CoordGeodetic *CoordGeodetic,
303 MAGtype_Date *MagneticDate);
304
305void MAG_PrintGradient(MAGtype_Gradient Gradient);
306
307void MAG_PrintUserData(MAGtype_GeoMagneticElements GeomagElements,
308 MAGtype_CoordGeodetic SpaceInput, MAGtype_Date TimeInput,
309 MAGtype_MagneticModel *MagneticModel,
310 MAGtype_Geoid *Geoid);
311
312int MAG_ValidateDMSstring(char *input, int min, int max, char *Error);
313
314int MAG_Warnings(int control, double value,
315 MAGtype_MagneticModel *MagneticModel);
316
317/*Memory and File Processing*/
318
319MAGtype_LegendreFunction *MAG_AllocateLegendreFunctionMemory(int NumTerms);
320
321MAGtype_MagneticModel *MAG_AllocateModelMemory(int NumTerms);
322
323MAGtype_SphericalHarmonicVariables *MAG_AllocateSphVarMemory(int nMax);
324
325void MAG_AssignHeaderValues(MAGtype_MagneticModel *model,
326 char values[][MAXLINELENGTH]);
327
328void MAG_AssignMagneticModelCoeffs(MAGtype_MagneticModel *Assignee,
329 MAGtype_MagneticModel *Source, int nMax,
330 int nMaxSecVar);
331
332int MAG_FreeMemory(MAGtype_MagneticModel *MagneticModel,
333 MAGtype_MagneticModel *TimedMagneticModel,
334 MAGtype_LegendreFunction *LegendreFunction);
335
336int MAG_FreeLegendreMemory(MAGtype_LegendreFunction *LegendreFunction);
337
338int MAG_FreeMagneticModelMemory(MAGtype_MagneticModel *MagneticModel);
339
340int MAG_FreeSphVarMemory(MAGtype_SphericalHarmonicVariables *SphVar);
341
342void MAG_PrintWMMFormat(char *filename, MAGtype_MagneticModel *MagneticModel);
343
344void MAG_PrintEMMFormat(char *filename, char *filenameSV,
345 MAGtype_MagneticModel *MagneticModel);
346
347void MAG_PrintSHDFFormat(char *filename,
348 MAGtype_MagneticModel *(*MagneticModel)[1]);
349
350int MAG_readMagneticModel(char *filename, MAGtype_MagneticModel *MagneticModel);
351
352int MAG_readMagneticModel_Large(char *filename, char *filenameSV,
353 MAGtype_MagneticModel *MagneticModel);
354
355int MAG_readMagneticModel_SHDF(char *filename,
356 MAGtype_MagneticModel *(*magneticmodels)[1]);
357
358char *MAG_Trim(char *str);
359
360/*Conversions, Transformations, and other Calculations*/
361void MAG_BaseErrors(double DeclCoef, double DeclBaseline, double InclOffset,
362 double FOffset, double Multiplier, double H,
363 double *DeclErr, double *InclErr, double *FErr);
364
365int MAG_CalculateGeoMagneticElements(
366 MAGtype_MagneticResults *MagneticResultsGeo,
367 MAGtype_GeoMagneticElements *GeoMagneticElements);
368
369void MAG_CalculateGradientElements(MAGtype_MagneticResults GradResults,
370 MAGtype_GeoMagneticElements MagneticElements,
371 MAGtype_GeoMagneticElements *GradElements);
372
373int MAG_CalculateSecularVariationElements(
374 MAGtype_MagneticResults MagneticVariation,
375 MAGtype_GeoMagneticElements *MagneticElements);
376
377int MAG_CalculateGridVariation(MAGtype_CoordGeodetic location,
379
380void MAG_CartesianToGeodetic(MAGtype_Ellipsoid Ellip, double x, double y,
381 double z, MAGtype_CoordGeodetic *CoordGeodetic);
382
383MAGtype_CoordGeodetic MAG_CoordGeodeticAssign(
384 MAGtype_CoordGeodetic CoordGeodetic);
385
386int MAG_DateToYear(MAGtype_Date *Calendar_Date, char *Error);
387
388void MAG_DegreeToDMSstring(double DegreesOfArc, int UnitDepth, char *DMSstring);
389
390void MAG_DMSstringToDegree(char *DMSstring, double *DegreesOfArc);
391
392void MAG_ErrorCalc(MAGtype_GeoMagneticElements B,
394
395int MAG_GeodeticToSpherical(MAGtype_Ellipsoid Ellip,
396 MAGtype_CoordGeodetic CoordGeodetic,
397 MAGtype_CoordSpherical *CoordSpherical);
398
399MAGtype_GeoMagneticElements MAG_GeoMagneticElementsAssign(
401
402MAGtype_GeoMagneticElements MAG_GeoMagneticElementsScale(
403 MAGtype_GeoMagneticElements Elements, double factor);
404
405MAGtype_GeoMagneticElements MAG_GeoMagneticElementsSubtract(
407 MAGtype_GeoMagneticElements subtrahend);
408
409int MAG_GetTransverseMercator(MAGtype_CoordGeodetic CoordGeodetic,
410 MAGtype_UTMParameters *UTMParameters);
411
412int MAG_GetUTMParameters(double Latitude, double Longitude, int *Zone,
413 char *Hemisphere, double *CentralMeridian);
414
415int MAG_isNaN(double d);
416
417int MAG_RotateMagneticVector(MAGtype_CoordSpherical,
418 MAGtype_CoordGeodetic CoordGeodetic,
419 MAGtype_MagneticResults MagneticResultsSph,
420 MAGtype_MagneticResults *MagneticResultsGeo);
421
422void MAG_SphericalToCartesian(MAGtype_CoordSpherical CoordSpherical, double *x,
423 double *y, double *z);
424
425void MAG_SphericalToGeodetic(MAGtype_Ellipsoid Ellip,
426 MAGtype_CoordSpherical CoordSpherical,
427 MAGtype_CoordGeodetic *CoordGeodetic);
428
429void MAG_TMfwd4(double Eps, double Epssq, double K0R4, double K0R4oa,
430 double Acoeff[], double Lam0, double K0, double falseE,
431 double falseN, int XYonly, double Lambda, double Phi, double *X,
432 double *Y, double *pscale, double *CoM);
433
434int MAG_YearToDate(MAGtype_Date *Date);
435
436/*Spherical Harmonics*/
437
438int MAG_AssociatedLegendreFunction(MAGtype_CoordSpherical CoordSpherical,
439 int nMax,
440 MAGtype_LegendreFunction *LegendreFunction);
441
442int MAG_CheckGeographicPole(MAGtype_CoordGeodetic *CoordGeodetic);
443
444int MAG_ComputeSphericalHarmonicVariables(
445 MAGtype_Ellipsoid Ellip, MAGtype_CoordSpherical CoordSpherical, int nMax,
447
448void MAG_GradY(MAGtype_Ellipsoid Ellip, MAGtype_CoordSpherical CoordSpherical,
449 MAGtype_CoordGeodetic CoordGeodetic,
450 MAGtype_MagneticModel *TimedMagneticModel,
451 MAGtype_GeoMagneticElements GeoMagneticElements,
452 MAGtype_GeoMagneticElements *GradYElements);
453
454void MAG_GradYSummation(MAGtype_LegendreFunction *LegendreFunction,
455 MAGtype_MagneticModel *MagneticModel,
457 MAGtype_CoordSpherical CoordSpherical,
459
460int MAG_PcupHigh(double *Pcup, double *dPcup, double x, int nMax);
461
462int MAG_PcupLow(double *Pcup, double *dPcup, double x, int nMax);
463
464int MAG_SecVarSummation(MAGtype_LegendreFunction *LegendreFunction,
465 MAGtype_MagneticModel *MagneticModel,
467 MAGtype_CoordSpherical CoordSpherical,
468 MAGtype_MagneticResults *MagneticResults);
469
470int MAG_SecVarSummationSpecial(MAGtype_MagneticModel *MagneticModel,
472 MAGtype_CoordSpherical CoordSpherical,
473 MAGtype_MagneticResults *MagneticResults);
474
475int MAG_Summation(MAGtype_LegendreFunction *LegendreFunction,
476 MAGtype_MagneticModel *MagneticModel,
478 MAGtype_CoordSpherical CoordSpherical,
479 MAGtype_MagneticResults *MagneticResults);
480
481int MAG_SummationSpecial(MAGtype_MagneticModel *MagneticModel,
483 MAGtype_CoordSpherical CoordSpherical,
484 MAGtype_MagneticResults *MagneticResults);
485
486int MAG_TimelyModifyMagneticModel(MAGtype_Date UserDate,
487 MAGtype_MagneticModel *MagneticModel,
488 MAGtype_MagneticModel *TimedMagneticModel);
489
490/*Geoid*/
491
492int MAG_ConvertGeoidToEllipsoidHeight(MAGtype_CoordGeodetic *CoordGeodetic,
493 MAGtype_Geoid *Geoid);
494/*
495 * The function Convert_Geoid_To_Ellipsoid_Height converts the specified WGS84
496 * geoid height at the specified geodetic coordinates to the equivalent
497 * ellipsoid height, using the EGM96 gravity model.
498 *
499 * Latitude : Geodetic latitude in radians (input)
500 * Longitude : Geodetic longitude in radians (input)
501 * Geoid_Height : Geoid height, in meters (input)
502 * Ellipsoid_Height : Ellipsoid height, in meters. (output)
503 *
504 */
505
506int MAG_GetGeoidHeight(double Latitude, double Longitude, double *DeltaHeight,
507 MAGtype_Geoid *Geoid);
508/*
509 * The private function Get_Geoid_Height returns the height of the
510 * WGS84 geiod above or below the WGS84 ellipsoid,
511 * at the specified geodetic coordinates,
512 * using a grid of height adjustments from the EGM96 gravity model.
513 *
514 * Latitude : Geodetic latitude in radians (input)
515 * Longitude : Geodetic longitude in radians (input)
516 * DeltaHeight : Height Adjustment, in meters. (output)
517 *
518 */
519
520void MAG_EquivalentLatLon(double lat, double lon, double *repairedLat,
521 double *repairedLon);
522
523void MAG_WMMErrorCalc(double H, MAGtype_GeoMagneticElements *Uncertainty);
524void MAG_PrintUserDataWithUncertainty(
525 MAGtype_GeoMagneticElements GeomagElements,
527 MAGtype_Date TimeInput, MAGtype_MagneticModel *MagneticModel,
528 MAGtype_Geoid *Geoid);
529
530void MAG_GetDeg(char *Query_String, double *latitude, double bounds[2]);
531int MAG_GetAltitude(char *Query_String, MAGtype_Geoid *Geoid,
532 MAGtype_CoordGeodetic *coords, int bounds[2],
533 int AltitudeSetting);
534
535#ifdef __cplusplus
536}
537#endif /* __cplusplus */
538
539#endif /*GEOMAGHEADER_H*/