Skip to content
Permalink
Browse files

Partial revert BoundCRS identification change

Sync behavior with the new GDAL behavior, where a CRS defined using
a proj string alone will be considered equivalent to the underlying
source crs.

(cherry picked from commit 2e37301)
  • Loading branch information
nyalldawson committed Dec 18, 2019
1 parent 3d82440 commit 7ddd181f5760da0356108a6eb841ebc2dfd6f60b
@@ -838,7 +838,7 @@ bool QgsCoordinateReferenceSystem::createFromProj( const QString &projString )
{
QString authName;
QString authCode;
if ( QgsProjUtils::identifyCrs( crs.get(), authName, authCode ) )
if ( QgsProjUtils::identifyCrs( crs.get(), authName, authCode, QgsProjUtils::FlagMatchBoundCrsToUnderlyingSourceCrs ) )
{
const QString authid = QStringLiteral( "%1:%2" ).arg( authName, authCode );
if ( createFromOgcWmsCrs( authid ) )
@@ -184,7 +184,7 @@ QgsProjUtils::proj_pj_unique_ptr QgsProjUtils::crsToSingleCrs( const PJ *crs )
return nullptr;
}

bool QgsProjUtils::identifyCrs( const PJ *crs, QString &authName, QString &authCode )
bool QgsProjUtils::identifyCrs( const PJ *crs, QString &authName, QString &authCode, IdentifyFlags flags )
{
authName.clear();
authCode.clear();
@@ -207,8 +207,11 @@ bool QgsProjUtils::identifyCrs( const PJ *crs, QString &authName, QString &authC
{
case PJ_TYPE_BOUND_CRS:
// proj_identify also matches bound CRSes to the source CRS. But they are not the same as the source CRS, so we don't
// consider them a candidate for a match here
continue;
// consider them a candidate for a match here (depending on the identify flags, that is!)
if ( flags & FlagMatchBoundCrsToUnderlyingSourceCrs )
break;
else
continue;

default:
break;
@@ -103,13 +103,20 @@ class CORE_EXPORT QgsProjUtils
*/
static proj_pj_unique_ptr crsToSingleCrs( const PJ *crs );

//! Flags controlling CRS identification behavior
enum IdentifyFlag
{
FlagMatchBoundCrsToUnderlyingSourceCrs = 1 << 0, //!< Allow matching a BoundCRS object to its underlying SourceCRS
};
Q_DECLARE_FLAGS( IdentifyFlags, IdentifyFlag )

/**
* Attempts to identify a \a crs, matching it to a known authority and code within
* an acceptable level of tolerance.
*
* Returns TRUE if a matching authority and code was found.
*/
static bool identifyCrs( const PJ *crs, QString &authName, QString &authCode );
static bool identifyCrs( const PJ *crs, QString &authName, QString &authCode, IdentifyFlags flags = nullptr );

/**
* Returns TRUE if a coordinate operation (specified via proj string) is available.
@@ -176,5 +183,6 @@ class CORE_EXPORT QgsProjContext
#endif
};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsProjUtils::IdentifyFlags )
#endif
#endif // QGSPROJUTILS_H
@@ -429,17 +429,16 @@ void TestQgsCoordinateReferenceSystem::fromProj4EPSG20936()
{
#if PROJ_VERSION_MAJOR>=6
QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromProj( QStringLiteral( "+proj=utm +zone=36 +south +a=6378249.145 +b=6356514.966398753 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs" ) );
QVERIFY( crs.isValid() );
QCOMPARE( crs.toWkt(), QStringLiteral( R"""(PROJCS["unknown",GEOGCS["unknown",DATUM["unknown",SPHEROID["unknown",6378249.145,293.466307699995],TOWGS84[-143,-90,-294,0,0,0,0]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",33],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH]])""" ) );
QCOMPARE( crs.toProj(), QStringLiteral( "+proj=utm +zone=36 +south +a=6378249.145 +b=6356514.966398753 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs" ) );

// should ideally be EPSG:20936, but see https://github.com/OSGeo/PROJ/issues/1805
// so instead we get a BoundCRS of EPSG:20936 created from the proj string, which must be a user CRS (not EPSG:20936 itself!)
#if 0
// For consistency with GDAL, we treat BoundCRS defined from a proj string as equivalent to their underlying CRS (ie. in this case EPSG:20936)

QVERIFY( crs.isValid() );
QCOMPARE( crs.authid(), QStringLiteral( "EPSG:20936" ) );
#endif
// must NOT be a BoundCRS!
QCOMPARE( crs.toWkt(), QStringLiteral( R"""(PROJCS["Arc 1950 / UTM zone 36S",GEOGCS["Arc 1950",DATUM["Arc_1950",SPHEROID["Clarke 1880 (Arc)",6378249.145,293.4663077,AUTHORITY["EPSG","7013"]],AUTHORITY["EPSG","6209"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4209"]],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",0],PARAMETER["central_meridian",33],PARAMETER["scale_factor",0.9996],PARAMETER["false_easting",500000],PARAMETER["false_northing",10000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","20936"]])""" ) );
QCOMPARE( crs.toProj(), QStringLiteral( "+proj=utm +zone=36 +south +a=6378249.145 +rf=293.4663077 +towgs84=-143,-90,-294,0,0,0,0 +units=m +no_defs" ) );

QCOMPARE( crs.ellipsoidAcronym(), QStringLiteral( "PARAMETER:6378249.14499999955296516:6356514.96639875322580338" ) );
QCOMPARE( crs.ellipsoidAcronym(), QStringLiteral( "EPSG:7013" ) );
#endif
}

0 comments on commit 7ddd181

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