Skip to content

Commit fbf99af

Browse files
committed
Add method to retrieve all valid srs ids from CRS databases
1 parent f2ac60a commit fbf99af

5 files changed

+135
-0
lines changed

python/core/conversions.sip

+47
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,53 @@ template <TYPE>
438438
};
439439

440440

441+
%MappedType QList<long>
442+
{
443+
%TypeHeaderCode
444+
#include <QList>
445+
%End
446+
447+
%ConvertFromTypeCode
448+
// Create the list.
449+
PyObject *l;
450+
451+
if ((l = PyList_New(sipCpp->size())) == NULL)
452+
return NULL;
453+
454+
// Set the list elements.
455+
QList<long>::iterator it = sipCpp->begin();
456+
for (int i = 0; it != sipCpp->end(); ++it, ++i)
457+
{
458+
PyObject *tobj;
459+
460+
if ((tobj = PyLong_FromLong(*it)) == NULL)
461+
{
462+
Py_DECREF(l);
463+
return NULL;
464+
}
465+
PyList_SET_ITEM(l, i, tobj);
466+
}
467+
468+
return l;
469+
%End
470+
471+
%ConvertToTypeCode
472+
// Check the type if that is all that is required.
473+
if (sipIsErr == NULL)
474+
return PyList_Check(sipPy);
475+
476+
QList<long> *qlist = new QList<long>;
477+
478+
for (int i = 0; i < PyList_GET_SIZE(sipPy); ++i)
479+
{
480+
*qlist << PyLong_AsLong(PyList_GET_ITEM(sipPy, i));
481+
}
482+
483+
*sipCppPtr = qlist;
484+
return sipGetState(sipTransferObj);
485+
%End
486+
};
487+
441488
%MappedType QList<qint64>
442489
{
443490
%TypeHeaderCode

python/core/qgscoordinatereferencesystem.sip

+2
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,8 @@ class QgsCoordinateReferenceSystem
183183
// TODO QGIS 3: remove theType and always use EPSG code
184184
QgsCoordinateReferenceSystem( const long theId, CrsType theType = PostgisCrsId );
185185

186+
static QList< long > validSrsIds();
187+
186188
// static creators
187189

188190
/** Creates a CRS from a given OGC WMS-format Coordinate Reference System string.

src/core/qgscoordinatereferencesystem.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,66 @@ QgsCoordinateReferenceSystem& QgsCoordinateReferenceSystem::operator=( const Qgs
9090
return *this;
9191
}
9292

93+
QList<long> QgsCoordinateReferenceSystem::validSrsIds()
94+
{
95+
QList<long> results;
96+
// check both standard & user defined projection databases
97+
QStringList dbs = QStringList() << QgsApplication::srsDatabaseFilePath() << QgsApplication::qgisUserDatabaseFilePath();
98+
99+
Q_FOREACH ( const QString& db, dbs )
100+
{
101+
QFileInfo myInfo( db );
102+
if ( !myInfo.exists() )
103+
{
104+
QgsDebugMsg( "failed : " + db + " does not exist!" );
105+
continue;
106+
}
107+
108+
sqlite3 *database = nullptr;
109+
const char *tail = nullptr;
110+
sqlite3_stmt *statement = nullptr;
111+
112+
//check the db is available
113+
int result = openDatabase( db, &database );
114+
if ( result != SQLITE_OK )
115+
{
116+
QgsDebugMsg( "failed : " + db + " could not be opened!" );
117+
continue;
118+
}
119+
120+
QString sql = "select srs_id from tbl_srs";
121+
result = sqlite3_prepare( database, sql.toUtf8(),
122+
sql.toUtf8().length(),
123+
&statement, &tail );
124+
while ( 1 )
125+
{
126+
// this one is an infinitive loop, intended to fetch any row
127+
int ret = sqlite3_step( statement );
128+
129+
if ( ret == SQLITE_DONE )
130+
{
131+
// there are no more rows to fetch - we can stop looping
132+
break;
133+
}
134+
135+
if ( ret == SQLITE_ROW )
136+
{
137+
results.append( sqlite3_column_int( statement, 0 ) );
138+
}
139+
else
140+
{
141+
QgsMessageLog::logMessage( QObject::tr( "SQLite error: %2\nSQL: %1" ).arg( sql, sqlite3_errmsg( database ) ), QObject::tr( "SpatiaLite" ) );
142+
break;
143+
}
144+
}
145+
146+
sqlite3_finalize( statement );
147+
sqlite3_close( database );
148+
}
149+
std::sort( results.begin(), results.end() );
150+
return results;
151+
}
152+
93153
QgsCoordinateReferenceSystem QgsCoordinateReferenceSystem::fromOgcWmsCrs( const QString& ogcCrs )
94154
{
95155
QgsCoordinateReferenceSystem crs;

src/core/qgscoordinatereferencesystem.h

+10
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,15 @@ class CORE_EXPORT QgsCoordinateReferenceSystem
236236
//! Assignment operator
237237
QgsCoordinateReferenceSystem& operator=( const QgsCoordinateReferenceSystem& srs );
238238

239+
/**
240+
* Returns a list of all valid SRS IDs present in the CRS database. Any of the
241+
* returned values can be safely passed to fromSrsId() to create a new, valid
242+
* QgsCoordinateReferenceSystem object.
243+
* @see fromSrsId()
244+
* @note added in QGIS 3.0
245+
*/
246+
static QList< long > validSrsIds();
247+
239248
// static creators
240249

241250
/** Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
@@ -274,6 +283,7 @@ class CORE_EXPORT QgsCoordinateReferenceSystem
274283
* @returns matching CRS, or an invalid CRS if ID could not be found
275284
* @note added in QGIS 3.0
276285
* @see createFromSrsId()
286+
* @see validSrsIds()
277287
*/
278288
static QgsCoordinateReferenceSystem fromSrsId( long srsId );
279289

tests/src/core/testqgscoordinatereferencesystem.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class TestQgsCoordinateReferenceSystem: public QObject
7373
void setValidationHint();
7474
void hasAxisInverted();
7575
void createFromProj4Invalid();
76+
void validSrsIds();
77+
7678
private:
7779
void debugPrint( QgsCoordinateReferenceSystem &theCrs );
7880
// these used by createFromESRIWkt()
@@ -724,5 +726,19 @@ void TestQgsCoordinateReferenceSystem::createFromProj4Invalid()
724726
QVERIFY( !myCrs.createFromProj4( "+proj=longlat +no_defs" ) );
725727
}
726728

729+
void TestQgsCoordinateReferenceSystem::validSrsIds()
730+
{
731+
QList< long > ids = QgsCoordinateReferenceSystem::validSrsIds();
732+
QVERIFY( ids.contains( 3857 ) );
733+
QVERIFY( ids.contains( 28356 ) );
734+
735+
// check that all returns ids are valid
736+
Q_FOREACH ( long id, ids )
737+
{
738+
QgsCoordinateReferenceSystem c = QgsCoordinateReferenceSystem::fromSrsId( id );
739+
QVERIFY( c.isValid() );
740+
}
741+
}
742+
727743
QGSTEST_MAIN( TestQgsCoordinateReferenceSystem )
728744
#include "testqgscoordinatereferencesystem.moc"

0 commit comments

Comments
 (0)