34using namespace Qt::StringLiterals;
44static
bool sDisableCache = false;
49 static const QMap< QString, QString > sProj6EllipsoidAcronymMap {
50 {
"clrk80",
"clrk80ign" },
51 {
"Adrastea2000",
"ESRI:107909" },
52 {
"Amalthea2000",
"ESRI:107910" },
53 {
"Ananke2000",
"ESRI:107911" },
54 {
"Ariel2000",
"ESRI:107945" },
55 {
"Atlas2000",
"ESRI:107926" },
56 {
"Belinda2000",
"ESRI:107946" },
57 {
"Bianca2000",
"ESRI:107947" },
58 {
"Callisto2000",
"ESRI:107912" },
59 {
"Calypso2000",
"ESRI:107927" },
60 {
"Carme2000",
"ESRI:107913" },
61 {
"Charon2000",
"ESRI:107970" },
62 {
"Cordelia2000",
"ESRI:107948" },
63 {
"Cressida2000",
"ESRI:107949" },
64 {
"Deimos2000",
"ESRI:107906" },
65 {
"Desdemona2000",
"ESRI:107950" },
66 {
"Despina2000",
"ESRI:107961" },
67 {
"Dione2000",
"ESRI:107928" },
68 {
"Elara2000",
"ESRI:107914" },
69 {
"Enceladus2000",
"ESRI:107929" },
70 {
"Epimetheus2000",
"ESRI:107930" },
71 {
"Europa2000",
"ESRI:107915" },
72 {
"Galatea2000",
"ESRI:107962" },
73 {
"Ganymede2000",
"ESRI:107916" },
74 {
"Helene2000",
"ESRI:107931" },
75 {
"Himalia2000",
"ESRI:107917" },
76 {
"Hyperion2000",
"ESRI:107932" },
77 {
"Iapetus2000",
"ESRI:107933" },
78 {
"Io2000",
"ESRI:107918" },
79 {
"Janus2000",
"ESRI:107934" },
80 {
"Juliet2000",
"ESRI:107951" },
81 {
"Jupiter2000",
"ESRI:107908" },
82 {
"Larissa2000",
"ESRI:107963" },
83 {
"Leda2000",
"ESRI:107919" },
84 {
"Lysithea2000",
"ESRI:107920" },
85 {
"Mars2000",
"ESRI:107905" },
86 {
"Mercury2000",
"ESRI:107900" },
87 {
"Metis2000",
"ESRI:107921" },
88 {
"Mimas2000",
"ESRI:107935" },
89 {
"Miranda2000",
"ESRI:107952" },
90 {
"Moon2000",
"ESRI:107903" },
91 {
"Naiad2000",
"ESRI:107964" },
92 {
"Neptune2000",
"ESRI:107960" },
93 {
"Nereid2000",
"ESRI:107965" },
94 {
"Oberon2000",
"ESRI:107953" },
95 {
"Ophelia2000",
"ESRI:107954" },
96 {
"Pan2000",
"ESRI:107936" },
97 {
"Pandora2000",
"ESRI:107937" },
98 {
"Pasiphae2000",
"ESRI:107922" },
99 {
"Phobos2000",
"ESRI:107907" },
100 {
"Phoebe2000",
"ESRI:107938" },
101 {
"Pluto2000",
"ESRI:107969" },
102 {
"Portia2000",
"ESRI:107955" },
103 {
"Prometheus2000",
"ESRI:107939" },
104 {
"Proteus2000",
"ESRI:107966" },
105 {
"Puck2000",
"ESRI:107956" },
106 {
"Rhea2000",
"ESRI:107940" },
107 {
"Rosalind2000",
"ESRI:107957" },
108 {
"Saturn2000",
"ESRI:107925" },
109 {
"Sinope2000",
"ESRI:107923" },
110 {
"Telesto2000",
"ESRI:107941" },
111 {
"Tethys2000",
"ESRI:107942" },
112 {
"Thalassa2000",
"ESRI:107967" },
113 {
"Thebe2000",
"ESRI:107924" },
114 {
"Titan2000",
"ESRI:107943" },
115 {
"Titania2000",
"ESRI:107958" },
116 {
"Triton2000",
"ESRI:107968" },
117 {
"Umbriel2000",
"ESRI:107959" },
118 {
"Uranus2000",
"ESRI:107944" },
119 {
"Venus2000",
"ESRI:107902" },
120 {
"IGNF:ELG053",
"EPSG:7030" },
121 {
"IGNF:ELG052",
"EPSG:7043" },
122 {
"IGNF:ELG102",
"EPSG:7043" },
123 {
"WGS66",
"ESRI:107001" },
124 {
"plessis",
"EPSG:7027" },
125 {
"IGNF:ELG017",
"EPSG:7027" },
126 {
"mod_airy",
"EPSG:7002" },
127 {
"IGNF:ELG037",
"EPSG:7019" },
128 {
"IGNF:ELG108",
"EPSG:7036" },
129 {
"cape",
"EPSG:7034" },
130 {
"IGNF:ELG010",
"EPSG:7011" },
131 {
"IGNF:ELG003",
"EPSG:7012" },
132 {
"IGNF:ELG004",
"EPSG:7008" },
133 {
"GSK2011",
"EPSG:1025" },
134 {
"airy",
"EPSG:7001" },
135 {
"aust_SA",
"EPSG:7003" },
136 {
"bessel",
"EPSG:7004" },
137 {
"clrk66",
"EPSG:7008" },
138 {
"clrk80ign",
"EPSG:7011" },
139 {
"evrst30",
"EPSG:7015" },
140 {
"evrstSS",
"EPSG:7016" },
141 {
"evrst48",
"EPSG:7018" },
142 {
"GRS80",
"EPSG:7019" },
143 {
"helmert",
"EPSG:7020" },
144 {
"intl",
"EPSG:7022" },
145 {
"krass",
"EPSG:7024" },
146 {
"NWL9D",
"EPSG:7025" },
147 {
"WGS84",
"EPSG:7030" },
148 {
"GRS67",
"EPSG:7036" },
149 {
"WGS72",
"EPSG:7043" },
150 {
"bess_nam",
"EPSG:7046" },
151 {
"IAU76",
"EPSG:7049" },
152 {
"sphere",
"EPSG:7052" },
153 {
"hough",
"EPSG:7053" },
154 {
"evrst69",
"EPSG:7056" },
155 {
"fschr60",
"ESRI:107002" },
156 {
"fschr68",
"ESRI:107003" },
157 {
"fschr60m",
"ESRI:107004" },
158 {
"walbeck",
"ESRI:107007" },
159 {
"IGNF:ELG001",
"EPSG:7022" },
160 {
"engelis",
"EPSG:7054" },
161 {
"evrst56",
"EPSG:7044" },
162 {
"SEasia",
"ESRI:107004" },
163 {
"SGS85",
"EPSG:7054" },
164 {
"andrae",
"PROJ:ANDRAE" },
165 {
"clrk80",
"EPSG:7034" },
166 {
"CPM",
"PROJ:CPM" },
167 {
"delmbr",
"PROJ:DELMBR" },
168 {
"Earth2000",
"PROJ:EARTH2000" },
169 {
"kaula",
"PROJ:KAULA" },
170 {
"lerch",
"PROJ:LERCH" },
171 {
"MERIT",
"PROJ:MERIT" },
172 {
"mprts",
"PROJ:MPRTS" },
173 {
"new_intl",
"PROJ:NEW_INTL" },
174 {
"WGS60",
"PROJ:WGS60" }
177 QString ellipsoid = e;
179 static std::once_flag initialized;
180 std::call_once( initialized, [] {
185 ellipsoid = sProj6EllipsoidAcronymMap.value( ellipsoid, ellipsoid );
190 if ( !sDisableCache )
192 const QHash< QString, EllipsoidParameters >::const_iterator cacheIt = sEllipsoidCache()->constFind( ellipsoid );
193 if ( cacheIt != sEllipsoidCache()->constEnd() )
208 if ( ellipsoid.startsWith(
"PARAMETER"_L1 ) )
210 QStringList paramList = ellipsoid.split(
':' );
211 bool semiMajorOk, semiMinorOk;
212 const double semiMajor = paramList[1].toDouble( &semiMajorOk );
213 const double semiMinor = paramList[2].toDouble( &semiMinorOk );
214 if ( semiMajorOk && semiMinorOk )
224 params.
valid =
false;
228 if ( !sDisableCache )
230 sEllipsoidCache()->insert( ellipsoid, params );
234 params.
valid =
false;
237 if ( !sDisableCache )
239 sEllipsoidCache()->insert( ellipsoid, params );
248 if ( !sDefinitionCache()->isEmpty() )
250 return *sDefinitionCache();
254 QList<QgsEllipsoidUtils::EllipsoidDefinition> defs;
259 if ( PROJ_STRING_LIST authorities = proj_get_authorities_from_database( context ) )
261 PROJ_STRING_LIST authoritiesIt = authorities;
262 while (
char *authority = *authoritiesIt )
264 if ( PROJ_STRING_LIST codes = proj_get_codes_from_database( context, authority, PJ_TYPE_ELLIPSOID, 0 ) )
266 PROJ_STRING_LIST codesIt = codes;
267 while (
char *code = *codesIt )
273 QString name = QString( proj_get_name( ellipsoid.get() ) );
274 def.
acronym = u
"%1:%2"_s.arg( authority, code );
275 name.replace(
'_',
' ' );
276 def.
description = u
"%1 (%2:%3)"_s.arg( name, authority, code );
278 def.
celestialBodyName = proj_get_celestial_body_name( context, ellipsoid.get() );
280 double semiMajor, semiMinor, invFlattening;
281 int semiMinorComputed = 0;
282 if ( proj_ellipsoid_get_parameters( context, ellipsoid.get(), &semiMajor, &semiMinor, &semiMinorComputed, &invFlattening ) )
287 if ( !semiMinorComputed )
300 if ( !sDisableCache )
308 proj_string_list_destroy( codes );
313 proj_string_list_destroy( authorities );
318 collator.setCaseSensitivity( Qt::CaseInsensitive );
320 if ( !sDisableCache )
322 *sDefinitionCache() = defs;
331 const QList<QgsEllipsoidUtils::EllipsoidDefinition> defs =
definitions();
332 result.reserve( defs.size() );
335 result << def.acronym;
350 if ( !sDisableCache )
353 sDisableCache =
true;
354 sEllipsoidCache()->clear();
355 sDefinitionCache()->clear();
static QgsCoordinateReferenceSystemRegistry * coordinateReferenceSystemRegistry()
Returns the application's coordinate reference system (CRS) registry, which handles known CRS definit...
QList< QgsCelestialBody > celestialBodies() const
Returns a list of all known celestial bodies.
bool createFromProj(const QString &projString, bool identify=true)
Sets this CRS by passing it a PROJ style formatted string.
Contains utility functions for working with ellipsoids and querying the ellipsoid database.
static QList< QgsEllipsoidUtils::EllipsoidDefinition > definitions()
Returns a list of the definitions for all known ellipsoids from the internal ellipsoid database.
static QList< QgsCelestialBody > celestialBodies()
Returns a list of all known celestial bodies.
static void invalidateCache(bool disableCache=false)
Clears the internal cache used.
static EllipsoidParameters ellipsoidParameters(const QString &ellipsoid)
Returns the parameters for the specified ellipsoid.
static QStringList acronyms()
Returns a list of all known ellipsoid acronyms from the internal ellipsoid database.
static PJ_CONTEXT * get()
Returns a thread local instance of a proj context, safe for use in the current thread.
std::unique_ptr< PJ, ProjPJDeleter > proj_pj_unique_ptr
Scoped Proj PJ object.
A convenience class that simplifies locking and unlocking QReadWriteLocks.
void unlock()
Unlocks the lock.
void changeMode(Mode mode)
Change the mode of the lock to mode.
Scoped object for logging of the runtime for a single operation or group of operations.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
QList< QgsEllipsoidUtils::EllipsoidDefinition > EllipsoidDefinitionCache
QHash< QString, QgsEllipsoidUtils::EllipsoidParameters > EllipsoidParamCache
Q_GLOBAL_STATIC(QReadWriteLock, sDefinitionCacheLock)
Contains definition of an ellipsoid.
QString acronym
authority:code for QGIS builds with proj version 6 or greater, or custom acronym for ellipsoid for ea...
QString celestialBodyName
Name of the associated celestial body (e.g.
QString description
Description of ellipsoid.
QgsEllipsoidUtils::EllipsoidParameters parameters
Ellipsoid parameters.
Contains parameters for an ellipsoid.
double semiMajor
Semi-major axis, in meters.
bool valid
Whether ellipsoid parameters are valid.
double semiMinor
Semi-minor axis, in meters.
QgsCoordinateReferenceSystem crs
Associated coordinate reference system.
double inverseFlattening
Inverse flattening.
bool useCustomParameters
Whether custom parameters alone should be used (semiMajor/semiMinor only).