QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsellipsoidutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsellipsoidutils.cpp
3  ----------------------
4  Date : April 2017
5  Copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsellipsoidutils.h"
17 #include "qgsapplication.h"
18 #include "qgslogger.h"
19 #include "qgsmessagelog.h"
20 #include <sqlite3.h>
21 #include <QCollator>
22 #include "qgsprojutils.h"
23 #include "qgsreadwritelocker.h"
24 #include "qgsruntimeprofiler.h"
25 
26 #if PROJ_VERSION_MAJOR>=6
27 #include <proj.h>
28 #include <mutex>
29 #endif
30 
31 Q_GLOBAL_STATIC( QReadWriteLock, sEllipsoidCacheLock )
32 typedef QHash< QString, QgsEllipsoidUtils::EllipsoidParameters > EllipsoidParamCache;
33 Q_GLOBAL_STATIC( EllipsoidParamCache, sEllipsoidCache )
34 
35 Q_GLOBAL_STATIC( QReadWriteLock, sDefinitionCacheLock );
36 typedef QList< QgsEllipsoidUtils::EllipsoidDefinition > EllipsoidDefinitionCache;
37 Q_GLOBAL_STATIC( EllipsoidDefinitionCache, sDefinitionCache )
38 
39 static bool sDisableCache = false;
40 
41 QgsEllipsoidUtils::EllipsoidParameters QgsEllipsoidUtils::ellipsoidParameters( const QString &e )
42 {
43 // maps older QGIS ellipsoid acronyms to proj acronyms/names
44  static const QMap< QString, QString > sProj6EllipsoidAcronymMap
45  {
46  { "clrk80", "clrk80ign" },
47  {"Adrastea2000", "ESRI:107909"},
48  {"Amalthea2000", "ESRI:107910"},
49  {"Ananke2000", "ESRI:107911"},
50  {"Ariel2000", "ESRI:107945"},
51  {"Atlas2000", "ESRI:107926"},
52  {"Belinda2000", "ESRI:107946"},
53  {"Bianca2000", "ESRI:107947"},
54  {"Callisto2000", "ESRI:107912"},
55  {"Calypso2000", "ESRI:107927"},
56  {"Carme2000", "ESRI:107913"},
57  {"Charon2000", "ESRI:107970"},
58  {"Cordelia2000", "ESRI:107948"},
59  {"Cressida2000", "ESRI:107949"},
60  {"Deimos2000", "ESRI:107906"},
61  {"Desdemona2000", "ESRI:107950"},
62  {"Despina2000", "ESRI:107961"},
63  {"Dione2000", "ESRI:107928"},
64  {"Elara2000", "ESRI:107914"},
65  {"Enceladus2000", "ESRI:107929"},
66  {"Epimetheus2000", "ESRI:107930"},
67  {"Europa2000", "ESRI:107915"},
68  {"Galatea2000", "ESRI:107962"},
69  {"Ganymede2000", "ESRI:107916"},
70  {"Helene2000", "ESRI:107931"},
71  {"Himalia2000", "ESRI:107917"},
72  {"Hyperion2000", "ESRI:107932"},
73  {"Iapetus2000", "ESRI:107933"},
74  {"Io2000", "ESRI:107918"},
75  {"Janus2000", "ESRI:107934"},
76  {"Juliet2000", "ESRI:107951"},
77  {"Jupiter2000", "ESRI:107908"},
78  {"Larissa2000", "ESRI:107963"},
79  {"Leda2000", "ESRI:107919"},
80  {"Lysithea2000", "ESRI:107920"},
81  {"Mars2000", "ESRI:107905"},
82  {"Mercury2000", "ESRI:107900"},
83  {"Metis2000", "ESRI:107921"},
84  {"Mimas2000", "ESRI:107935"},
85  {"Miranda2000", "ESRI:107952"},
86  {"Moon2000", "ESRI:107903"},
87  {"Naiad2000", "ESRI:107964"},
88  {"Neptune2000", "ESRI:107960"},
89  {"Nereid2000", "ESRI:107965"},
90  {"Oberon2000", "ESRI:107953"},
91  {"Ophelia2000", "ESRI:107954"},
92  {"Pan2000", "ESRI:107936"},
93  {"Pandora2000", "ESRI:107937"},
94  {"Pasiphae2000", "ESRI:107922"},
95  {"Phobos2000", "ESRI:107907"},
96  {"Phoebe2000", "ESRI:107938"},
97  {"Pluto2000", "ESRI:107969"},
98  {"Portia2000", "ESRI:107955"},
99  {"Prometheus2000", "ESRI:107939"},
100  {"Proteus2000", "ESRI:107966"},
101  {"Puck2000", "ESRI:107956"},
102  {"Rhea2000", "ESRI:107940"},
103  {"Rosalind2000", "ESRI:107957"},
104  {"Saturn2000", "ESRI:107925"},
105  {"Sinope2000", "ESRI:107923"},
106  {"Telesto2000", "ESRI:107941"},
107  {"Tethys2000", "ESRI:107942"},
108  {"Thalassa2000", "ESRI:107967"},
109  {"Thebe2000", "ESRI:107924"},
110  {"Titan2000", "ESRI:107943"},
111  {"Titania2000", "ESRI:107958"},
112  {"Triton2000", "ESRI:107968"},
113  {"Umbriel2000", "ESRI:107959"},
114  {"Uranus2000", "ESRI:107944"},
115  {"Venus2000", "ESRI:107902"},
116  {"IGNF:ELG053", "EPSG:7030"},
117  {"IGNF:ELG052", "EPSG:7043"},
118  {"IGNF:ELG102", "EPSG:7043"},
119  {"WGS66", "ESRI:107001"},
120  {"plessis", "EPSG:7027"},
121  {"IGNF:ELG017", "EPSG:7027"},
122  {"mod_airy", "EPSG:7002"},
123  {"IGNF:ELG037", "EPSG:7019"},
124  {"IGNF:ELG108", "EPSG:7036"},
125  {"cape", "EPSG:7034"},
126  {"IGNF:ELG010", "EPSG:7011"},
127  {"IGNF:ELG003", "EPSG:7012"},
128  {"IGNF:ELG004", "EPSG:7008"},
129  {"GSK2011", "EPSG:1025"},
130  {"airy", "EPSG:7001"},
131  {"aust_SA", "EPSG:7003"},
132  {"bessel", "EPSG:7004"},
133  {"clrk66", "EPSG:7008"},
134  {"clrk80ign", "EPSG:7011"},
135  {"evrst30", "EPSG:7015"},
136  {"evrstSS", "EPSG:7016"},
137  {"evrst48", "EPSG:7018"},
138  {"GRS80", "EPSG:7019"},
139  {"helmert", "EPSG:7020"},
140  {"intl", "EPSG:7022"},
141  {"krass", "EPSG:7024"},
142  {"NWL9D", "EPSG:7025"},
143  {"WGS84", "EPSG:7030"},
144  {"GRS67", "EPSG:7036"},
145  {"WGS72", "EPSG:7043"},
146  {"bess_nam", "EPSG:7046"},
147  {"IAU76", "EPSG:7049"},
148  {"sphere", "EPSG:7052"},
149  {"hough", "EPSG:7053"},
150  {"evrst69", "EPSG:7056"},
151  {"fschr60", "ESRI:107002"},
152  {"fschr68", "ESRI:107003"},
153  {"fschr60m", "ESRI:107004"},
154  {"walbeck", "ESRI:107007"},
155  {"IGNF:ELG001", "EPSG:7022"},
156  {"engelis", "EPSG:7054"},
157  {"evrst56", "EPSG:7044"},
158  {"SEasia", "ESRI:107004"},
159  {"SGS85", "EPSG:7054"},
160  {"andrae", "PROJ:ANDRAE"},
161  {"clrk80", "EPSG:7034"},
162  {"CPM", "PROJ:CPM"},
163  {"delmbr", "PROJ:DELMBR"},
164  {"Earth2000", "PROJ:EARTH2000"},
165  {"kaula", "PROJ:KAULA"},
166  {"lerch", "PROJ:LERCH"},
167  {"MERIT", "PROJ:MERIT"},
168  {"mprts", "PROJ:MPRTS"},
169  {"new_intl", "PROJ:NEW_INTL"},
170  {"WGS60", "PROJ:WGS60"}
171  };
172 
173  QString ellipsoid = e;
174 #if PROJ_VERSION_MAJOR >= 6
175  // ensure ellipsoid database is populated when first called
176  static std::once_flag initialized;
177  std::call_once( initialized, [ = ]
178  {
179  QgsScopedRuntimeProfile profile( QObject::tr( "Initialize ellipsoids" ) );
180  ( void )definitions();
181  } );
182 
183  ellipsoid = sProj6EllipsoidAcronymMap.value( ellipsoid, ellipsoid ); // silently upgrade older QGIS acronyms to proj acronyms
184 #else
185  ( void )sProj6EllipsoidAcronymMap;
186 #endif
187 
188  // check cache
189  {
190  QgsReadWriteLocker locker( *sEllipsoidCacheLock(), QgsReadWriteLocker::Read );
191  if ( !sDisableCache )
192  {
193  QHash< QString, EllipsoidParameters >::const_iterator cacheIt = sEllipsoidCache()->constFind( ellipsoid );
194  if ( cacheIt != sEllipsoidCache()->constEnd() )
195  {
196  // found a match in the cache
197  QgsEllipsoidUtils::EllipsoidParameters params = cacheIt.value();
198  return params;
199  }
200  }
201  }
202 
203  EllipsoidParameters params;
204 
205  // Check if we have a custom projection, and set from text string.
206  // Format is "PARAMETER:<semi-major axis>:<semi minor axis>
207  // Numbers must be with (optional) decimal point and no other separators (C locale)
208  // Distances in meters. Flattening is calculated.
209  if ( ellipsoid.startsWith( QLatin1String( "PARAMETER" ) ) )
210  {
211  QStringList paramList = ellipsoid.split( ':' );
212  bool semiMajorOk, semiMinorOk;
213  double semiMajor = paramList[1].toDouble( & semiMajorOk );
214  double semiMinor = paramList[2].toDouble( & semiMinorOk );
215  if ( semiMajorOk && semiMinorOk )
216  {
217  params.semiMajor = semiMajor;
218  params.semiMinor = semiMinor;
219  params.inverseFlattening = semiMajor / ( semiMajor - semiMinor );
220  params.useCustomParameters = true;
221  }
222  else
223  {
224  params.valid = false;
225  }
226 
227  QgsReadWriteLocker locker( *sEllipsoidCacheLock(), QgsReadWriteLocker::Write );
228  if ( !sDisableCache )
229  {
230  sEllipsoidCache()->insert( ellipsoid, params );
231  }
232  return params;
233  }
234 
235 #if PROJ_VERSION_MAJOR< 6
236  // cache miss - get from database
237  // NOT REQUIRED FOR PROJ >= 6 -- we populate known types once by calling definitions() above
238 
239  QString radius, parameter2;
240  //
241  // SQLITE3 stuff - get parameters for selected ellipsoid
242  //
245  // Continue with PROJ list of ellipsoids.
246 
247  //check the db is available
248  int result = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
249  if ( result )
250  {
251  QgsMessageLog::logMessage( QObject::tr( "Can not open srs database (%1): %2" ).arg( QgsApplication::srsDatabaseFilePath(), database.errorMessage() ) );
252  // XXX This will likely never happen since on open, sqlite creates the
253  // database if it does not exist.
254  return params;
255  }
256  // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
257  QString sql = "select radius, parameter2 from tbl_ellipsoid where acronym='" + ellipsoid + '\'';
258  statement = database.prepare( sql, result );
259  // XXX Need to free memory from the error msg if one is set
260  if ( result == SQLITE_OK )
261  {
262  if ( statement.step() == SQLITE_ROW )
263  {
264  radius = statement.columnAsText( 0 );
265  parameter2 = statement.columnAsText( 1 );
266  }
267  }
268  // row for this ellipsoid wasn't found?
269  if ( radius.isEmpty() || parameter2.isEmpty() )
270  {
271  QgsDebugMsg( QStringLiteral( "setEllipsoid: no row in tbl_ellipsoid for acronym '%1'" ).arg( ellipsoid ) );
272  params.valid = false;
273  sEllipsoidCacheLock()->lockForWrite();
274  if ( !sDisableCache )
275  {
276  sEllipsoidCache()->insert( ellipsoid, params );
277  }
278  sEllipsoidCacheLock()->unlock();
279  return params;
280  }
281 
282  // get major semiaxis
283  if ( radius.left( 2 ) == QLatin1String( "a=" ) )
284  params.semiMajor = radius.midRef( 2 ).toDouble();
285  else
286  {
287  QgsDebugMsg( QStringLiteral( "setEllipsoid: wrong format of radius field: '%1'" ).arg( radius ) );
288  params.valid = false;
289  sEllipsoidCacheLock()->lockForWrite();
290  if ( !sDisableCache )
291  {
292  sEllipsoidCache()->insert( ellipsoid, params );
293  }
294  sEllipsoidCacheLock()->unlock();
295  return params;
296  }
297 
298  // get second parameter
299  // one of values 'b' or 'f' is in field parameter2
300  // second one must be computed using formula: invf = a/(a-b)
301  if ( parameter2.left( 2 ) == QLatin1String( "b=" ) )
302  {
303  params.semiMinor = parameter2.midRef( 2 ).toDouble();
304  params.inverseFlattening = params.semiMajor / ( params.semiMajor - params.semiMinor );
305  }
306  else if ( parameter2.left( 3 ) == QLatin1String( "rf=" ) )
307  {
308  params.inverseFlattening = parameter2.midRef( 3 ).toDouble();
309  params.semiMinor = params.semiMajor - ( params.semiMajor / params.inverseFlattening );
310  }
311  else
312  {
313  QgsDebugMsg( QStringLiteral( "setEllipsoid: wrong format of parameter2 field: '%1'" ).arg( parameter2 ) );
314  params.valid = false;
315  sEllipsoidCacheLock()->lockForWrite();
316  if ( !sDisableCache )
317  {
318  sEllipsoidCache()->insert( ellipsoid, params );
319  }
320  sEllipsoidCacheLock()->unlock();
321  return params;
322  }
323 
324  QgsDebugMsgLevel( QStringLiteral( "setEllipsoid: a=%1, b=%2, 1/f=%3" ).arg( params.semiMajor ).arg( params.semiMinor ).arg( params.inverseFlattening ), 4 );
325 
326 
327  // get spatial ref system for ellipsoid
328  QString proj4 = "+proj=longlat +ellps=" + ellipsoid + " +no_defs";
330  //TODO: createFromProj used to save to the user database any new CRS
331  // this behavior was changed in order to separate creation and saving.
332  // Not sure if it necessary to save it here, should be checked by someone
333  // familiar with the code (should also give a more descriptive name to the generated CRS)
334  if ( destCRS.srsid() == 0 )
335  {
336  QString name = QStringLiteral( " * %1 (%2)" )
337  .arg( QObject::tr( "Generated CRS", "A CRS automatically generated from layer info get this prefix for description" ),
338  destCRS.toProj() );
339  destCRS.saveAsUserCrs( name );
340  }
341  //
342 
343  // set transformation from project CRS to ellipsoid coordinates
344  params.crs = destCRS;
345 
346  sEllipsoidCacheLock()->lockForWrite();
347  if ( !sDisableCache )
348  {
349  sEllipsoidCache()->insert( ellipsoid, params );
350  }
351  sEllipsoidCacheLock()->unlock();
352  return params;
353 #else
354  params.valid = false;
355 
356  QgsReadWriteLocker l( *sEllipsoidCacheLock(), QgsReadWriteLocker::Write );
357  if ( !sDisableCache )
358  {
359  sEllipsoidCache()->insert( ellipsoid, params );
360  }
361 
362  return params;
363 #endif
364 }
365 
366 QList<QgsEllipsoidUtils::EllipsoidDefinition> QgsEllipsoidUtils::definitions()
367 {
368  QgsReadWriteLocker defLocker( *sDefinitionCacheLock(), QgsReadWriteLocker::Read );
369  if ( !sDefinitionCache()->isEmpty() )
370  {
371  return *sDefinitionCache();
372  }
374 
375  QList<QgsEllipsoidUtils::EllipsoidDefinition> defs;
376 
377 #if PROJ_VERSION_MAJOR>=6
378  QgsReadWriteLocker locker( *sEllipsoidCacheLock(), QgsReadWriteLocker::Write );
379 
380  PJ_CONTEXT *context = QgsProjContext::get();
381  if ( PROJ_STRING_LIST authorities = proj_get_authorities_from_database( context ) )
382  {
383  PROJ_STRING_LIST authoritiesIt = authorities;
384  while ( char *authority = *authoritiesIt )
385  {
386  if ( PROJ_STRING_LIST codes = proj_get_codes_from_database( context, authority, PJ_TYPE_ELLIPSOID, 0 ) )
387  {
388  PROJ_STRING_LIST codesIt = codes;
389  while ( char *code = *codesIt )
390  {
391  QgsProjUtils::proj_pj_unique_ptr ellipsoid( proj_create_from_database( context, authority, code, PJ_CATEGORY_ELLIPSOID, 0, nullptr ) );
392  if ( ellipsoid.get() )
393  {
395  QString name = QString( proj_get_name( ellipsoid.get() ) );
396  def.acronym = QStringLiteral( "%1:%2" ).arg( authority, code );
397  name.replace( '_', ' ' );
398  def.description = QStringLiteral( "%1 (%2:%3)" ).arg( name, authority, code );
399 
400  double semiMajor, semiMinor, invFlattening;
401  int semiMinorComputed = 0;
402  if ( proj_ellipsoid_get_parameters( context, ellipsoid.get(), &semiMajor, &semiMinor, &semiMinorComputed, &invFlattening ) )
403  {
404  def.parameters.semiMajor = semiMajor;
405  def.parameters.semiMinor = semiMinor;
406  def.parameters.inverseFlattening = invFlattening;
407  if ( !semiMinorComputed )
408  def.parameters.crs.createFromProj( QStringLiteral( "+proj=longlat +a=%1 +b=%2 +no_defs +type=crs" ).arg( def.parameters.semiMajor, 0, 'g', 17 ).arg( def.parameters.semiMinor, 0, 'g', 17 ), false );
409  else if ( !qgsDoubleNear( def.parameters.inverseFlattening, 0.0 ) )
410  def.parameters.crs.createFromProj( QStringLiteral( "+proj=longlat +a=%1 +rf=%2 +no_defs +type=crs" ).arg( def.parameters.semiMajor, 0, 'g', 17 ).arg( def.parameters.inverseFlattening, 0, 'g', 17 ), false );
411  else
412  def.parameters.crs.createFromProj( QStringLiteral( "+proj=longlat +a=%1 +no_defs +type=crs" ).arg( def.parameters.semiMajor, 0, 'g', 17 ), false );
413  }
414  else
415  {
416  def.parameters.valid = false;
417  }
418 
419  defs << def;
420  if ( !sDisableCache )
421  {
422  sEllipsoidCache()->insert( def.acronym, def.parameters );
423  }
424  }
425 
426  codesIt++;
427  }
428  proj_string_list_destroy( codes );
429  }
430 
431  authoritiesIt++;
432  }
433  proj_string_list_destroy( authorities );
434  }
435  locker.unlock();
436 
437 #else
440  int result;
441 
442  //check the db is available
443  result = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
444  if ( result )
445  {
446  QgsDebugMsg( QStringLiteral( "Can't open database: %1" ).arg( database.errorMessage() ) );
447  // XXX This will likely never happen since on open, sqlite creates the
448  // database if it does not exist.
449  Q_ASSERT( result == 0 );
450  }
451 
452  // Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
453  QString sql = QStringLiteral( "select acronym, name from tbl_ellipsoid order by name" );
454  statement = database.prepare( sql, result );
455 
456  if ( result == SQLITE_OK )
457  {
458  while ( statement.step() == SQLITE_ROW )
459  {
461  def.acronym = statement.columnAsText( 0 );
462  def.description = statement.columnAsText( 1 );
463 
464  // use ellipsoidParameters so that result is cached
466 
467  defs << def;
468  }
469  }
470 
471 #endif
472 
473  QCollator collator;
474  collator.setCaseSensitivity( Qt::CaseInsensitive );
475  std::sort( defs.begin(), defs.end(), [&collator]( const EllipsoidDefinition & a, const EllipsoidDefinition & b )
476  {
477  return collator.compare( a.description, b.description ) < 0;
478  } );
479  if ( !sDisableCache )
480  {
481  *sDefinitionCache() = defs;
482  }
483 
484  return defs;
485 }
486 
488 {
489  QStringList result;
490  const QList<QgsEllipsoidUtils::EllipsoidDefinition> defs = definitions();
491  result.reserve( defs.size() );
492  for ( const QgsEllipsoidUtils::EllipsoidDefinition &def : defs )
493  {
494  result << def.acronym;
495  }
496  return result;
497 }
498 
499 void QgsEllipsoidUtils::invalidateCache( bool disableCache )
500 {
501  QgsReadWriteLocker locker1( *sEllipsoidCacheLock(), QgsReadWriteLocker::Write );
502  QgsReadWriteLocker locker2( *sDefinitionCacheLock(), QgsReadWriteLocker::Write );
503 
504  if ( !sDisableCache )
505  {
506  if ( disableCache )
507  sDisableCache = true;
508  sEllipsoidCache()->clear();
509  sDefinitionCache()->clear();
510  }
511 }
QgsProjContext::get
static PJ_CONTEXT * get()
Returns a thread local instance of a proj context, safe for use in the current thread.
Definition: qgsprojutils.cpp:60
QgsReadWriteLocker::changeMode
void changeMode(Mode mode)
Change the mode of the lock to mode.
Definition: qgsreadwritelocker.cpp:30
qgsreadwritelocker.h
QgsReadWriteLocker::Read
@ Read
Lock for read.
Definition: qgsreadwritelocker.h:75
QgsEllipsoidUtils::EllipsoidDefinition::parameters
QgsEllipsoidUtils::EllipsoidParameters parameters
Ellipsoid parameters.
Definition: qgsellipsoidutils.h:70
qgsruntimeprofiler.h
EllipsoidDefinitionCache
QList< QgsEllipsoidUtils::EllipsoidDefinition > EllipsoidDefinitionCache
Definition: qgsellipsoidutils.cpp:36
QgsEllipsoidUtils::EllipsoidParameters::useCustomParameters
bool useCustomParameters
Whether custom parameters alone should be used (semiMajor/semiMinor only)
Definition: qgsellipsoidutils.h:50
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
sqlite3_database_unique_ptr::prepare
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
Definition: qgssqliteutils.cpp:99
QgsCoordinateReferenceSystem::fromProj
static QgsCoordinateReferenceSystem fromProj(const QString &proj)
Creates a CRS from a proj style formatted string.
Definition: qgscoordinatereferencesystem.cpp:226
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsEllipsoidUtils::ellipsoidParameters
static EllipsoidParameters ellipsoidParameters(const QString &ellipsoid)
Returns the parameters for the specified ellipsoid.
Definition: qgsellipsoidutils.cpp:41
sqlite3_database_unique_ptr::errorMessage
QString errorMessage() const
Returns the most recent error message encountered by the database.
Definition: qgssqliteutils.cpp:94
Q_GLOBAL_STATIC
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
QgsReadWriteLocker::unlock
void unlock()
Unlocks the lock.
Definition: qgsreadwritelocker.cpp:45
qgsellipsoidutils.h
QgsEllipsoidUtils::EllipsoidParameters::crs
QgsCoordinateReferenceSystem crs
Associated coordinate reference system.
Definition: qgsellipsoidutils.h:56
sqlite3_statement_unique_ptr::step
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
Definition: qgssqliteutils.cpp:41
QgsReadWriteLocker
Definition: qgsreadwritelocker.h:40
qgsapplication.h
QgsApplication::srsDatabaseFilePath
static QString srsDatabaseFilePath()
Returns the path to the srs.db file.
Definition: qgsapplication.cpp:998
QgsCoordinateReferenceSystem::srsid
long srsid() const
Returns the internal CRS ID, if available.
Definition: qgscoordinatereferencesystem.cpp:1289
QgsEllipsoidUtils::EllipsoidDefinition
Contains definition of an ellipsoid.
Definition: qgsellipsoidutils.h:63
QgsEllipsoidUtils::EllipsoidParameters::valid
bool valid
Whether ellipsoid parameters are valid.
Definition: qgsellipsoidutils.h:42
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsReadWriteLocker::Write
@ Write
Lock for write.
Definition: qgsreadwritelocker.h:76
QgsEllipsoidUtils::EllipsoidParameters::semiMinor
double semiMinor
Semi-minor axis.
Definition: qgsellipsoidutils.h:47
QgsCoordinateReferenceSystem::toProj
QString toProj() const
Returns a Proj string representation of this CRS.
Definition: qgscoordinatereferencesystem.cpp:1398
sqlite3_database_unique_ptr::open_v2
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
Definition: qgssqliteutils.cpp:86
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:206
QgsCoordinateReferenceSystem::saveAsUserCrs
long saveAsUserCrs(const QString &name, Format nativeFormat=FormatWkt)
Saves the CRS as a custom ("USER") CRS.
Definition: qgscoordinatereferencesystem.cpp:2269
sqlite3_statement_unique_ptr::columnAsText
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
Definition: qgssqliteutils.cpp:61
QgsEllipsoidUtils::EllipsoidParameters
Contains parameters for an ellipsoid.
Definition: qgsellipsoidutils.h:39
QgsEllipsoidUtils::definitions
static QList< QgsEllipsoidUtils::EllipsoidDefinition > definitions()
Returns a list of the definitions for all known ellipsoids from the internal ellipsoid database.
Definition: qgsellipsoidutils.cpp:366
QgsCoordinateReferenceSystem::createFromProj
bool createFromProj(const QString &projString, bool identify=true)
Sets this CRS by passing it a PROJ style formatted string.
Definition: qgscoordinatereferencesystem.cpp:912
QgsEllipsoidUtils::EllipsoidDefinition::description
QString description
Description of ellipsoid.
Definition: qgsellipsoidutils.h:68
QgsEllipsoidUtils
Definition: qgsellipsoidutils.h:31
qgsprojutils.h
QgsScopedRuntimeProfile
Definition: qgsruntimeprofiler.h:115
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
PJ_CONTEXT
void PJ_CONTEXT
Definition: qgsprojutils.h:151
QgsEllipsoidUtils::EllipsoidParameters::inverseFlattening
double inverseFlattening
Inverse flattening.
Definition: qgsellipsoidutils.h:53
qgslogger.h
QgsEllipsoidUtils::EllipsoidParameters::semiMajor
double semiMajor
Semi-major axis.
Definition: qgsellipsoidutils.h:45
sqlite3_database_unique_ptr
Definition: qgssqliteutils.h:118
QgsEllipsoidUtils::invalidateCache
static void invalidateCache(bool disableCache=false)
Clears the internal cache used.
Definition: qgsellipsoidutils.cpp:499
EllipsoidParamCache
QHash< QString, QgsEllipsoidUtils::EllipsoidParameters > EllipsoidParamCache
Definition: qgsellipsoidutils.cpp:32
QgsEllipsoidUtils::acronyms
static QStringList acronyms()
Returns a list of all known ellipsoid acronyms from the internal ellipsoid database.
Definition: qgsellipsoidutils.cpp:487
QgsEllipsoidUtils::EllipsoidDefinition::acronym
QString acronym
authority:code for QGIS builds with proj version 6 or greater, or custom acronym for ellipsoid for ea...
Definition: qgsellipsoidutils.h:66
sqlite3_statement_unique_ptr
Definition: qgssqliteutils.h:69
qgsmessagelog.h