QGIS API Documentation 3.99.0-Master (a8882ad4560)
Loading...
Searching...
No Matches
qgsmagneticmodel.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmagneticmodel.cpp
3 ---------------------------
4 begin : December 2025
5 copyright : (C) 2025 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgsmagneticmodel.h"
19
20#ifdef WITH_GEOGRAPHICLIB
21#include <GeographicLib/MagneticModel.hpp>
22#else
23#include "qgsexception.h"
24#endif
25
27{
28#ifdef WITH_GEOGRAPHICLIB
29 return QString::fromStdString( GeographicLib::MagneticModel::DefaultMagneticPath() );
30#else
31 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
32#endif
33}
34
36{
37#ifdef WITH_GEOGRAPHICLIB
38 return QString::fromStdString( GeographicLib::MagneticModel::DefaultMagneticName() );
39#else
40 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
41#endif
42}
43
44QgsMagneticModel::QgsMagneticModel( const QString &name, const QString &path, int nMax, int mMax )
45 : mName( name )
46 , mPath( path )
47{
48#ifdef WITH_GEOGRAPHICLIB
49 try
50 {
51 mModel = std::make_unique< GeographicLib::MagneticModel >( mName.toStdString(), mPath.toStdString(), GeographicLib::Geocentric::WGS84(), nMax, mMax );
52 }
53 catch ( GeographicLib::GeographicErr &e )
54 {
55 mError = QString::fromStdString( e.what() );
56 }
57 catch ( std::bad_alloc &e )
58 {
59 mError = QString::fromStdString( e.what() );
60 }
61#else
62 ( void ) nMax;
63 ( void ) mMax;
64#endif
65}
66
68
70{
71#ifdef WITH_GEOGRAPHICLIB
72 return static_cast< bool >( mModel );
73#else
74 return false;
75#endif
76}
77
79{
80#ifdef WITH_GEOGRAPHICLIB
81 if ( !mModel )
82 return QString();
83
84 const QString desc = QString::fromStdString( mModel->Description() );
85 return desc == "UNKNOWN"_L1 ? QString() : desc;
86#else
87 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
88#endif
89}
90
92{
93#ifdef WITH_GEOGRAPHICLIB
94 if ( !mModel )
95 return QDateTime();
96
97 const QString dt = QString::fromStdString( mModel->DateTime() );
98 if ( dt == "UNKNOWN"_L1 )
99 return QDateTime();
100
101 return QDateTime::fromString( dt, Qt::ISODate );
102#else
103 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
104#endif
105}
106
108{
109#ifdef WITH_GEOGRAPHICLIB
110 return mModel ? QString::fromStdString( mModel->MagneticFile() ) : QString();
111#else
112 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
113#endif
114}
115
117{
118#ifdef WITH_GEOGRAPHICLIB
119 return mModel ? QString::fromStdString( mModel->MagneticModelDirectory() ) : QString();
120#else
121 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
122#endif
123}
124
126{
127#ifdef WITH_GEOGRAPHICLIB
128 return mModel ? QString::fromStdString( mModel->MagneticModelName() ) : QString();
129#else
130 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
131#endif
132}
133
135{
136#ifdef WITH_GEOGRAPHICLIB
137 return mModel ? mModel->MinHeight() : 0;
138#else
139 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
140#endif
141}
142
144{
145#ifdef WITH_GEOGRAPHICLIB
146 return mModel ? mModel->MaxHeight() : 0;
147#else
148 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
149#endif
150}
151
153{
154#ifdef WITH_GEOGRAPHICLIB
155 return mModel ? mModel->MinTime() : 0;
156#else
157 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
158#endif
159}
160
162{
163#ifdef WITH_GEOGRAPHICLIB
164 return mModel ? mModel->MaxTime() : 0;
165#else
166 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
167#endif
168}
169
171{
172#ifdef WITH_GEOGRAPHICLIB
173 return mModel ? mModel->Degree() : 0;
174#else
175 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
176#endif
177}
178
180{
181#ifdef WITH_GEOGRAPHICLIB
182 return mModel ? mModel->Order() : 0;
183#else
184 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
185#endif
186}
187
188bool QgsMagneticModel::declination( double years, double latitude, double longitude, double height, double &declination ) const
189{
190 declination = 0;
191#ifdef WITH_GEOGRAPHICLIB
192 double Bx = 0;
193 double By = 0;
194 double Bz = 0;
195 if ( !getComponents( years, latitude, longitude, height, Bx, By, Bz ) )
196 return false;
197
198 double H = 0;
199 double F = 0;
200 double I = 0;
201 if ( !fieldComponents( Bx, By, Bz, H, F, declination, I ) )
202 return false;
203
204 return true;
205#else
206 ( void )years;
207 ( void )latitude;
208 ( void )longitude;
209 ( void )height;
210 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
211#endif
212}
213
214bool QgsMagneticModel::inclination( double years, double latitude, double longitude, double height, double &inclination ) const
215{
216 inclination = 0;
217#ifdef WITH_GEOGRAPHICLIB
218 double Bx = 0;
219 double By = 0;
220 double Bz = 0;
221 if ( !getComponents( years, latitude, longitude, height, Bx, By, Bz ) )
222 return false;
223
224 double H = 0;
225 double F = 0;
226 double D = 0;
227 if ( !fieldComponents( Bx, By, Bz, H, F, D, inclination ) )
228 return false;
229
230 return true;
231#else
232 ( void )years;
233 ( void )latitude;
234 ( void )longitude;
235 ( void )height;
236 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
237#endif
238}
239
240bool QgsMagneticModel::getComponents( double years, double latitude, double longitude, double height, double &Bx, double &By, double &Bz ) const
241{
242 Bx = 0;
243 By = 0;
244 Bz = 0;
245#ifdef WITH_GEOGRAPHICLIB
246 if ( !mModel )
247 return false;
248
249 ( *mModel )( years, latitude, longitude, height, Bx, By, Bz );
250 return true;
251#else
252 ( void ) years;
253 ( void ) latitude;
254 ( void ) longitude;
255 ( void ) height;
256 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
257#endif
258}
259
260bool QgsMagneticModel::getComponentsWithTimeDerivatives( double years, double latitude, double longitude, double height, double &Bx, double &By, double &Bz, double &Bxt, double &Byt, double &Bzt ) const
261{
262 Bx = 0;
263 By = 0;
264 Bz = 0;
265 Bxt = 0;
266 Byt = 0;
267 Bzt = 0;
268#ifdef WITH_GEOGRAPHICLIB
269 if ( !mModel )
270 return false;
271
272 ( *mModel )( years, latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt );
273 return true;
274#else
275 ( void ) years;
276 ( void ) latitude;
277 ( void ) longitude;
278 ( void ) height;
279 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
280#endif
281}
282
283bool QgsMagneticModel::fieldComponents( double Bx, double By, double Bz, double &H, double &F, double &D, double &I )
284{
285 H = 0;
286 F = 0;
287 D = 0;
288 I = 0;
289#ifdef WITH_GEOGRAPHICLIB
290 GeographicLib::MagneticModel::FieldComponents( Bx, By, Bz, H, F, D, I );
291 return true;
292#else
293 ( void ) Bx;
294 ( void ) By;
295 ( void ) Bz;
296 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
297#endif
298}
299
300bool QgsMagneticModel::fieldComponentsWithTimeDerivatives( double Bx, double By, double Bz, double Bxt, double Byt, double Bzt, double &H, double &F, double &D, double &I, double &Ht, double &Ft, double &Dt, double &It )
301{
302 H = 0;
303 F = 0;
304 D = 0;
305 I = 0;
306 Ht = 0;
307 Ft = 0;
308 Dt = 0;
309 It = 0;
310#ifdef WITH_GEOGRAPHICLIB
311 GeographicLib::MagneticModel::FieldComponents( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It );
312 return true;
313#else
314 ( void ) Bx;
315 ( void ) By;
316 ( void ) Bz;
317 ( void ) Bxt;
318 ( void ) Byt;
319 ( void ) Bzt;
320 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
321#endif
322}
bool getComponents(double years, double latitude, double longitude, double height, double &Bx, double &By, double &Bz) const
Evaluates the components of the geomagnetic field at a point.
static QString defaultFilePath()
Returns the default path used by GeographicLib to search for magnetic models.
int order() const
Returns the maximum order of the components of the model.
QString description() const
Returns the description of the magnetic model, if available.
double minimumHeight() const
Returns the minimum height above the ellipsoid (in meters) for which the model should be used.
QString file() const
Returns the full file name for the magnetic model.
bool isValid() const
Returns true if the model is valid and can be used.
bool declination(double years, double latitude, double longitude, double height, double &declination) const
Calculates the declination of the field at a point.
double maximumYear() const
Returns the maximum time (in decimal years) for which the model should be used.
QString name() const
Returns the name of the magnetic model.
static bool fieldComponentsWithTimeDerivatives(double Bx, double By, double Bz, double Bxt, double Byt, double Bzt, double &H, double &F, double &D, double &I, double &Ht, double &Ft, double &Dt, double &It)
Compute various quantities dependent on a magnetic field and their rates of change.
QString directory() const
Returns the full directory name containing the magnetic model file.
bool getComponentsWithTimeDerivatives(double years, double latitude, double longitude, double height, double &Bx, double &By, double &Bz, double &Bxt, double &Byt, double &Bzt) const
Evaluates the components of the geomagnetic field at a point, and their time derivatives.
int degree() const
Returns the maximum degree of the components of the model.
double minimumYear() const
Returns the minimum time (in decimal years) for which the model should be used.
QDateTime dateTime() const
Returns the date of the magnetic model, if available.
bool inclination(double years, double latitude, double longitude, double height, double &inclination) const
Calculates the inclination of the field at a point.
double maximumHeight() const
Returns the maximum height above the ellipsoid (in meters) for which the model should be used.
static QString defaultModelName()
Returns the name of the default magnetic model used by GeographicLib.
static bool fieldComponents(double Bx, double By, double Bz, double &H, double &F, double &D, double &I)
Compute various quantities dependent on a magnetic field.
QgsMagneticModel(const QString &name, const QString &path=QString(), int maxDegree=-1, int maxOrder=-1)
Constructor for QgsMagneticModel.
Custom exception class which is raised when an operation is not supported.