Skip to content

Commit

Permalink
Add helper method to determine whether a proj string uses angular units
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Apr 5, 2019
1 parent 7095eff commit 353060d
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 5 deletions.
15 changes: 11 additions & 4 deletions src/app/qgscustomprojectiondialog.cpp
Expand Up @@ -538,16 +538,23 @@ void QgsCustomProjectionDialog::pbnCalculate_clicked()
{
QString tmp;

int precision = 7;
int precision = 4;
bool isLatLong = false;

#if PROJ_VERSION_MAJOR<6
if ( pj_is_latlong( proj ) )
#if PROJ_VERSION_MAJOR>= 6
isLatLong = QgsProjUtils::usesAngularUnit( projDef );
#else
isLatLong = pj_is_latlong( proj );
if ( isLatLong )
{
northing *= RAD_TO_DEG;
easting *= RAD_TO_DEG;
precision = 7;
}
#endif
if ( isLatLong )
{
precision = 7;
}

tmp = QLocale().toString( northing, 'f', precision );
projectedX->setText( tmp );
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgscoordinatetransform_p.cpp
Expand Up @@ -267,7 +267,7 @@ ProjData QgsCoordinateTransformPrivate::threadLocalProjData()
locker.changeMode( QgsReadWriteLocker::Write );

#if PROJ_VERSION_MAJOR>=6
ProjData res = proj_create_crs_to_crs( context, mSourceProjString.toUtf8(), mDestProjString.toUtf8(), nullptr );
ProjData res = proj_create_crs_to_crs( context, mSourceProjString.toUtf8().constData(), mDestProjString.toUtf8().constData(), nullptr );
mProjProjections.insert( reinterpret_cast< uintptr_t>( context ), res );
#else
#ifdef USE_THREAD_LOCAL
Expand Down
41 changes: 41 additions & 0 deletions src/core/qgsprojutils.cpp
Expand Up @@ -15,6 +15,7 @@
* *
***************************************************************************/
#include "qgsprojutils.h"
#include <QString>

#if PROJ_VERSION_MAJOR>=6
#include <proj.h>
Expand Down Expand Up @@ -71,4 +72,44 @@ void QgsProjUtils::ProjPJDeleter::operator()( PJ *object )
{
proj_destroy( object );
}

bool QgsProjUtils::usesAngularUnit( const QString &projDef )
{
const QString crsDef = QStringLiteral( "%1 +type=crs" ).arg( projDef );
PJ_CONTEXT *context = QgsProjContext::get();
QgsProjUtils::proj_pj_unique_ptr projSingleOperation( proj_create( context, crsDef.toUtf8().constData() ) );
if ( !projSingleOperation )
return false;

QgsProjUtils::proj_pj_unique_ptr coordinateSystem( proj_crs_get_coordinate_system( context, projSingleOperation.get() ) );
if ( !coordinateSystem )
return false;

const int axisCount = proj_cs_get_axis_count( context, coordinateSystem.get() );
if ( axisCount > 0 )
{
const char *outUnitAuthName = nullptr;
const char *outUnitAuthCode = nullptr;
// Read only first axis
proj_cs_get_axis_info( context, coordinateSystem.get(), 0,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
&outUnitAuthName,
&outUnitAuthCode );

if ( outUnitAuthName && outUnitAuthCode )
{
const char *unitCategory = nullptr;
if ( proj_uom_get_info_from_database( context, outUnitAuthName, outUnitAuthCode, nullptr, nullptr, &unitCategory ) )
{
return QString( unitCategory ).compare( QLatin1String( "angular" ), Qt::CaseInsensitive ) == 0;
}
}
}
return false;
}

#endif
8 changes: 8 additions & 0 deletions src/core/qgsprojutils.h
Expand Up @@ -73,6 +73,14 @@ class CORE_EXPORT QgsProjUtils
*/
using proj_pj_unique_ptr = std::unique_ptr< PJ, ProjPJDeleter >;

/**
* Returns true if the given proj coordinate system uses angular units. \a projDef must be
* a proj string defining a CRS object.
*/
static bool usesAngularUnit( const QString &projDef );



#endif
#endif
};
Expand Down
10 changes: 10 additions & 0 deletions tests/src/core/testqgsprojutils.cpp
Expand Up @@ -29,6 +29,7 @@ class TestQgsProjUtils: public QObject
void initTestCase();
void cleanupTestCase();
void threadSafeContext();
void usesAngularUnits();

};

Expand Down Expand Up @@ -67,5 +68,14 @@ void TestQgsProjUtils::threadSafeContext()
QtConcurrent::blockingMap( list, ProjContextWrapper() );
}

void TestQgsProjUtils::usesAngularUnits()
{
QVERIFY( !QgsProjUtils::usesAngularUnit( QString() ) );
QVERIFY( !QgsProjUtils::usesAngularUnit( QString( "" ) ) );
QVERIFY( !QgsProjUtils::usesAngularUnit( QStringLiteral( "x" ) ) );
QVERIFY( QgsProjUtils::usesAngularUnit( QStringLiteral( "+proj=longlat +ellps=WGS60 +no_defs" ) ) );
QVERIFY( !QgsProjUtils::usesAngularUnit( QStringLiteral( "+proj=tmerc +lat_0=0 +lon_0=147 +k_0=0.9996 +x_0=500000 +y_0=10000000 +ellps=GRS80 +units=m +no_defs" ) ) );
}

QGSTEST_MAIN( TestQgsProjUtils )
#include "testqgsprojutils.moc"

0 comments on commit 353060d

Please sign in to comment.