Skip to content
Permalink
Browse files

When restoring a custom CRS from XML, if the CRS does NOT match

any of the existing user defined CRS's on the QGIS profile then
still restore the previously saved name of the custom CRS

This way we will correctly show the CRS with its original
name as defined by the original project author (instead of just
"custom crs")
  • Loading branch information
nyalldawson committed Sep 25, 2020
1 parent d3833fd commit e6d316ace7031821e04ca625e35f7c2c4d57f639
@@ -837,6 +837,11 @@ bool QgsCoordinateReferenceSystem::hasAxisInverted() const
}

bool QgsCoordinateReferenceSystem::createFromWkt( const QString &wkt )
{
return createFromWktInternal( wkt, QString() );
}

bool QgsCoordinateReferenceSystem::createFromWktInternal( const QString &wkt, const QString &description )
{
if ( wkt.isEmpty() )
return false;
@@ -851,6 +856,14 @@ bool QgsCoordinateReferenceSystem::createFromWkt( const QString &wkt )
{
// found a match in the cache
*this = crsIt.value();

if ( !description.isEmpty() && d->mDescription.isEmpty() )
{
// now we have a name for a previously unknown CRS! Update the cached CRS accordingly, so that we use the name from now on...
d->mDescription = description;
locker.changeMode( QgsReadWriteLocker::Write );
sWktCache()->insert( wkt, *this );
}
return true;
}
}
@@ -2036,8 +2049,14 @@ bool QgsCoordinateReferenceSystem::readXml( const QDomNode &node )
// if wkt is present, prefer that since it's lossless (unlike proj4 strings)
if ( !initialized )
{
// before doing anything, we grab and set the stored CRS name (description).
// this way if the stored CRS doesn't match anything available locally (i.e. from Proj's db
// or the user's custom CRS list), then we will correctly show the CRS with its original
// name (instead of just "custom crs")
const QString description = srsNode.namedItem( QStringLiteral( "description" ) ).toElement().text();

const QString wkt = srsNode.namedItem( QStringLiteral( "wkt" ) ).toElement().text();
initialized = createFromWkt( wkt );
initialized = createFromWktInternal( wkt, description );
}

if ( !initialized )
@@ -928,6 +928,8 @@ class CORE_EXPORT QgsCoordinateReferenceSystem
*/
bool loadFromDatabase( const QString &db, const QString &expression, const QString &value );

bool createFromWktInternal( const QString &wkt, const QString &description );

#if PROJ_VERSION_MAJOR<6 // not used for proj >= 6.0
static bool loadIds( QHash<int, QString> &wkts );
static bool loadWkts( QHash<int, QString> &wkts, const char *filename );
@@ -1119,6 +1119,35 @@ void TestQgsCoordinateReferenceSystem::readWriteXml()
QCOMPARE( myCrs19.toProj(), QStringLiteral( "+proj=lcc +lat_1=-36 +lat_2=-38 +lat_0=-37 +lon_0=145 +x_0=2500000 +y_0=2500000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs" ) );
QCOMPARE( myCrs19.toWkt(), QStringLiteral( R"""(PROJCS["GDA94 / Vicgrid",GEOGCS["GDA94",DATUM["Geocentric_Datum_of_Australia_1994",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6283"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4283"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",-36],PARAMETER["standard_parallel_2",-38],PARAMETER["latitude_of_origin",-37],PARAMETER["central_meridian",145],PARAMETER["false_easting",2500000],PARAMETER["false_northing",2500000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","3111"]])""" ) );
#endif

#if PROJ_VERSION_MAJOR>=6
// valid CRS from WKT string, not matching a local user CRS
QgsCoordinateReferenceSystem myCrs20;
myCrs20.createFromWkt( QStringLiteral( R"""(PROJCS["xxx",GEOGCS["GDA94",DATUM["Geocentric_Datum_of_Australia_1994",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[1,2,3,4,5,16,17],AUTHORITY["EPSG","6283"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4283"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],PROJECTION["Lambert_Conformal_Conic_2SP"],PARAMETER["standard_parallel_1",-36],PARAMETER["standard_parallel_2",-38],PARAMETER["latitude_of_origin",-37.5],PARAMETER["central_meridian",145.5],PARAMETER["false_easting",2533000],PARAMETER["false_northing",2533000],AXIS["Easting",EAST],AXIS["Northing",NORTH]])""" ) );
QVERIFY( myCrs20.isValid() );
node = document.createElement( QStringLiteral( "crs" ) );
document.appendChild( node );
QVERIFY( myCrs20.writeXml( node, document ) );
QgsCoordinateReferenceSystem myCrs21;
QVERIFY( myCrs21.readXml( node ) );
QVERIFY( myCrs21.isValid() );
QgsDebugMsg( myCrs21.toWkt( QgsCoordinateReferenceSystem::WKT2_2019 ) );
QCOMPARE( myCrs21.toWkt( QgsCoordinateReferenceSystem::WKT2_2019 ), QStringLiteral( R"""(BOUNDCRS[SOURCECRS[PROJCRS["xxx",BASEGEOGCRS["GDA94",DATUM["Geocentric Datum of Australia 1994",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4283]],CONVERSION["unnamed",METHOD["Lambert Conic Conformal (2SP)",ID["EPSG",9802]],PARAMETER["Latitude of 1st standard parallel",-36,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8823]],PARAMETER["Latitude of 2nd standard parallel",-38,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8824]],PARAMETER["Latitude of false origin",-37.5,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8821]],PARAMETER["Longitude of false origin",145.5,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8822]],PARAMETER["Easting at false origin",2533000,LENGTHUNIT["metre",1],ID["EPSG",8826]],PARAMETER["Northing at false origin",2533000,LENGTHUNIT["metre",1],ID["EPSG",8827]]],CS[Cartesian,2],AXIS["easting",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["northing",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]]],TARGETCRS[GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]]],ABRIDGEDTRANSFORMATION["Transformation from GDA94 to WGS84",METHOD["Position Vector transformation (geog2D domain)",ID["EPSG",9606]],PARAMETER["X-axis translation",1,ID["EPSG",8605]],PARAMETER["Y-axis translation",2,ID["EPSG",8606]],PARAMETER["Z-axis translation",3,ID["EPSG",8607]],PARAMETER["X-axis rotation",4,ID["EPSG",8608]],PARAMETER["Y-axis rotation",5,ID["EPSG",8609]],PARAMETER["Z-axis rotation",16,ID["EPSG",8610]],PARAMETER["Scale difference",1.000017,ID["EPSG",8611]]]])""" ) );
QCOMPARE( myCrs21.description(), QString() );

// now fudge in the description node to mimic as though the XML came from a different QGIS install where this CRS was a user-defined CRS with a name
QDomElement descriptionElement = document.createElement( QStringLiteral( "description" ) );
descriptionElement.appendChild( document.createTextNode( QStringLiteral( "someone else's previously saved CRS" ) ) );
node.toElement().elementsByTagName( QStringLiteral( "spatialrefsys" ) ).at( 0 ).toElement().removeChild( node.toElement().elementsByTagName( QStringLiteral( "spatialrefsys" ) ).at( 0 ).toElement().elementsByTagName( QStringLiteral( "description" ) ).at( 0 ) );
node.toElement().elementsByTagName( QStringLiteral( "spatialrefsys" ) ).at( 0 ).toElement().appendChild( descriptionElement );
QgsCoordinateReferenceSystem myCrs22;
QVERIFY( myCrs22.readXml( node ) );
QVERIFY( myCrs22.isValid() );
QgsDebugMsg( myCrs22.toWkt( QgsCoordinateReferenceSystem::WKT2_2019 ) );
QCOMPARE( myCrs22.toWkt( QgsCoordinateReferenceSystem::WKT2_2019 ), QStringLiteral( R"""(BOUNDCRS[SOURCECRS[PROJCRS["xxx",BASEGEOGCRS["GDA94",DATUM["Geocentric Datum of Australia 1994",ELLIPSOID["GRS 1980",6378137,298.257222101,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4283]],CONVERSION["unnamed",METHOD["Lambert Conic Conformal (2SP)",ID["EPSG",9802]],PARAMETER["Latitude of 1st standard parallel",-36,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8823]],PARAMETER["Latitude of 2nd standard parallel",-38,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8824]],PARAMETER["Latitude of false origin",-37.5,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8821]],PARAMETER["Longitude of false origin",145.5,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8822]],PARAMETER["Easting at false origin",2533000,LENGTHUNIT["metre",1],ID["EPSG",8826]],PARAMETER["Northing at false origin",2533000,LENGTHUNIT["metre",1],ID["EPSG",8827]]],CS[Cartesian,2],AXIS["easting",east,ORDER[1],LENGTHUNIT["metre",1,ID["EPSG",9001]]],AXIS["northing",north,ORDER[2],LENGTHUNIT["metre",1,ID["EPSG",9001]]]]],TARGETCRS[GEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]]],ABRIDGEDTRANSFORMATION["Transformation from GDA94 to WGS84",METHOD["Position Vector transformation (geog2D domain)",ID["EPSG",9606]],PARAMETER["X-axis translation",1,ID["EPSG",8605]],PARAMETER["Y-axis translation",2,ID["EPSG",8606]],PARAMETER["Z-axis translation",3,ID["EPSG",8607]],PARAMETER["X-axis rotation",4,ID["EPSG",8608]],PARAMETER["Y-axis rotation",5,ID["EPSG",8609]],PARAMETER["Z-axis rotation",16,ID["EPSG",8610]],PARAMETER["Scale difference",1.000017,ID["EPSG",8611]]]])""" ) );
// description should be restored, even though it's not a user-defined CRS on this install...
QCOMPARE( myCrs22.description(), QStringLiteral( "someone else's previously saved CRS" ) );
#endif
}

void TestQgsCoordinateReferenceSystem::setCustomSrsValidation()

0 comments on commit e6d316a

Please sign in to comment.
You can’t perform that action at this time.