Skip to content

Commit

Permalink
Partial revert BoundCRS identification change
Browse files Browse the repository at this point in the history
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 20, 2019
1 parent 3d82440 commit 7ddd181
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/core/qgscoordinatereferencesystem.cpp
Expand Up @@ -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 ) )
Expand Down
9 changes: 6 additions & 3 deletions src/core/qgsprojutils.cpp
Expand Up @@ -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();
Expand All @@ -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;
Expand Down
10 changes: 9 additions & 1 deletion src/core/qgsprojutils.h
Expand Up @@ -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.
Expand Down Expand Up @@ -176,5 +183,6 @@ class CORE_EXPORT QgsProjContext
#endif
};

Q_DECLARE_OPERATORS_FOR_FLAGS( QgsProjUtils::IdentifyFlags )
#endif
#endif // QGSPROJUTILS_H
15 changes: 7 additions & 8 deletions tests/src/core/testqgscoordinatereferencesystem.cpp
Expand Up @@ -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
}

Expand Down

0 comments on commit 7ddd181

Please sign in to comment.