Skip to content

Commit

Permalink
Add QgsCoordinateReferenceSystemRegistry::celestialBodies() for
Browse files Browse the repository at this point in the history
retrieving a list of all known celestial bodies from PROJ

Requires PROJ 8.1+
  • Loading branch information
nyalldawson committed May 10, 2021
1 parent 7e1f9d7 commit 7604b6e
Show file tree
Hide file tree
Showing 9 changed files with 133 additions and 0 deletions.
Expand Up @@ -9,6 +9,7 @@




class QgsCoordinateReferenceSystemRegistry : QObject
{
%Docstring(signature="appended")
Expand All @@ -31,6 +32,8 @@ any user-defined CRSes.
Constructor for QgsCoordinateReferenceSystemRegistry, with the specified ``parent`` object.
%End

~QgsCoordinateReferenceSystemRegistry();

class UserCrsDetails
{
%Docstring(signature="appended")
Expand Down Expand Up @@ -108,6 +111,20 @@ Removes the existing user CRS with matching ``id``.
Returns ``False`` if the CRS could not be removed.

.. seealso:: :py:func:`userCrsRemoved`
%End

QList< QgsCelestialBody > celestialBodies() const;
%Docstring
Returns a list of all known celestial bodies.

.. warning::

This method requires PROJ 8.1 or later

:raises :: py:class:`QgsNotSupportedException` on QGIS builds based on PROJ 8.0 or earlier.


.. versionadded:: 3.20
%End

signals:
Expand Down
21 changes: 21 additions & 0 deletions python/core/auto_generated/proj/qgsellipsoidutils.sip.in
Expand Up @@ -8,6 +8,7 @@




class QgsEllipsoidUtils
{
%Docstring(signature="appended")
Expand All @@ -33,6 +34,7 @@ Contains utility functions for working with ellipsoids and querying the ellipsoi
double inverseFlattening;

QgsCoordinateReferenceSystem crs;

};

struct EllipsoidDefinition
Expand Down Expand Up @@ -64,6 +66,25 @@ Returns a list of all known ellipsoid acronyms from the internal
ellipsoid database.

.. seealso:: :py:func:`definitions`
%End

static QList< QgsCelestialBody > celestialBodies();
%Docstring
Returns a list of all known celestial bodies.

.. note::

This method is an alias for :py:func:`QgsCoordinateReferenceSystemRegistry.celestialBodies()`.

.. warning::

This method requires PROJ 8.1 or later


:raises :: py:class:`QgsNotSupportedException` on QGIS builds based on PROJ 8.0 or earlier.


.. versionadded:: 3.20
%End

};
Expand Down
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -428,6 +428,7 @@
%Include auto_generated/pointcloud/qgspointcloudrenderer.sip
%Include auto_generated/pointcloud/qgspointcloudrendererregistry.sip
%Include auto_generated/pointcloud/qgspointcloudrgbrenderer.sip
%Include auto_generated/proj/qgscelestialbody.sip
%Include auto_generated/proj/qgscoordinatereferencesystem.sip
%Include auto_generated/proj/qgscoordinatereferencesystemregistry.sip
%Include auto_generated/proj/qgscoordinatetransform.sip
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -1357,6 +1357,7 @@ set(QGIS_CORE_HDRS
pointcloud/qgspointcloudrendererregistry.h
pointcloud/qgspointcloudrgbrenderer.h

proj/qgscelestialbody.h
proj/qgscoordinatereferencesystem.h
proj/qgscoordinatereferencesystemregistry.h
proj/qgscoordinatetransform.h
Expand Down
44 changes: 44 additions & 0 deletions src/core/proj/qgscoordinatereferencesystemregistry.cpp
Expand Up @@ -22,15 +22,23 @@
#include "qgslogger.h"
#include "qgsmessagelog.h"
#include "qgssqliteutils.h"
#include "qgscelestialbody.h"
#include "qgsprojutils.h"
#include "qgsruntimeprofiler.h"
#include "qgsexception.h"

#include <sqlite3.h>
#include <mutex>
#include <proj.h>

QgsCoordinateReferenceSystemRegistry::QgsCoordinateReferenceSystemRegistry( QObject *parent )
: QObject( parent )
{

}

QgsCoordinateReferenceSystemRegistry::~QgsCoordinateReferenceSystemRegistry() = default;

QList<QgsCoordinateReferenceSystemRegistry::UserCrsDetails> QgsCoordinateReferenceSystemRegistry::userCrsList() const
{
QList<QgsCoordinateReferenceSystemRegistry::UserCrsDetails> res;
Expand Down Expand Up @@ -335,3 +343,39 @@ bool QgsCoordinateReferenceSystemRegistry::insertProjection( const QString &proj

return true;
}

QList< QgsCelestialBody> QgsCoordinateReferenceSystemRegistry::celestialBodies() const
{
#if PROJ_VERSION_MAJOR>8 || (PROJ_VERSION_MAJOR==8 && PROJ_VERSION_MINOR>=1)

static std::once_flag initialized;
std::call_once( initialized, [ = ]
{
QgsScopedRuntimeProfile profile( QObject::tr( "Initialize celestial bodies" ) );

PJ_CONTEXT *context = QgsProjContext::get();

int resultCount = 0;
PROJ_CELESTIAL_BODY_INFO **list = proj_get_celestial_body_list_from_database( context, nullptr, &resultCount );
mCelestialBodies.reserve( resultCount );
for ( int i = 0; i < resultCount; i++ )
{
const PROJ_CELESTIAL_BODY_INFO *info = list[ i ];
if ( !info )
break;

QgsCelestialBody body;
body.mValid = true;
body.mAuthority = QString( info->auth_name );
body.mName = QString( info->name );

mCelestialBodies << body;
}
proj_celestial_body_list_destroy( list );
} );

return mCelestialBodies;
#else
throw QgsNotSupportedException( QStringLiteral( "Retrieving celestial bodies requires a QGIS build based on PROJ 8.1 or later" ) );
#endif
}
17 changes: 17 additions & 0 deletions src/core/proj/qgscoordinatereferencesystemregistry.h
Expand Up @@ -21,6 +21,8 @@
#include <QObject>
#include "qgscoordinatereferencesystem.h"

class QgsCelestialBody;

/**
* \class QgsCoordinateReferenceSystemRegistry
* \ingroup core
Expand All @@ -42,6 +44,8 @@ class CORE_EXPORT QgsCoordinateReferenceSystemRegistry : public QObject
*/
explicit QgsCoordinateReferenceSystemRegistry( QObject *parent = nullptr );

~QgsCoordinateReferenceSystemRegistry();

/**
* \brief Contains details of a custom (user defined) CRS.
* \ingroup core
Expand Down Expand Up @@ -119,6 +123,17 @@ class CORE_EXPORT QgsCoordinateReferenceSystemRegistry : public QObject
*/
bool removeUserCrs( long id );

/**
* Returns a list of all known celestial bodies.
*
* \warning This method requires PROJ 8.1 or later
*
* \throws QgsNotSupportedException on QGIS builds based on PROJ 8.0 or earlier.
*
* \since QGIS 3.20
*/
QList< QgsCelestialBody > celestialBodies() const;

signals:

/**
Expand Down Expand Up @@ -163,6 +178,8 @@ class CORE_EXPORT QgsCoordinateReferenceSystemRegistry : public QObject

bool insertProjection( const QString &projectionAcronym );

mutable QList< QgsCelestialBody > mCelestialBodies;

};


Expand Down
7 changes: 7 additions & 0 deletions src/core/proj/qgsellipsoidutils.cpp
Expand Up @@ -22,6 +22,8 @@
#include "qgsprojutils.h"
#include "qgsreadwritelocker.h"
#include "qgsruntimeprofiler.h"
#include "qgscoordinatereferencesystemregistry.h"
#include "qgscelestialbody.h"

#include <proj.h>
#include <mutex>
Expand Down Expand Up @@ -336,6 +338,11 @@ QStringList QgsEllipsoidUtils::acronyms()
return result;
}

QList<QgsCelestialBody> QgsEllipsoidUtils::celestialBodies()
{
return QgsApplication::coordinateReferenceSystemRegistry()->celestialBodies();
}

void QgsEllipsoidUtils::invalidateCache( bool disableCache )
{
QgsReadWriteLocker locker1( *sEllipsoidCacheLock(), QgsReadWriteLocker::Write );
Expand Down
16 changes: 16 additions & 0 deletions src/core/proj/qgsellipsoidutils.h
Expand Up @@ -21,6 +21,8 @@
#include "qgscoordinatereferencesystem.h"
#include <QStringList>

class QgsCelestialBody;

/**
* \class QgsEllipsoidUtils
* \ingroup core
Expand Down Expand Up @@ -54,6 +56,7 @@ class CORE_EXPORT QgsEllipsoidUtils

//! Associated coordinate reference system
QgsCoordinateReferenceSystem crs;

};

/**
Expand Down Expand Up @@ -99,6 +102,19 @@ class CORE_EXPORT QgsEllipsoidUtils
*/
static QStringList acronyms();

/**
* Returns a list of all known celestial bodies.
*
* \note This method is an alias for QgsCoordinateReferenceSystemRegistry::celestialBodies().
*
* \warning This method requires PROJ 8.1 or later
*
* \throws QgsNotSupportedException on QGIS builds based on PROJ 8.0 or earlier.
*
* \since QGIS 3.20
*/
static QList< QgsCelestialBody > celestialBodies();

#ifndef SIP_RUN

/**
Expand Down
9 changes: 9 additions & 0 deletions tests/src/python/test_qgsellipsoidutils.py
Expand Up @@ -112,6 +112,15 @@ def testDefinitions(self):
self.assertFalse(gany_defs.parameters.useCustomParameters)
self.assertEqual(gany_defs.parameters.crs.authid(), '')

@unittest.skipIf(QgsProjUtils.projVersionMajor() < 8 or (QgsProjUtils.projVersionMajor() == 8 and QgsProjUtils.projVersionMinor() < 1), 'Not a proj >= 8.1 build')
def testCelestialBodies(self):
bodies = QgsEllipsoidUtils.celestialBodies()

self.assertTrue(bodies)

ganymede = [body for body in bodies if body.name() == 'Ganymede' and body.authority() == 'ESRI'][0]
self.assertTrue(ganymede.isValid())

def testMappingEllipsoidsToProj6(self):
old_qgis_ellipsoids = {'Adrastea2000': 'Adrastea2000', 'airy': 'Airy 1830', 'Amalthea2000': 'Amalthea2000',
'Ananke2000': 'Ananke2000',
Expand Down

0 comments on commit 7604b6e

Please sign in to comment.