mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Move retrieval of lists of known ellipsoids to QgsEllipsoidUtils
This commit is contained in:
parent
147bb7f1ed
commit
5f1656b8e9
@ -53,6 +53,22 @@ Associated coordinate reference system
|
|||||||
%End
|
%End
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct EllipsoidDefinition
|
||||||
|
{
|
||||||
|
QString acronym;
|
||||||
|
%Docstring
|
||||||
|
Acronym for ellipsoid
|
||||||
|
%End
|
||||||
|
QString description;
|
||||||
|
%Docstring
|
||||||
|
Description of ellipsoid
|
||||||
|
%End
|
||||||
|
QgsEllipsoidUtils::EllipsoidParameters parameters;
|
||||||
|
%Docstring
|
||||||
|
Ellipsoid parameters
|
||||||
|
%End
|
||||||
|
};
|
||||||
|
|
||||||
static EllipsoidParameters ellipsoidParameters( const QString &ellipsoid );
|
static EllipsoidParameters ellipsoidParameters( const QString &ellipsoid );
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns the parameters for the specified ``ellipsoid``.
|
Returns the parameters for the specified ``ellipsoid``.
|
||||||
@ -60,6 +76,22 @@ Associated coordinate reference system
|
|||||||
:rtype: EllipsoidParameters
|
:rtype: EllipsoidParameters
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
static QList< QgsEllipsoidUtils::EllipsoidDefinition > definitions();
|
||||||
|
%Docstring
|
||||||
|
Returns a list of the definitions for all known ellipsoids from the
|
||||||
|
internal ellipsoid database.
|
||||||
|
\see acronyms()
|
||||||
|
:rtype: list of QgsEllipsoidUtils.EllipsoidDefinition
|
||||||
|
%End
|
||||||
|
|
||||||
|
static QStringList acronyms();
|
||||||
|
%Docstring
|
||||||
|
Returns a list of all known ellipsoid acronyms from the internal
|
||||||
|
ellipsoid database.
|
||||||
|
\see definitions()
|
||||||
|
:rtype: list of str
|
||||||
|
%End
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1805,10 +1805,6 @@ void QgsProjectProperties::populateEllipsoidList()
|
|||||||
//
|
//
|
||||||
// Populate the ellipsoid list
|
// Populate the ellipsoid list
|
||||||
//
|
//
|
||||||
sqlite3 *myDatabase = nullptr;
|
|
||||||
const char *myTail = nullptr;
|
|
||||||
sqlite3_stmt *myPreparedStatement = nullptr;
|
|
||||||
int myResult;
|
|
||||||
EllipsoidDefs myItem;
|
EllipsoidDefs myItem;
|
||||||
|
|
||||||
myItem.acronym = GEO_NONE;
|
myItem.acronym = GEO_NONE;
|
||||||
@ -1823,58 +1819,17 @@ void QgsProjectProperties::populateEllipsoidList()
|
|||||||
myItem.semiMinor = 6370997.0;
|
myItem.semiMinor = 6370997.0;
|
||||||
mEllipsoidList.append( myItem );
|
mEllipsoidList.append( myItem );
|
||||||
|
|
||||||
//check the db is available
|
Q_FOREACH ( const QgsEllipsoidUtils::EllipsoidDefinition &def, QgsEllipsoidUtils::definitions() )
|
||||||
myResult = sqlite3_open_v2( QgsApplication::srsDatabaseFilePath().toUtf8().data(), &myDatabase, SQLITE_OPEN_READONLY, nullptr );
|
|
||||||
if ( myResult )
|
|
||||||
{
|
{
|
||||||
QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( myDatabase ) ) );
|
myItem.acronym = def.acronym;
|
||||||
// XXX This will likely never happen since on open, sqlite creates the
|
myItem.description = def.description;
|
||||||
// database if it does not exist.
|
// Fall-back values
|
||||||
Q_ASSERT( myResult == 0 );
|
myItem.semiMajor = 0.0;
|
||||||
|
myItem.semiMinor = 0.0;
|
||||||
|
myItem.semiMajor = def.parameters.semiMajor;
|
||||||
|
myItem.semiMinor = def.parameters.semiMinor;
|
||||||
|
mEllipsoidList.append( myItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
|
|
||||||
QString mySql = QStringLiteral( "select acronym, name, radius, parameter2 from tbl_ellipsoid order by name" );
|
|
||||||
myResult = sqlite3_prepare( myDatabase, mySql.toUtf8(), mySql.toUtf8().length(), &myPreparedStatement, &myTail );
|
|
||||||
// XXX Need to free memory from the error msg if one is set
|
|
||||||
if ( myResult == SQLITE_OK )
|
|
||||||
{
|
|
||||||
while ( sqlite3_step( myPreparedStatement ) == SQLITE_ROW )
|
|
||||||
{
|
|
||||||
QString para1, para2;
|
|
||||||
myItem.acronym = ( const char * )sqlite3_column_text( myPreparedStatement, 0 );
|
|
||||||
myItem.description = ( const char * )sqlite3_column_text( myPreparedStatement, 1 );
|
|
||||||
|
|
||||||
// Copied from QgsDistanecArea. Should perhaps be moved there somehow?
|
|
||||||
// No error checking, this values are for show only, never used in calculations.
|
|
||||||
|
|
||||||
// Fall-back values
|
|
||||||
myItem.semiMajor = 0.0;
|
|
||||||
myItem.semiMinor = 0.0;
|
|
||||||
// Crash if no column?
|
|
||||||
para1 = ( const char * )sqlite3_column_text( myPreparedStatement, 2 );
|
|
||||||
para2 = ( const char * )sqlite3_column_text( myPreparedStatement, 3 );
|
|
||||||
myItem.semiMajor = para1.midRef( 2 ).toDouble();
|
|
||||||
if ( para2.left( 2 ) == QLatin1String( "b=" ) )
|
|
||||||
{
|
|
||||||
myItem.semiMinor = para2.midRef( 2 ).toDouble();
|
|
||||||
}
|
|
||||||
else if ( para2.left( 3 ) == QLatin1String( "rf=" ) )
|
|
||||||
{
|
|
||||||
double invFlattening = para2.midRef( 3 ).toDouble();
|
|
||||||
if ( invFlattening != 0.0 )
|
|
||||||
{
|
|
||||||
myItem.semiMinor = myItem.semiMajor - ( myItem.semiMajor / invFlattening );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mEllipsoidList.append( myItem );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// close the sqlite3 statement
|
|
||||||
sqlite3_finalize( myPreparedStatement );
|
|
||||||
sqlite3_close( myDatabase );
|
|
||||||
|
|
||||||
// Add all items to selector
|
// Add all items to selector
|
||||||
|
|
||||||
Q_FOREACH ( const EllipsoidDefs &i, mEllipsoidList )
|
Q_FOREACH ( const EllipsoidDefs &i, mEllipsoidList )
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
QReadWriteLock QgsEllipsoidUtils::sEllipsoidCacheLock;
|
QReadWriteLock QgsEllipsoidUtils::sEllipsoidCacheLock;
|
||||||
QHash< QString, QgsEllipsoidUtils::EllipsoidParameters > QgsEllipsoidUtils::sEllipsoidCache;
|
QHash< QString, QgsEllipsoidUtils::EllipsoidParameters > QgsEllipsoidUtils::sEllipsoidCache;
|
||||||
|
QReadWriteLock QgsEllipsoidUtils::sDefinitionCacheLock;
|
||||||
|
QList< QgsEllipsoidUtils::EllipsoidDefinition > QgsEllipsoidUtils::sDefinitionCache;
|
||||||
|
|
||||||
QgsEllipsoidUtils::EllipsoidParameters QgsEllipsoidUtils::ellipsoidParameters( const QString &ellipsoid )
|
QgsEllipsoidUtils::EllipsoidParameters QgsEllipsoidUtils::ellipsoidParameters( const QString &ellipsoid )
|
||||||
{
|
{
|
||||||
@ -177,3 +178,71 @@ QgsEllipsoidUtils::EllipsoidParameters QgsEllipsoidUtils::ellipsoidParameters( c
|
|||||||
sEllipsoidCacheLock.unlock();
|
sEllipsoidCacheLock.unlock();
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QList<QgsEllipsoidUtils::EllipsoidDefinition> QgsEllipsoidUtils::definitions()
|
||||||
|
{
|
||||||
|
sDefinitionCacheLock.lockForRead();
|
||||||
|
if ( !sDefinitionCache.isEmpty() )
|
||||||
|
{
|
||||||
|
QList<QgsEllipsoidUtils::EllipsoidDefinition> defs = sDefinitionCache;
|
||||||
|
sDefinitionCacheLock.unlock();
|
||||||
|
return defs;
|
||||||
|
}
|
||||||
|
sDefinitionCacheLock.unlock();
|
||||||
|
|
||||||
|
sDefinitionCacheLock.lockForWrite();
|
||||||
|
sqlite3 *database = nullptr;
|
||||||
|
const char *tail = nullptr;
|
||||||
|
sqlite3_stmt *preparedStatement = nullptr;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
QList<QgsEllipsoidUtils::EllipsoidDefinition> defs;
|
||||||
|
|
||||||
|
//check the db is available
|
||||||
|
result = sqlite3_open_v2( QgsApplication::srsDatabaseFilePath().toUtf8().data(), &database, SQLITE_OPEN_READONLY, nullptr );
|
||||||
|
if ( result )
|
||||||
|
{
|
||||||
|
QgsDebugMsg( QString( "Can't open database: %1" ).arg( sqlite3_errmsg( database ) ) );
|
||||||
|
// XXX This will likely never happen since on open, sqlite creates the
|
||||||
|
// database if it does not exist.
|
||||||
|
Q_ASSERT( result == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the query to retrieve the projection information needed to populate the ELLIPSOID list
|
||||||
|
QString sql = QStringLiteral( "select acronym, name from tbl_ellipsoid order by name" );
|
||||||
|
result = sqlite3_prepare( database, sql.toUtf8(), sql.toUtf8().length(), &preparedStatement, &tail );
|
||||||
|
// XXX Need to free memory from the error msg if one is set
|
||||||
|
if ( result == SQLITE_OK )
|
||||||
|
{
|
||||||
|
while ( sqlite3_step( preparedStatement ) == SQLITE_ROW )
|
||||||
|
{
|
||||||
|
EllipsoidDefinition def;
|
||||||
|
def.acronym = ( const char * )sqlite3_column_text( preparedStatement, 0 );
|
||||||
|
def.description = ( const char * )sqlite3_column_text( preparedStatement, 1 );
|
||||||
|
|
||||||
|
// use ellipsoidParameters so that result is cached
|
||||||
|
def.parameters = ellipsoidParameters( def.acronym );
|
||||||
|
|
||||||
|
defs << def;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// close the sqlite3 statement
|
||||||
|
sqlite3_finalize( preparedStatement );
|
||||||
|
sqlite3_close( database );
|
||||||
|
|
||||||
|
sDefinitionCache = defs;
|
||||||
|
sDefinitionCacheLock.unlock();
|
||||||
|
|
||||||
|
return defs;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList QgsEllipsoidUtils::acronyms()
|
||||||
|
{
|
||||||
|
QStringList result;
|
||||||
|
Q_FOREACH ( const QgsEllipsoidUtils::EllipsoidDefinition &def, definitions() )
|
||||||
|
{
|
||||||
|
result << def.acronym;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "qgis_core.h"
|
#include "qgis_core.h"
|
||||||
#include "qgis.h"
|
#include "qgis.h"
|
||||||
#include "qgscoordinatereferencesystem.h"
|
#include "qgscoordinatereferencesystem.h"
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class QgsEllipsoidUtils
|
* \class QgsEllipsoidUtils
|
||||||
@ -32,7 +33,7 @@ class CORE_EXPORT QgsEllipsoidUtils
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains parameter definitions for an ellipsoid.
|
* Contains parameters for an ellipsoid.
|
||||||
* \since QGIS 3.0
|
* \since QGIS 3.0
|
||||||
*/
|
*/
|
||||||
struct EllipsoidParameters
|
struct EllipsoidParameters
|
||||||
@ -55,17 +56,47 @@ class CORE_EXPORT QgsEllipsoidUtils
|
|||||||
QgsCoordinateReferenceSystem crs;
|
QgsCoordinateReferenceSystem crs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains definition of an ellipsoid.
|
||||||
|
* \since QGIS 3.0
|
||||||
|
*/
|
||||||
|
struct EllipsoidDefinition
|
||||||
|
{
|
||||||
|
//! Acronym for ellipsoid
|
||||||
|
QString acronym;
|
||||||
|
//! Description of ellipsoid
|
||||||
|
QString description;
|
||||||
|
//! Ellipsoid parameters
|
||||||
|
QgsEllipsoidUtils::EllipsoidParameters parameters;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the parameters for the specified \a ellipsoid.
|
* Returns the parameters for the specified \a ellipsoid.
|
||||||
* Results are cached to allow for fast retrieval of parameters.
|
* Results are cached to allow for fast retrieval of parameters.
|
||||||
*/
|
*/
|
||||||
static EllipsoidParameters ellipsoidParameters( const QString &ellipsoid );
|
static EllipsoidParameters ellipsoidParameters( const QString &ellipsoid );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of the definitions for all known ellipsoids from the
|
||||||
|
* internal ellipsoid database.
|
||||||
|
* \see acronyms()
|
||||||
|
*/
|
||||||
|
static QList< QgsEllipsoidUtils::EllipsoidDefinition > definitions();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all known ellipsoid acronyms from the internal
|
||||||
|
* ellipsoid database.
|
||||||
|
* \see definitions()
|
||||||
|
*/
|
||||||
|
static QStringList acronyms();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// ellipsoid cache
|
// ellipsoid cache
|
||||||
static QReadWriteLock sEllipsoidCacheLock;
|
static QReadWriteLock sEllipsoidCacheLock;
|
||||||
static QHash< QString, EllipsoidParameters > sEllipsoidCache;
|
static QHash< QString, EllipsoidParameters > sEllipsoidCache;
|
||||||
|
static QReadWriteLock sDefinitionCacheLock;
|
||||||
|
static QList< QgsEllipsoidUtils::EllipsoidDefinition > sDefinitionCache;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,6 +29,15 @@ class TestQgsEllipsoidUtils(unittest.TestCase):
|
|||||||
|
|
||||||
# run each test twice, so that ellipsoid is fetched from cache on the second time
|
# run each test twice, so that ellipsoid is fetched from cache on the second time
|
||||||
|
|
||||||
|
for i in range(2):
|
||||||
|
params = QgsEllipsoidUtils.ellipsoidParameters("WGS84")
|
||||||
|
self.assertTrue(params.valid)
|
||||||
|
self.assertEqual(params.semiMajor, 6378137.0)
|
||||||
|
self.assertAlmostEqual(params.semiMinor, 6356752.314245179, 5)
|
||||||
|
self.assertAlmostEqual(params.inverseFlattening, 298.257223563, 5)
|
||||||
|
self.assertFalse(params.useCustomParameters)
|
||||||
|
self.assertEqual(params.crs.authid(), 'EPSG:4030')
|
||||||
|
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
params = QgsEllipsoidUtils.ellipsoidParameters("Ganymede2000")
|
params = QgsEllipsoidUtils.ellipsoidParameters("Ganymede2000")
|
||||||
self.assertTrue(params.valid)
|
self.assertTrue(params.valid)
|
||||||
@ -53,6 +62,23 @@ class TestQgsEllipsoidUtils(unittest.TestCase):
|
|||||||
params = QgsEllipsoidUtils.ellipsoidParameters("Babies first ellipsoid!")
|
params = QgsEllipsoidUtils.ellipsoidParameters("Babies first ellipsoid!")
|
||||||
self.assertFalse(params.valid)
|
self.assertFalse(params.valid)
|
||||||
|
|
||||||
|
def testAcronyms(self):
|
||||||
|
self.assertTrue('WGS84' in QgsEllipsoidUtils.acronyms())
|
||||||
|
self.assertTrue('Ganymede2000' in QgsEllipsoidUtils.acronyms())
|
||||||
|
|
||||||
|
def testDefinitions(self):
|
||||||
|
defs = QgsEllipsoidUtils.definitions()
|
||||||
|
|
||||||
|
gany_defs = [d for d in defs if d.acronym == 'Ganymede2000'][0]
|
||||||
|
self.assertEqual(gany_defs.acronym, 'Ganymede2000')
|
||||||
|
self.assertEqual(gany_defs.description, 'Ganymede2000')
|
||||||
|
self.assertTrue(gany_defs.parameters.valid)
|
||||||
|
self.assertEqual(gany_defs.parameters.semiMajor, 2632400.0)
|
||||||
|
self.assertEqual(gany_defs.parameters.semiMinor, 2632350.0)
|
||||||
|
self.assertEqual(gany_defs.parameters.inverseFlattening, 52648.0)
|
||||||
|
self.assertFalse(gany_defs.parameters.useCustomParameters)
|
||||||
|
self.assertEqual(gany_defs.parameters.crs.authid(), '')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user