Skip to content

Commit 353060d

Browse files
committedApr 5, 2019
Add helper method to determine whether a proj string uses angular units
1 parent 7095eff commit 353060d

File tree

5 files changed

+71
-5
lines changed

5 files changed

+71
-5
lines changed
 

‎src/app/qgscustomprojectiondialog.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -538,16 +538,23 @@ void QgsCustomProjectionDialog::pbnCalculate_clicked()
538538
{
539539
QString tmp;
540540

541-
int precision = 7;
541+
int precision = 4;
542+
bool isLatLong = false;
542543

543-
#if PROJ_VERSION_MAJOR<6
544-
if ( pj_is_latlong( proj ) )
544+
#if PROJ_VERSION_MAJOR>= 6
545+
isLatLong = QgsProjUtils::usesAngularUnit( projDef );
546+
#else
547+
isLatLong = pj_is_latlong( proj );
548+
if ( isLatLong )
545549
{
546550
northing *= RAD_TO_DEG;
547551
easting *= RAD_TO_DEG;
548-
precision = 7;
549552
}
550553
#endif
554+
if ( isLatLong )
555+
{
556+
precision = 7;
557+
}
551558

552559
tmp = QLocale().toString( northing, 'f', precision );
553560
projectedX->setText( tmp );

‎src/core/qgscoordinatetransform_p.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ ProjData QgsCoordinateTransformPrivate::threadLocalProjData()
267267
locker.changeMode( QgsReadWriteLocker::Write );
268268

269269
#if PROJ_VERSION_MAJOR>=6
270-
ProjData res = proj_create_crs_to_crs( context, mSourceProjString.toUtf8(), mDestProjString.toUtf8(), nullptr );
270+
ProjData res = proj_create_crs_to_crs( context, mSourceProjString.toUtf8().constData(), mDestProjString.toUtf8().constData(), nullptr );
271271
mProjProjections.insert( reinterpret_cast< uintptr_t>( context ), res );
272272
#else
273273
#ifdef USE_THREAD_LOCAL

‎src/core/qgsprojutils.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* *
1616
***************************************************************************/
1717
#include "qgsprojutils.h"
18+
#include <QString>
1819

1920
#if PROJ_VERSION_MAJOR>=6
2021
#include <proj.h>
@@ -71,4 +72,44 @@ void QgsProjUtils::ProjPJDeleter::operator()( PJ *object )
7172
{
7273
proj_destroy( object );
7374
}
75+
76+
bool QgsProjUtils::usesAngularUnit( const QString &projDef )
77+
{
78+
const QString crsDef = QStringLiteral( "%1 +type=crs" ).arg( projDef );
79+
PJ_CONTEXT *context = QgsProjContext::get();
80+
QgsProjUtils::proj_pj_unique_ptr projSingleOperation( proj_create( context, crsDef.toUtf8().constData() ) );
81+
if ( !projSingleOperation )
82+
return false;
83+
84+
QgsProjUtils::proj_pj_unique_ptr coordinateSystem( proj_crs_get_coordinate_system( context, projSingleOperation.get() ) );
85+
if ( !coordinateSystem )
86+
return false;
87+
88+
const int axisCount = proj_cs_get_axis_count( context, coordinateSystem.get() );
89+
if ( axisCount > 0 )
90+
{
91+
const char *outUnitAuthName = nullptr;
92+
const char *outUnitAuthCode = nullptr;
93+
// Read only first axis
94+
proj_cs_get_axis_info( context, coordinateSystem.get(), 0,
95+
nullptr,
96+
nullptr,
97+
nullptr,
98+
nullptr,
99+
nullptr,
100+
&outUnitAuthName,
101+
&outUnitAuthCode );
102+
103+
if ( outUnitAuthName && outUnitAuthCode )
104+
{
105+
const char *unitCategory = nullptr;
106+
if ( proj_uom_get_info_from_database( context, outUnitAuthName, outUnitAuthCode, nullptr, nullptr, &unitCategory ) )
107+
{
108+
return QString( unitCategory ).compare( QLatin1String( "angular" ), Qt::CaseInsensitive ) == 0;
109+
}
110+
}
111+
}
112+
return false;
113+
}
114+
74115
#endif

‎src/core/qgsprojutils.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,14 @@ class CORE_EXPORT QgsProjUtils
7373
*/
7474
using proj_pj_unique_ptr = std::unique_ptr< PJ, ProjPJDeleter >;
7575

76+
/**
77+
* Returns true if the given proj coordinate system uses angular units. \a projDef must be
78+
* a proj string defining a CRS object.
79+
*/
80+
static bool usesAngularUnit( const QString &projDef );
81+
82+
83+
7684
#endif
7785
#endif
7886
};

‎tests/src/core/testqgsprojutils.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class TestQgsProjUtils: public QObject
2929
void initTestCase();
3030
void cleanupTestCase();
3131
void threadSafeContext();
32+
void usesAngularUnits();
3233

3334
};
3435

@@ -67,5 +68,14 @@ void TestQgsProjUtils::threadSafeContext()
6768
QtConcurrent::blockingMap( list, ProjContextWrapper() );
6869
}
6970

71+
void TestQgsProjUtils::usesAngularUnits()
72+
{
73+
QVERIFY( !QgsProjUtils::usesAngularUnit( QString() ) );
74+
QVERIFY( !QgsProjUtils::usesAngularUnit( QString( "" ) ) );
75+
QVERIFY( !QgsProjUtils::usesAngularUnit( QStringLiteral( "x" ) ) );
76+
QVERIFY( QgsProjUtils::usesAngularUnit( QStringLiteral( "+proj=longlat +ellps=WGS60 +no_defs" ) ) );
77+
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" ) ) );
78+
}
79+
7080
QGSTEST_MAIN( TestQgsProjUtils )
7181
#include "testqgsprojutils.moc"

0 commit comments

Comments
 (0)
Please sign in to comment.