QGIS API Documentation 3.99.0-Master (d270888f95f)
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#include <QString>
21
22using namespace Qt::StringLiterals;
23
24#ifdef WITH_GEOGRAPHICLIB
25#include <GeographicLib/MagneticModel.hpp>
26#else
27#include "qgsexception.h"
28#endif
29
31{
32#ifdef WITH_GEOGRAPHICLIB
33 return QString::fromStdString( GeographicLib::MagneticModel::DefaultMagneticPath() );
34#else
35 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
36#endif
37}
38
40{
41#ifdef WITH_GEOGRAPHICLIB
42 return QString::fromStdString( GeographicLib::MagneticModel::DefaultMagneticName() );
43#else
44 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
45#endif
46}
47
48QgsMagneticModel::QgsMagneticModel( const QString &name, const QString &path, int nMax, int mMax )
49 : mName( name )
50 , mPath( path )
51{
52#ifdef WITH_GEOGRAPHICLIB
53 try
54 {
55 mModel = std::make_unique< GeographicLib::MagneticModel >( mName.toStdString(), mPath.toStdString(), GeographicLib::Geocentric::WGS84(), nMax, mMax );
56 }
57 catch ( GeographicLib::GeographicErr &e )
58 {
59 mError = QString::fromStdString( e.what() );
60 }
61 catch ( std::bad_alloc &e )
62 {
63 mError = QString::fromStdString( e.what() );
64 }
65#else
66 ( void ) nMax;
67 ( void ) mMax;
68#endif
69}
70
72
74{
75#ifdef WITH_GEOGRAPHICLIB
76 return static_cast< bool >( mModel );
77#else
78 return false;
79#endif
80}
81
83{
84#ifdef WITH_GEOGRAPHICLIB
85 if ( !mModel )
86 return QString();
87
88 const QString desc = QString::fromStdString( mModel->Description() );
89 return desc == "UNKNOWN"_L1 ? QString() : desc;
90#else
91 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
92#endif
93}
94
96{
97#ifdef WITH_GEOGRAPHICLIB
98 if ( !mModel )
99 return QDateTime();
100
101 const QString dt = QString::fromStdString( mModel->DateTime() );
102 if ( dt == "UNKNOWN"_L1 )
103 return QDateTime();
104
105 return QDateTime::fromString( dt, Qt::ISODate );
106#else
107 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
108#endif
109}
110
112{
113#ifdef WITH_GEOGRAPHICLIB
114 return mModel ? QString::fromStdString( mModel->MagneticFile() ) : QString();
115#else
116 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
117#endif
118}
119
121{
122#ifdef WITH_GEOGRAPHICLIB
123 return mModel ? QString::fromStdString( mModel->MagneticModelDirectory() ) : QString();
124#else
125 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
126#endif
127}
128
130{
131#ifdef WITH_GEOGRAPHICLIB
132 return mModel ? QString::fromStdString( mModel->MagneticModelName() ) : QString();
133#else
134 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
135#endif
136}
137
139{
140#ifdef WITH_GEOGRAPHICLIB
141 return mModel ? mModel->MinHeight() : 0;
142#else
143 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
144#endif
145}
146
148{
149#ifdef WITH_GEOGRAPHICLIB
150 return mModel ? mModel->MaxHeight() : 0;
151#else
152 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
153#endif
154}
155
157{
158#ifdef WITH_GEOGRAPHICLIB
159 return mModel ? mModel->MinTime() : 0;
160#else
161 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
162#endif
163}
164
166{
167#ifdef WITH_GEOGRAPHICLIB
168 return mModel ? mModel->MaxTime() : 0;
169#else
170 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
171#endif
172}
173
175{
176#ifdef WITH_GEOGRAPHICLIB
177 return mModel ? mModel->Degree() : 0;
178#else
179 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
180#endif
181}
182
184{
185#ifdef WITH_GEOGRAPHICLIB
186 return mModel ? mModel->Order() : 0;
187#else
188 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
189#endif
190}
191
192bool QgsMagneticModel::declination( double years, double latitude, double longitude, double height, double &declination ) const
193{
194 declination = 0;
195#ifdef WITH_GEOGRAPHICLIB
196 double Bx = 0;
197 double By = 0;
198 double Bz = 0;
199 if ( !getComponents( years, latitude, longitude, height, Bx, By, Bz ) )
200 return false;
201
202 double H = 0;
203 double F = 0;
204 double I = 0;
205 if ( !fieldComponents( Bx, By, Bz, H, F, declination, I ) )
206 return false;
207
208 return true;
209#else
210 ( void )years;
211 ( void )latitude;
212 ( void )longitude;
213 ( void )height;
214 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
215#endif
216}
217
218bool QgsMagneticModel::inclination( double years, double latitude, double longitude, double height, double &inclination ) const
219{
220 inclination = 0;
221#ifdef WITH_GEOGRAPHICLIB
222 double Bx = 0;
223 double By = 0;
224 double Bz = 0;
225 if ( !getComponents( years, latitude, longitude, height, Bx, By, Bz ) )
226 return false;
227
228 double H = 0;
229 double F = 0;
230 double D = 0;
231 if ( !fieldComponents( Bx, By, Bz, H, F, D, inclination ) )
232 return false;
233
234 return true;
235#else
236 ( void )years;
237 ( void )latitude;
238 ( void )longitude;
239 ( void )height;
240 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
241#endif
242}
243
244bool QgsMagneticModel::getComponents( double years, double latitude, double longitude, double height, double &Bx, double &By, double &Bz ) const
245{
246 Bx = 0;
247 By = 0;
248 Bz = 0;
249#ifdef WITH_GEOGRAPHICLIB
250 if ( !mModel )
251 return false;
252
253 ( *mModel )( years, latitude, longitude, height, Bx, By, Bz );
254 return true;
255#else
256 ( void ) years;
257 ( void ) latitude;
258 ( void ) longitude;
259 ( void ) height;
260 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
261#endif
262}
263
264bool QgsMagneticModel::getComponentsWithTimeDerivatives( double years, double latitude, double longitude, double height, double &Bx, double &By, double &Bz, double &Bxt, double &Byt, double &Bzt ) const
265{
266 Bx = 0;
267 By = 0;
268 Bz = 0;
269 Bxt = 0;
270 Byt = 0;
271 Bzt = 0;
272#ifdef WITH_GEOGRAPHICLIB
273 if ( !mModel )
274 return false;
275
276 ( *mModel )( years, latitude, longitude, height, Bx, By, Bz, Bxt, Byt, Bzt );
277 return true;
278#else
279 ( void ) years;
280 ( void ) latitude;
281 ( void ) longitude;
282 ( void ) height;
283 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
284#endif
285}
286
287bool QgsMagneticModel::fieldComponents( double Bx, double By, double Bz, double &H, double &F, double &D, double &I )
288{
289 H = 0;
290 F = 0;
291 D = 0;
292 I = 0;
293#ifdef WITH_GEOGRAPHICLIB
294 GeographicLib::MagneticModel::FieldComponents( Bx, By, Bz, H, F, D, I );
295 return true;
296#else
297 ( void ) Bx;
298 ( void ) By;
299 ( void ) Bz;
300 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
301#endif
302}
303
304bool 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 )
305{
306 H = 0;
307 F = 0;
308 D = 0;
309 I = 0;
310 Ht = 0;
311 Ft = 0;
312 Dt = 0;
313 It = 0;
314#ifdef WITH_GEOGRAPHICLIB
315 GeographicLib::MagneticModel::FieldComponents( Bx, By, Bz, Bxt, Byt, Bzt, H, F, D, I, Ht, Ft, Dt, It );
316 return true;
317#else
318 ( void ) Bx;
319 ( void ) By;
320 ( void ) Bz;
321 ( void ) Bxt;
322 ( void ) Byt;
323 ( void ) Bzt;
324 throw QgsNotSupportedException( u"GeographicLib is not available on this system"_s );
325#endif
326}
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.