@@ -31,15 +31,137 @@ QHash< QString, QgsEllipsoidUtils::EllipsoidParameters > QgsEllipsoidUtils::sEll
3131QReadWriteLock QgsEllipsoidUtils::sDefinitionCacheLock ;
3232QList< QgsEllipsoidUtils::EllipsoidDefinition > QgsEllipsoidUtils::sDefinitionCache ;
3333
34- QgsEllipsoidUtils::EllipsoidParameters QgsEllipsoidUtils::ellipsoidParameters ( const QString &ellipsoid )
34+ // maps older QGIS ellipsoid acronyms to proj acronyms/names
35+ const QMap< QString, QString > sProj6EllipsoidAcronymMap
3536{
37+ { " clrk80" , " clrk80ign" },
38+ {" Adrastea2000" , " ESRI:107909" },
39+ {" Amalthea2000" , " ESRI:107910" },
40+ {" Ananke2000" , " ESRI:107911" },
41+ {" Ariel2000" , " ESRI:107945" },
42+ {" Atlas2000" , " ESRI:107926" },
43+ {" Belinda2000" , " ESRI:107946" },
44+ {" Bianca2000" , " ESRI:107947" },
45+ {" Callisto2000" , " ESRI:107912" },
46+ {" Calypso2000" , " ESRI:107927" },
47+ {" Carme2000" , " ESRI:107913" },
48+ {" Charon2000" , " ESRI:107970" },
49+ {" Cordelia2000" , " ESRI:107948" },
50+ {" Cressida2000" , " ESRI:107949" },
51+ {" Deimos2000" , " ESRI:107906" },
52+ {" Desdemona2000" , " ESRI:107950" },
53+ {" Despina2000" , " ESRI:107961" },
54+ {" Dione2000" , " ESRI:107928" },
55+ {" Elara2000" , " ESRI:107914" },
56+ {" Enceladus2000" , " ESRI:107929" },
57+ {" Epimetheus2000" , " ESRI:107930" },
58+ {" Europa2000" , " ESRI:107915" },
59+ {" Galatea2000" , " ESRI:107962" },
60+ {" Ganymede2000" , " ESRI:107916" },
61+ {" Helene2000" , " ESRI:107931" },
62+ {" Himalia2000" , " ESRI:107917" },
63+ {" Hyperion2000" , " ESRI:107932" },
64+ {" Iapetus2000" , " ESRI:107933" },
65+ {" Io2000" , " ESRI:107918" },
66+ {" Janus2000" , " ESRI:107934" },
67+ {" Juliet2000" , " ESRI:107951" },
68+ {" Jupiter2000" , " ESRI:107908" },
69+ {" Larissa2000" , " ESRI:107963" },
70+ {" Leda2000" , " ESRI:107919" },
71+ {" Lysithea2000" , " ESRI:107920" },
72+ {" Mars2000" , " ESRI:107905" },
73+ {" Mercury2000" , " ESRI:107900" },
74+ {" Metis2000" , " ESRI:107921" },
75+ {" Mimas2000" , " ESRI:107935" },
76+ {" Miranda2000" , " ESRI:107952" },
77+ {" Moon2000" , " ESRI:107903" },
78+ {" Naiad2000" , " ESRI:107964" },
79+ {" Neptune2000" , " ESRI:107960" },
80+ {" Nereid2000" , " ESRI:107965" },
81+ {" Oberon2000" , " ESRI:107953" },
82+ {" Ophelia2000" , " ESRI:107954" },
83+ {" Pan2000" , " ESRI:107936" },
84+ {" Pandora2000" , " ESRI:107937" },
85+ {" Pasiphae2000" , " ESRI:107922" },
86+ {" Phobos2000" , " ESRI:107907" },
87+ {" Phoebe2000" , " ESRI:107938" },
88+ {" Pluto2000" , " ESRI:107969" },
89+ {" Portia2000" , " ESRI:107955" },
90+ {" Prometheus2000" , " ESRI:107939" },
91+ {" Proteus2000" , " ESRI:107966" },
92+ {" Puck2000" , " ESRI:107956" },
93+ {" Rhea2000" , " ESRI:107940" },
94+ {" Rosalind2000" , " ESRI:107957" },
95+ {" Saturn2000" , " ESRI:107925" },
96+ {" Sinope2000" , " ESRI:107923" },
97+ {" Telesto2000" , " ESRI:107941" },
98+ {" Tethys2000" , " ESRI:107942" },
99+ {" Thalassa2000" , " ESRI:107967" },
100+ {" Thebe2000" , " ESRI:107924" },
101+ {" Titan2000" , " ESRI:107943" },
102+ {" Titania2000" , " ESRI:107958" },
103+ {" Triton2000" , " ESRI:107968" },
104+ {" Umbriel2000" , " ESRI:107959" },
105+ {" Uranus2000" , " ESRI:107944" },
106+ {" Venus2000" , " ESRI:107902" },
107+ {" IGNF:ELG053" , " EPSG:7030" },
108+ {" IGNF:ELG052" , " EPSG:7043" },
109+ {" IGNF:ELG102" , " EPSG:7043" },
110+ {" WGS66" , " ESRI:107001" },
111+ {" plessis" , " EPSG:7027" },
112+ {" IGNF:ELG017" , " EPSG:7027" },
113+ {" mod_airy" , " EPSG:7002" },
114+ {" IGNF:ELG037" , " EPSG:7019" },
115+ {" IGNF:ELG108" , " EPSG:7036" },
116+ {" cape" , " EPSG:7034" },
117+ {" IGNF:ELG010" , " EPSG:7011" },
118+ {" IGNF:ELG003" , " EPSG:7012" },
119+ {" IGNF:ELG004" , " EPSG:7008" },
120+ {" GSK2011" , " EPSG:1025" },
121+ {" airy" , " EPSG:7001" },
122+ {" aust_SA" , " EPSG:7003" },
123+ {" bessel" , " EPSG:7004" },
124+ {" clrk66" , " EPSG:7008" },
125+ {" clrk80ign" , " EPSG:7011" },
126+ {" evrst30" , " EPSG:7015" },
127+ {" evrstSS" , " EPSG:7016" },
128+ {" evrst48" , " EPSG:7018" },
129+ {" GRS80" , " EPSG:7019" },
130+ {" helmert" , " EPSG:7020" },
131+ {" intl" , " EPSG:7022" },
132+ {" krass" , " EPSG:7024" },
133+ {" NWL9D" , " EPSG:7025" },
134+ {" WGS84" , " EPSG:7030" },
135+ {" GRS67" , " EPSG:7036" },
136+ {" WGS72" , " EPSG:7043" },
137+ {" bess_nam" , " EPSG:7046" },
138+ {" IAU76" , " EPSG:7049" },
139+ {" sphere" , " EPSG:7052" },
140+ {" hough" , " EPSG:7053" },
141+ {" evrst69" , " EPSG:7056" },
142+ {" fschr60" , " ESRI:107002" },
143+ {" fschr68" , " ESRI:107003" },
144+ {" fschr60m" , " ESRI:107004" },
145+ {" walbeck" , " ESRI:107007" },
146+ {" IGNF:ELG001" , " EPSG:7022" },
147+ {" engelis" , " EPSG:7054" },
148+ {" evrst56" , " EPSG:7044" },
149+ {" SEasia" , " ESRI:107004" },
150+ {" SGS85" , " EPSG:7054" }
151+ };
152+
153+ QgsEllipsoidUtils::EllipsoidParameters QgsEllipsoidUtils::ellipsoidParameters ( const QString &e )
154+ {
155+ QString ellipsoid = e;
36156#if PROJ_VERSION_MAJOR >= 6
37157 // ensure ellipsoid database is populated when first called
38158 static std::once_flag initialized;
39159 std::call_once ( initialized, [ = ]
40160 {
41161 ( void )definitions ();
42162 } );
163+
164+ ellipsoid = sProj6EllipsoidAcronymMap .value ( ellipsoid, ellipsoid ); // silently upgrade older QGIS acronyms to proj acronyms
43165#endif
44166
45167 // check cache
@@ -221,37 +343,44 @@ QList<QgsEllipsoidUtils::EllipsoidDefinition> QgsEllipsoidUtils::definitions()
221343 PROJ_STRING_LIST authoritiesIt = authorities;
222344 while ( char *authority = *authoritiesIt )
223345 {
224- QgsDebugMsg ( QString ( authority ) );
225346 PROJ_STRING_LIST codes = proj_get_codes_from_database ( context, authority, PJ_TYPE_ELLIPSOID, 0 );
226347 PROJ_STRING_LIST codesIt = codes;
227348 while ( char *code = *codesIt )
228349 {
229350 EllipsoidDefinition def;
230351
231- QgsDebugMsg ( QString ( code ) );
232-
233352 PJ *ellipsoid = proj_create_from_database ( context, authority, code, PJ_CATEGORY_ELLIPSOID, 0 , nullptr );
234353
235- QgsDebugMsg ( QString ( proj_get_name ( ellipsoid ) ) );
236- def.description = QString ( proj_get_name ( ellipsoid ) ) ;
354+ QString name = QString ( proj_get_name ( ellipsoid ) );
355+ def.acronym = QStringLiteral ( " %1:%2" ).arg ( authority, code );
356+ name.replace ( ' _' , ' ' );
357+ def.description = QStringLiteral ( " %1 (%2:%3)" ).arg ( name, authority, code );
237358
238359 double semiMajor, semiMinor, invFlattening;
239360 int semiMinorComputed;
240- if ( proj_ellipsoid_get_parameters ( context, ellipsoid, &semiMajor, &semiMinor, &semiMinorComputed, &invFlattening ) == 0 )
361+ if ( proj_ellipsoid_get_parameters ( context, ellipsoid, &semiMajor, &semiMinor, &semiMinorComputed, &invFlattening ) )
241362 {
242363 def.parameters .semiMajor = semiMajor;
243- def.parameters .semiMinor = semiMinor;
244- def.parameters .inverseFlattening = invFlattening;
364+ if ( semiMinor > 0 )
365+ {
366+ def.parameters .semiMinor = semiMinor;
367+ def.parameters .inverseFlattening = def.parameters .semiMajor / ( def.parameters .semiMajor - def.parameters .semiMinor );
368+ def.parameters .crs = QgsCoordinateReferenceSystem::fromProj4 ( QStringLiteral ( " +proj=longlat +a=%1 +b=%2 +no_defs" ).arg ( def.parameters .semiMajor ).arg ( def.parameters .semiMinor ) );
369+ }
370+ else
371+ {
372+ def.parameters .inverseFlattening = invFlattening;
373+ def.parameters .semiMinor = def.parameters .semiMajor * ( 1 - def.parameters .inverseFlattening );
374+ def.parameters .crs = QgsCoordinateReferenceSystem::fromProj4 ( QStringLiteral ( " +proj=longlat +a=%1 +rf=%2 +no_defs" ).arg ( def.parameters .semiMajor ).arg ( def.parameters .inverseFlattening ) );
375+ }
245376 }
246377 else
247378 {
248379 def.parameters .valid = false ;
249380 }
250381
251382 defs << def;
252-
253- // sEllipsoidCache.insert( QString( ellipsoid->id ), def.parameters );
254-
383+ sEllipsoidCache .insert ( def.acronym , def.parameters );
255384
256385 codesIt++;
257386 }
@@ -260,57 +389,8 @@ QList<QgsEllipsoidUtils::EllipsoidDefinition> QgsEllipsoidUtils::definitions()
260389 authoritiesIt++;
261390 }
262391 proj_string_list_destroy ( authorities );
263-
264- #if 0
265- // use proj to get ellipsoids
266- const PJ_ELLPS *ellipsoid = proj_list_ellps();
267- while ( ellipsoid->name )
268- {
269- EllipsoidDefinition def;
270- def.acronym = ellipsoid->id ;
271- def.description = ellipsoid->name;
272- QgsDebugMsg( QString( ellipsoid->id ) );
273- QgsDebugMsg( QString( ellipsoid->name ) );
274- const QString majorString( ellipsoid->major );
275- def.parameters.semiMajor = majorString.midRef( 2 ).toDouble();
276- const QString minorString( ellipsoid->ell );
277- if ( minorString.startsWith( 'b' ) )
278- {
279- // b= style
280- def.parameters.semiMinor = minorString.midRef( 2 ).toDouble();
281- def.parameters.inverseFlattening = def.parameters.semiMajor / ( def.parameters.semiMajor - def.parameters.semiMinor );
282- }
283- else
284- {
285- // rf= style
286- def.parameters.inverseFlattening = minorString.midRef( 2 ).toDouble();
287- def.parameters.semiMinor = def.parameters.semiMajor * ( 1 - def.parameters.inverseFlattening );
288- }
289-
290- QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromProj4( QStringLiteral( "+proj=longlat +ellps=%1 +no_defs" ).arg( def.acronym ) );
291- if ( crs.srsid() == 0 )
292- {
293- //TODO: createFromProj4 used to save to the user database any new CRS
294- // this behavior was changed in order to separate creation and saving.
295- // Not sure if it necessary to save it here, should be checked by someone
296- // familiar with the code (should also give a more descriptive name to the generated CRS)
297- QString name = QStringLiteral( " * %1 (%2)" )
298- .arg( QObject::tr( "Generated CRS", "A CRS automatically generated from layer info get this prefix for description" ),
299- crs.toProj4() );
300- crs.saveAsUserCrs( name );
301- }
302- def.parameters.crs = crs;
303-
304- defs << def;
305-
306- sEllipsoidCache.insert( QString( ellipsoid->id ), def.parameters );
307-
308- ellipsoid++;
309- }
310- #endif
311392 sEllipsoidCacheLock .unlock ();
312393
313-
314394#else
315395 sqlite3_database_unique_ptr database;
316396 sqlite3_statement_unique_ptr statement;
0 commit comments