Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add api to allow the native format for a crs definition (i.e. wkt
or proj) to be saved when the crs is saved to xml

Allows us a way to present a custom crs in the same format as it was
originally defined using
  • Loading branch information
nyalldawson committed Jan 13, 2022
1 parent 33f4f1c commit 370bdfd
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 0 deletions.
Expand Up @@ -995,6 +995,34 @@ definition. FormatWkt is recommended as it is a lossless format.
Since QGIS 3.18, internally this calls :py:func:`QgsCoordinateReferenceSystemRegistry.addUserCrs()`.
%End

void setNativeFormat( Qgis::CrsDefinitionFormat format );
%Docstring
Sets the native ``format`` for the CRS definition.

.. note::

This has no effect on the underlying definition of the CRS, rather it controls what format
to use when displaying the CRS's definition to users.

.. seealso:: :py:func:`nativeFormat`

.. versionadded:: 3.24
%End

Qgis::CrsDefinitionFormat nativeFormat() const;
%Docstring
Returns the native format for the CRS definition.

.. note::

This has no effect on the underlying definition of the CRS, rather it controls what format
to use when displaying the CRS's definition to users.

.. seealso:: :py:func:`setNativeFormat`

.. versionadded:: 3.24
%End

QgsCoordinateReferenceSystem toGeographicCrs() const;
%Docstring
Returns the geographic CRS associated with this CRS object.
Expand Down
16 changes: 16 additions & 0 deletions src/core/proj/qgscoordinatereferencesystem.cpp
Expand Up @@ -124,13 +124,15 @@ QgsCoordinateReferenceSystem::QgsCoordinateReferenceSystem( const long id, CrsTy
QgsCoordinateReferenceSystem::QgsCoordinateReferenceSystem( const QgsCoordinateReferenceSystem &srs ) //NOLINT
: d( srs.d )
, mValidationHint( srs.mValidationHint )
, mNativeFormat( srs.mNativeFormat )
{
}

QgsCoordinateReferenceSystem &QgsCoordinateReferenceSystem::operator=( const QgsCoordinateReferenceSystem &srs ) //NOLINT
{
d = srs.d;
mValidationHint = srs.mValidationHint;
mNativeFormat = srs.mNativeFormat;
return *this;
}

Expand Down Expand Up @@ -1860,6 +1862,8 @@ bool QgsCoordinateReferenceSystem::readXml( const QDomNode &node )
{
d->mCoordinateEpoch = std::numeric_limits< double >::quiet_NaN();
}

mNativeFormat = qgsEnumKeyToValue<Qgis::CrsDefinitionFormat>( srsNode.toElement().attribute( QStringLiteral( "nativeFormat" ) ), Qgis::CrsDefinitionFormat::Wkt );
}
else
{
Expand All @@ -1875,6 +1879,8 @@ bool QgsCoordinateReferenceSystem::writeXml( QDomNode &node, QDomDocument &doc )
QDomElement layerNode = node.toElement();
QDomElement srsElement = doc.createElement( QStringLiteral( "spatialrefsys" ) );

srsElement.setAttribute( QStringLiteral( "nativeFormat" ), qgsEnumValueToKey<Qgis::CrsDefinitionFormat>( mNativeFormat ) );

if ( std::isfinite( d->mCoordinateEpoch ) )
{
srsElement.setAttribute( QStringLiteral( "coordinateEpoch" ), d->mCoordinateEpoch );
Expand Down Expand Up @@ -2052,6 +2058,16 @@ long QgsCoordinateReferenceSystem::saveAsUserCrs( const QString &name, Qgis::Crs
return QgsApplication::coordinateReferenceSystemRegistry()->addUserCrs( *this, name, nativeFormat );
}

void QgsCoordinateReferenceSystem::setNativeFormat( Qgis::CrsDefinitionFormat format )
{
mNativeFormat = format;
}

Qgis::CrsDefinitionFormat QgsCoordinateReferenceSystem::nativeFormat() const
{
return mNativeFormat;
}

long QgsCoordinateReferenceSystem::getRecordCount()
{
sqlite3_database_unique_ptr database;
Expand Down
24 changes: 24 additions & 0 deletions src/core/proj/qgscoordinatereferencesystem.h
Expand Up @@ -907,6 +907,28 @@ class CORE_EXPORT QgsCoordinateReferenceSystem
*/
long saveAsUserCrs( const QString &name, Qgis::CrsDefinitionFormat nativeFormat = Qgis::CrsDefinitionFormat::Wkt );

/**
* Sets the native \a format for the CRS definition.
*
* \note This has no effect on the underlying definition of the CRS, rather it controls what format
* to use when displaying the CRS's definition to users.
*
* \see nativeFormat()
* \since QGIS 3.24
*/
void setNativeFormat( Qgis::CrsDefinitionFormat format );

/**
* Returns the native format for the CRS definition.
*
* \note This has no effect on the underlying definition of the CRS, rather it controls what format
* to use when displaying the CRS's definition to users.
*
* \see setNativeFormat()
* \since QGIS 3.24
*/
Qgis::CrsDefinitionFormat nativeFormat() const;

/**
* Returns the geographic CRS associated with this CRS object.
*
Expand Down Expand Up @@ -1092,6 +1114,8 @@ class CORE_EXPORT QgsCoordinateReferenceSystem

QString mValidationHint;

Qgis::CrsDefinitionFormat mNativeFormat = Qgis::CrsDefinitionFormat::Wkt;

friend class QgsProjContext;

// Only meant to be called by QgsProjContext::~QgsProjContext()
Expand Down
36 changes: 36 additions & 0 deletions tests/src/core/testqgscoordinatereferencesystem.cpp
Expand Up @@ -74,6 +74,8 @@ class TestQgsCoordinateReferenceSystem: public QObject
void noEquality();
void equalityInvalid();
void readWriteXml();
void readWriteXmlNativeFormatWkt();
void readWriteXmlNativeFormatProj();
void setCustomSrsValidation();
void customSrsValidation();
void postgisSrid();
Expand Down Expand Up @@ -1308,6 +1310,40 @@ void TestQgsCoordinateReferenceSystem::readWriteXml()
QCOMPARE( myCrs21c.description(), QStringLiteral( "a new CRS C" ) );
}

void TestQgsCoordinateReferenceSystem::readWriteXmlNativeFormatWkt()
{
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromProj( QStringLiteral( "+proj=ortho +lat_0=-11 +lon_0=34 +x_0=0 +y_0=0 +ellps=sphere +units=m +no_defs +type=crs" ) );
crs.setNativeFormat( Qgis::CrsDefinitionFormat::Wkt );

QDomDocument document( QStringLiteral( "test" ) );
QDomElement node = document.createElement( QStringLiteral( "crs" ) );
document.appendChild( node );

QVERIFY( crs.writeXml( node, document ) );

QgsCoordinateReferenceSystem crs2;
QVERIFY( crs2.readXml( node ) );
QVERIFY( crs == crs2 );
QCOMPARE( crs2.nativeFormat(), Qgis::CrsDefinitionFormat::Wkt );
}

void TestQgsCoordinateReferenceSystem::readWriteXmlNativeFormatProj()
{
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromProj( QStringLiteral( "+proj=ortho +lat_0=-11.6 +lon_0=34 +x_0=0 +y_0=0 +ellps=sphere +units=m +no_defs +type=crs" ) );
crs.setNativeFormat( Qgis::CrsDefinitionFormat::Proj );

QDomDocument document( QStringLiteral( "test" ) );
QDomElement node = document.createElement( QStringLiteral( "crs" ) );
document.appendChild( node );

QVERIFY( crs.writeXml( node, document ) );

QgsCoordinateReferenceSystem crs2;
QVERIFY( crs2.readXml( node ) );
QVERIFY( crs == crs2 );
QCOMPARE( crs2.nativeFormat(), Qgis::CrsDefinitionFormat::Proj );
}

void TestQgsCoordinateReferenceSystem::setCustomSrsValidation()
{
//QgsCoordinateReferenceSystem myCrs;
Expand Down

0 comments on commit 370bdfd

Please sign in to comment.