Skip to content

Commit

Permalink
Add QgsCoordinateReferenceSystem::celestialBodyName
Browse files Browse the repository at this point in the history
Returns the associated celestial body name (proj 8.1+ only)
  • Loading branch information
nyalldawson committed May 10, 2021
1 parent 27085cf commit 95ed5ec
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 0 deletions.
71 changes: 71 additions & 0 deletions python/core/auto_generated/proj/qgscelestialbody.sip.in
@@ -0,0 +1,71 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/proj/qgscelestialbody.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/



class QgsCelestialBody
{
%Docstring(signature="appended")
Contains information about a celestial body.

.. note::

Only used in builds based on on PROJ 8.1 or later

.. versionadded:: 3.20
%End

%TypeHeaderCode
#include "qgscelestialbody.h"
%End
public:

bool isValid() const;
%Docstring
Returns ``True`` if the body is a valid object, or ``False`` if it is a null/invalid
object.
%End

QString name() const;
%Docstring
Name of celestial body.
%End

QString authority() const;
%Docstring
Authority name, e.g. EPSG.
%End

SIP_PYOBJECT __repr__();
%MethodCode
QString str;
if ( !sipCpp->isValid() )
{
str = QStringLiteral( "<QgsCelestialBody: invalid>" );
}
else
{
QString id;
if ( !sipCpp->authority().isEmpty() )
id = QStringLiteral( "%1 (%2)" ).arg( sipCpp->name(), sipCpp->authority() );
else
id = sipCpp->name();
str = QStringLiteral( "<QgsCelestialBody: %1>" ).arg( id );
}
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/proj/qgscelestialbody.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
Expand Up @@ -817,6 +817,20 @@ be returned.
:raises :: py:class:`QgsNotSupportedException` on QGIS builds based on PROJ 7 or earlier.


.. versionadded:: 3.20
%End

QString celestialBodyName() const throw( QgsNotSupportedException );
%Docstring
Attempts to retrieve the name of the celestial body associated with the CRS (e.g. "Earth").

.. 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
81 changes: 81 additions & 0 deletions src/core/proj/qgscelestialbody.h
@@ -0,0 +1,81 @@
/***************************************************************************
qgscelestialbody.h
------------------------
begin : May 2021
copyright : (C) 2021 Nyall Dawson
email : nyall dot dawson at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSCELESTIALBODY_H
#define QGSCELESTIALBODY_H

#include "qgis_core.h"
#include "qgis_sip.h"
#include <QString>

/**
* \ingroup core
* \brief Contains information about a celestial body.
*
* \note Only used in builds based on on PROJ 8.1 or later
* \since QGIS 3.20
*/
class CORE_EXPORT QgsCelestialBody
{
public:

/**
* Returns TRUE if the body is a valid object, or FALSE if it is a null/invalid
* object.
*/
bool isValid() const { return mValid; }

/**
* Name of celestial body.
*/
QString name() const { return mName; }

/**
* Authority name, e.g. EPSG.
*/
QString authority() const { return mAuthority; }

#ifdef SIP_RUN
SIP_PYOBJECT __repr__();
% MethodCode
QString str;
if ( !sipCpp->isValid() )
{
str = QStringLiteral( "<QgsCelestialBody: invalid>" );
}
else
{
QString id;
if ( !sipCpp->authority().isEmpty() )
id = QStringLiteral( "%1 (%2)" ).arg( sipCpp->name(), sipCpp->authority() );
else
id = sipCpp->name();
str = QStringLiteral( "<QgsCelestialBody: %1>" ).arg( id );
}
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
% End
#endif

private:

bool mValid = false;
QString mName;
QString mAuthority;

friend class QgsCoordinateReferenceSystemRegistry;
};

#endif // QGSCELESTIALBODY_H
15 changes: 15 additions & 0 deletions src/core/proj/qgscoordinatereferencesystem.cpp
Expand Up @@ -1210,6 +1210,21 @@ bool QgsCoordinateReferenceSystem::isDynamic() const
return QgsProjUtils::isDynamic( pj );
}

QString QgsCoordinateReferenceSystem::celestialBodyName() const
{
const PJ *pj = projObject();
if ( !pj )
return QString();

#if PROJ_VERSION_MAJOR>8 || (PROJ_VERSION_MAJOR==8 && PROJ_VERSION_MINOR>=1)
PJ_CONTEXT *context = QgsProjContext::get();

return QString( proj_get_celestial_body_name( context, pj ) );
#else
throw QgsNotSupportedException( QStringLiteral( "Retrieving celestial body requires a QGIS build based on PROJ 8.1 or later" ) );
#endif
}

void QgsCoordinateReferenceSystem::setCoordinateEpoch( double epoch )
{
if ( d->mCoordinateEpoch == epoch )
Expand Down
11 changes: 11 additions & 0 deletions src/core/proj/qgscoordinatereferencesystem.h
Expand Up @@ -756,6 +756,17 @@ class CORE_EXPORT QgsCoordinateReferenceSystem
*/
QgsDatumEnsemble datumEnsemble() const SIP_THROW( QgsNotSupportedException );

/**
* Attempts to retrieve the name of the celestial body associated with the CRS (e.g. "Earth").
*
* \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
*/
QString celestialBodyName() const SIP_THROW( QgsNotSupportedException );

/**
* Sets the coordinate \a epoch, as a decimal year.
*
Expand Down
13 changes: 13 additions & 0 deletions src/gui/qgsprojectionselectiontreewidget.cpp
Expand Up @@ -957,6 +957,19 @@ void QgsProjectionSelectionTreeWidget::updateBoundsPreview()
}
properties << ( currentCrs.isDynamic() ? tr( "Dynamic (relies on a datum which is not plate-fixed)" ) : tr( "Static (relies on a datum which is plate-fixed)" ) );

try
{
const QString celestialBody = currentCrs.celestialBodyName();
if ( !celestialBody.isEmpty() )
{
properties << tr( "Celestial body: %1" ).arg( celestialBody );
}
}
catch ( QgsNotSupportedException & )
{

}

try
{
const QgsDatumEnsemble ensemble = currentCrs.datumEnsemble();
Expand Down
15 changes: 15 additions & 0 deletions tests/src/core/testqgscoordinatereferencesystem.cpp
Expand Up @@ -79,6 +79,7 @@ class TestQgsCoordinateReferenceSystem: public QObject
void isGeographic();
void mapUnits();
void isDynamic();
void celestialBody();
void setValidationHint();
void hasAxisInverted();
void createFromProjInvalid();
Expand Down Expand Up @@ -1333,6 +1334,20 @@ void TestQgsCoordinateReferenceSystem::isDynamic()
#endif
}

void TestQgsCoordinateReferenceSystem::celestialBody()
{
#if (PROJ_VERSION_MAJOR>8 || (PROJ_VERSION_MAJOR==8 && PROJ_VERSION_MINOR >= 1 ) )
QgsCoordinateReferenceSystem crs;
QCOMPARE( crs.celestialBodyName(), QString() );

crs = QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) );
QCOMPARE( crs.celestialBodyName(), QStringLiteral( "Earth" ) );

crs = QgsCoordinateReferenceSystem( QStringLiteral( "ESRI:104903" ) );
QCOMPARE( crs.celestialBodyName(), QStringLiteral( "Moon" ) );
#endif
}

void TestQgsCoordinateReferenceSystem::setValidationHint()
{
QgsCoordinateReferenceSystem myCrs;
Expand Down

0 comments on commit 95ed5ec

Please sign in to comment.