From 370bdfd84d2750d264bdf8a7af4d919f9aaa846c Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Wed, 12 Jan 2022 12:19:29 +1000 Subject: [PATCH] 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 --- .../proj/qgscoordinatereferencesystem.sip.in | 28 +++++++++++++++ .../proj/qgscoordinatereferencesystem.cpp | 16 +++++++++ src/core/proj/qgscoordinatereferencesystem.h | 24 +++++++++++++ .../core/testqgscoordinatereferencesystem.cpp | 36 +++++++++++++++++++ 4 files changed, 104 insertions(+) diff --git a/python/core/auto_generated/proj/qgscoordinatereferencesystem.sip.in b/python/core/auto_generated/proj/qgscoordinatereferencesystem.sip.in index 3905e8a19ba..4778b990e5f 100644 --- a/python/core/auto_generated/proj/qgscoordinatereferencesystem.sip.in +++ b/python/core/auto_generated/proj/qgscoordinatereferencesystem.sip.in @@ -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. diff --git a/src/core/proj/qgscoordinatereferencesystem.cpp b/src/core/proj/qgscoordinatereferencesystem.cpp index 6234fbe727c..bfc18a3ea44 100644 --- a/src/core/proj/qgscoordinatereferencesystem.cpp +++ b/src/core/proj/qgscoordinatereferencesystem.cpp @@ -124,6 +124,7 @@ QgsCoordinateReferenceSystem::QgsCoordinateReferenceSystem( const long id, CrsTy QgsCoordinateReferenceSystem::QgsCoordinateReferenceSystem( const QgsCoordinateReferenceSystem &srs ) //NOLINT : d( srs.d ) , mValidationHint( srs.mValidationHint ) + , mNativeFormat( srs.mNativeFormat ) { } @@ -131,6 +132,7 @@ QgsCoordinateReferenceSystem &QgsCoordinateReferenceSystem::operator=( const Qgs { d = srs.d; mValidationHint = srs.mValidationHint; + mNativeFormat = srs.mNativeFormat; return *this; } @@ -1860,6 +1862,8 @@ bool QgsCoordinateReferenceSystem::readXml( const QDomNode &node ) { d->mCoordinateEpoch = std::numeric_limits< double >::quiet_NaN(); } + + mNativeFormat = qgsEnumKeyToValue( srsNode.toElement().attribute( QStringLiteral( "nativeFormat" ) ), Qgis::CrsDefinitionFormat::Wkt ); } else { @@ -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( mNativeFormat ) ); + if ( std::isfinite( d->mCoordinateEpoch ) ) { srsElement.setAttribute( QStringLiteral( "coordinateEpoch" ), d->mCoordinateEpoch ); @@ -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; diff --git a/src/core/proj/qgscoordinatereferencesystem.h b/src/core/proj/qgscoordinatereferencesystem.h index 7362df42ca7..7cf818d9430 100644 --- a/src/core/proj/qgscoordinatereferencesystem.h +++ b/src/core/proj/qgscoordinatereferencesystem.h @@ -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. * @@ -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() diff --git a/tests/src/core/testqgscoordinatereferencesystem.cpp b/tests/src/core/testqgscoordinatereferencesystem.cpp index 1242e10663d..11cb63fa63b 100644 --- a/tests/src/core/testqgscoordinatereferencesystem.cpp +++ b/tests/src/core/testqgscoordinatereferencesystem.cpp @@ -74,6 +74,8 @@ class TestQgsCoordinateReferenceSystem: public QObject void noEquality(); void equalityInvalid(); void readWriteXml(); + void readWriteXmlNativeFormatWkt(); + void readWriteXmlNativeFormatProj(); void setCustomSrsValidation(); void customSrsValidation(); void postgisSrid(); @@ -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;