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