Skip to content

Commit 48e6ec5

Browse files
authoredDec 19, 2017
Merge pull request #5906 from nyalldawson/datum
Datum fixes and cleanups
2 parents 13a888d + a77b5b6 commit 48e6ec5

18 files changed

+441
-392
lines changed
 

‎doc/api_break.dox

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -935,9 +935,9 @@ plugins calling these methods will need to be updated.
935935
- 'theNode', 'theDoc' parameters in readXML and writeXML have been renamed to 'node' and 'document' respectively
936936
- readXML() and writeXML() have been removed.
937937
- initialize() was removed.
938-
- datumTransformations() now returns a list of QgsCoordinateTransform.TransformPair instead of a list of lists.
939-
- datumTransformString() was renamed to datumTransformToProj()
940-
- datumTransformCrsInfo() was renamed to datumTransformInfo(), and now returns a QgsCoordinateTransform.TransformInfo object.
938+
- datumTransformations() was moved to QgsDatumTransform, and now returns a list of QgsDatumTransform.TransformPair instead of a list of lists.
939+
- datumTransformString() was moved to QgsDatumTransform and renamed to datumTransformToProj()
940+
- datumTransformCrsInfo() was moved to QgsDatumTransform and renamed to datumTransformInfo(), and now returns a QgsDatumTransform.TransformInfo object.
941941
- sourceDatumTransform() was renamed to sourceDatumTransformId()
942942
- setSourceDatumTransform() was renamed to setSourceDatumTransformId()
943943
- destinationDatumTransform() was renamed to destinationDatumTransformId()

‎python/core/qgscoordinatetransform.sip

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ transforms coordinates from the layer's coordinate system to the map canvas.
2828
.. note::
2929

3030
Since QGIS 3.0 QgsCoordinateReferenceSystem objects are implicitly shared.
31+
32+
.. seealso:: :py:class:`QgsDatumTransform`
33+
34+
.. seealso:: :py:class:`QgsCoordinateTransformContext`
3135
%End
3236

3337
%TypeHeaderCode
@@ -82,7 +86,7 @@ and it is used to retrieve the project's transform context only.
8286
%Docstring
8387
Constructs a QgsCoordinateTransform to transform from the ``source``
8488
to ``destination`` coordinate reference system, with the specified
85-
datum transforms.
89+
datum transforms (see QgsDatumTransform).
8690

8791
.. versionadded:: 3.0
8892
%End
@@ -252,47 +256,6 @@ otherwise points are transformed from destination to source CRS.
252256
bool isShortCircuited() const;
253257
%Docstring
254258
Returns true if the transform short circuits because the source and destination are equivalent.
255-
%End
256-
257-
static QList< QgsDatumTransform::TransformPair > datumTransformations( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination );
258-
%Docstring
259-
Returns a list of datum transformations which are available for the given ``source`` and ``destination`` CRS.
260-
261-
.. seealso:: :py:func:`datumTransformToProj()`
262-
263-
.. seealso:: :py:func:`datumTransformInfo()`
264-
%End
265-
266-
static QString datumTransformToProj( int datumTransformId );
267-
%Docstring
268-
Returns a proj string representing the specified ``datumTransformId`` datum transform ID.
269-
270-
.. seealso:: :py:func:`datumTransformations()`
271-
272-
.. seealso:: :py:func:`datumTransformInfo()`
273-
274-
.. seealso:: :py:func:`projStringToDatumTransformId()`
275-
%End
276-
277-
static int projStringToDatumTransformId( const QString &string );
278-
%Docstring
279-
Returns the datum transform ID corresponding to a specified proj ``string``.
280-
Returns -1 if matching datum ID was not found.
281-
282-
.. seealso:: :py:func:`datumTransformToProj()`
283-
284-
.. versionadded:: 3.0
285-
%End
286-
287-
static QgsDatumTransform::TransformInfo datumTransformInfo( int datumTransformId );
288-
%Docstring
289-
Returns detailed information about the specified ``datumTransformId``.
290-
If ``datumTransformId`` was not a valid transform ID, a TransformInfo with TransformInfo.datumTransformId of
291-
-1 will be returned.
292-
293-
.. seealso:: :py:func:`datumTransformations()`
294-
295-
.. seealso:: :py:func:`datumTransformToProj()`
296259
%End
297260

298261
int sourceDatumTransformId() const;
@@ -303,6 +266,8 @@ CRS.
303266
This is usually calculated automatically from the transform's QgsCoordinateTransformContext,
304267
but can be manually overwritten by a call to setSourceDatumTransformId().
305268

269+
.. seealso:: :py:class:`QgsDatumTransform`
270+
306271
.. seealso:: :py:func:`setSourceDatumTransformId()`
307272

308273
.. seealso:: :py:func:`destinationDatumTransformId()`
@@ -318,6 +283,8 @@ CRS.
318283
This is usually calculated automatically from the transform's QgsCoordinateTransformContext.
319284
Calling this method will overwrite any automatically calculated datum transform.
320285

286+
.. seealso:: :py:class:`QgsDatumTransform`
287+
321288
.. seealso:: :py:func:`sourceDatumTransformId()`
322289

323290
.. seealso:: :py:func:`setDestinationDatumTransformId()`
@@ -333,6 +300,8 @@ CRS.
333300
This is usually calculated automatically from the transform's QgsCoordinateTransformContext,
334301
but can be manually overwritten by a call to setDestinationDatumTransformId().
335302

303+
.. seealso:: :py:class:`QgsDatumTransform`
304+
336305
.. seealso:: :py:func:`setDestinationDatumTransformId()`
337306

338307
.. seealso:: :py:func:`sourceDatumTransformId()`
@@ -348,6 +317,8 @@ CRS.
348317
This is usually calculated automatically from the transform's QgsCoordinateTransformContext.
349318
Calling this method will overwrite any automatically calculated datum transform.
350319

320+
.. seealso:: :py:class:`QgsDatumTransform`
321+
351322
.. seealso:: :py:func:`destinationDatumTransformId()`
352323

353324
.. seealso:: :py:func:`setSourceDatumTransformId()`

‎python/core/qgscoordinatetransformcontext.sip

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ applies for destination CRS transforms set using addDestinationDatumTransform().
3737
QgsCoordinateTransformContext objects are implicitly shared.
3838

3939

40+
.. seealso:: :py:class:`QgsDatumTransform`
41+
42+
.. seealso:: :py:class:`QgsCoordinateTransform`
43+
44+
4045
.. versionadded:: 3.0
4146
%End
4247

‎python/core/qgsdatumtransform.sip

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,17 @@
88

99

1010

11+
12+
1113
class QgsDatumTransform
1214
{
1315
%Docstring
1416
Contains methods and classes relating the datum transformations.
1517

18+
.. seealso:: :py:class:`QgsCoordinateTransformContext`
19+
20+
.. seealso:: :py:class:`QgsCoordinateTransform`
21+
1622
.. versionadded:: 3.0
1723
%End
1824

@@ -103,6 +109,46 @@ True if transform is deprecated
103109
%End
104110

105111
};
112+
113+
static QList< QgsDatumTransform::TransformPair > datumTransformations( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination );
114+
%Docstring
115+
Returns a list of datum transformations which are available for the given ``source`` and ``destination`` CRS.
116+
117+
.. seealso:: :py:func:`datumTransformToProj()`
118+
119+
.. seealso:: :py:func:`datumTransformInfo()`
120+
%End
121+
122+
static QString datumTransformToProj( int datumTransformId );
123+
%Docstring
124+
Returns a proj string representing the specified ``datumTransformId`` datum transform ID.
125+
126+
.. seealso:: :py:func:`datumTransformations()`
127+
128+
.. seealso:: :py:func:`datumTransformInfo()`
129+
130+
.. seealso:: :py:func:`projStringToDatumTransformId()`
131+
%End
132+
133+
static int projStringToDatumTransformId( const QString &string );
134+
%Docstring
135+
Returns the datum transform ID corresponding to a specified proj ``string``.
136+
Returns -1 if matching datum ID was not found.
137+
138+
.. seealso:: :py:func:`datumTransformToProj()`
139+
%End
140+
141+
static QgsDatumTransform::TransformInfo datumTransformInfo( int datumTransformId );
142+
%Docstring
143+
Returns detailed information about the specified ``datumTransformId``.
144+
If ``datumTransformId`` was not a valid transform ID, a TransformInfo with TransformInfo.datumTransformId of
145+
-1 will be returned.
146+
147+
.. seealso:: :py:func:`datumTransformations()`
148+
149+
.. seealso:: :py:func:`datumTransformToProj()`
150+
%End
151+
106152
};
107153

108154
/************************************************************************

‎src/app/qgisapp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9151,7 +9151,7 @@ void QgisApp::projectCrsChanged()
91519151
if ( !transformsToAskFor.contains( it.value()->crs() ) &&
91529152
it.value()->crs() != QgsProject::instance()->crs() &&
91539153
!QgsProject::instance()->transformContext().hasTransform( it.value()->crs(), QgsProject::instance()->crs() ) &&
9154-
QgsCoordinateTransform::datumTransformations( it.value()->crs(), QgsProject::instance()->crs() ).count() > 1 )
9154+
QgsDatumTransform::datumTransformations( it.value()->crs(), QgsProject::instance()->crs() ).count() > 1 )
91559155
{
91569156
transformsToAskFor.append( it.value()->crs() );
91579157
}

‎src/app/qgsdatumtransformtablewidget.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ QVariant QgsDatumTransformTableModel::data( const QModelIndex &index, int role )
110110
case SourceTransformColumn:
111111
if ( sourceTransform != -1 )
112112
{
113-
return QgsCoordinateTransform::datumTransformToProj( sourceTransform );
113+
return QgsDatumTransform::datumTransformToProj( sourceTransform );
114114
}
115115
break;
116116
case DestinationCrsColumn:
@@ -119,7 +119,7 @@ QVariant QgsDatumTransformTableModel::data( const QModelIndex &index, int role )
119119
case DestinationTransformColumn:
120120
if ( destinationTransform != -1 )
121121
{
122-
return QgsCoordinateTransform::datumTransformToProj( destinationTransform );
122+
return QgsDatumTransform::datumTransformToProj( destinationTransform );
123123
}
124124
break;
125125
default:

‎src/core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ SET(QGIS_CORE_SRCS
161161
qgsdatasourceuri.cpp
162162
qgsdataprovider.cpp
163163
qgsdatetimestatisticalsummary.cpp
164+
qgsdatumtransform.cpp
164165
qgsdbfilterproxymodel.cpp
165166
qgsdefaultvalue.cpp
166167
qgsdiagramrenderer.cpp

‎src/core/qgscoordinatetransform.cpp

Lines changed: 0 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -700,97 +700,6 @@ const char *finder( const char *name )
700700
return proj.toUtf8();
701701
}
702702

703-
704-
705-
QList< QgsDatumTransform::TransformPair > QgsCoordinateTransform::datumTransformations( const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS )
706-
{
707-
QList< QgsDatumTransform::TransformPair > transformations;
708-
709-
QString srcGeoId = srcCRS.geographicCrsAuthId();
710-
QString destGeoId = destCRS.geographicCrsAuthId();
711-
712-
if ( srcGeoId.isEmpty() || destGeoId.isEmpty() )
713-
{
714-
return transformations;
715-
}
716-
717-
QStringList srcSplit = srcGeoId.split( ':' );
718-
QStringList destSplit = destGeoId.split( ':' );
719-
720-
if ( srcSplit.size() < 2 || destSplit.size() < 2 )
721-
{
722-
return transformations;
723-
}
724-
725-
int srcAuthCode = srcSplit.at( 1 ).toInt();
726-
int destAuthCode = destSplit.at( 1 ).toInt();
727-
728-
if ( srcAuthCode == destAuthCode )
729-
{
730-
return transformations; //crs have the same datum
731-
}
732-
733-
QList<int> directTransforms;
734-
searchDatumTransform( QStringLiteral( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code=%1 AND target_crs_code=%2 ORDER BY deprecated ASC,preferred DESC" ).arg( srcAuthCode ).arg( destAuthCode ),
735-
directTransforms );
736-
QList<int> reverseDirectTransforms;
737-
searchDatumTransform( QStringLiteral( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code = %1 AND target_crs_code=%2 ORDER BY deprecated ASC,preferred DESC" ).arg( destAuthCode ).arg( srcAuthCode ),
738-
reverseDirectTransforms );
739-
QList<int> srcToWgs84;
740-
searchDatumTransform( QStringLiteral( "SELECT coord_op_code FROM tbl_datum_transform WHERE (source_crs_code=%1 AND target_crs_code=%2) OR (source_crs_code=%2 AND target_crs_code=%1) ORDER BY deprecated ASC,preferred DESC" ).arg( srcAuthCode ).arg( 4326 ),
741-
srcToWgs84 );
742-
QList<int> destToWgs84;
743-
searchDatumTransform( QStringLiteral( "SELECT coord_op_code FROM tbl_datum_transform WHERE (source_crs_code=%1 AND target_crs_code=%2) OR (source_crs_code=%2 AND target_crs_code=%1) ORDER BY deprecated ASC,preferred DESC" ).arg( destAuthCode ).arg( 4326 ),
744-
destToWgs84 );
745-
746-
//add direct datum transformations
747-
for ( int transform : qgis::as_const( directTransforms ) )
748-
{
749-
transformations.push_back( QgsDatumTransform::TransformPair( transform, -1 ) );
750-
}
751-
752-
//add direct datum transformations
753-
for ( int transform : qgis::as_const( directTransforms ) )
754-
{
755-
transformations.push_back( QgsDatumTransform::TransformPair( -1, transform ) );
756-
}
757-
758-
for ( int srcTransform : qgis::as_const( srcToWgs84 ) )
759-
{
760-
for ( int destTransform : qgis::as_const( destToWgs84 ) )
761-
{
762-
transformations.push_back( QgsDatumTransform::TransformPair( srcTransform, destTransform ) );
763-
}
764-
}
765-
766-
return transformations;
767-
}
768-
769-
void QgsCoordinateTransform::searchDatumTransform( const QString &sql, QList< int > &transforms )
770-
{
771-
sqlite3_database_unique_ptr database;
772-
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
773-
if ( openResult != SQLITE_OK )
774-
{
775-
return;
776-
}
777-
778-
sqlite3_statement_unique_ptr statement;
779-
int prepareRes;
780-
statement = database.prepare( sql, prepareRes );
781-
if ( prepareRes != SQLITE_OK )
782-
{
783-
return;
784-
}
785-
786-
QString cOpCode;
787-
while ( statement.step() == SQLITE_ROW )
788-
{
789-
cOpCode = statement.columnAsText( 0 );
790-
transforms.push_back( cOpCode.toInt() );
791-
}
792-
}
793-
794703
bool QgsCoordinateTransform::setFromCache( const QgsCoordinateReferenceSystem &src, const QgsCoordinateReferenceSystem &dest, int srcDatumTransform, int destDatumTransform )
795704
{
796705
if ( !src.isValid() || !dest.isValid() )
@@ -833,61 +742,6 @@ void QgsCoordinateTransform::addToCache()
833742
sCacheLock.unlock();
834743
}
835744

836-
QString QgsCoordinateTransform::datumTransformToProj( int datumTransform )
837-
{
838-
return QgsCoordinateTransformPrivate::datumTransformString( datumTransform );
839-
}
840-
841-
int QgsCoordinateTransform::projStringToDatumTransformId( const QString &string )
842-
{
843-
return QgsCoordinateTransformPrivate::transformIdFromString( string );
844-
}
845-
846-
QgsDatumTransform::TransformInfo QgsCoordinateTransform::datumTransformInfo( int datumTransform )
847-
{
848-
QgsDatumTransform::TransformInfo info;
849-
850-
sqlite3_database_unique_ptr database;
851-
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
852-
if ( openResult != SQLITE_OK )
853-
{
854-
return info;
855-
}
856-
857-
sqlite3_statement_unique_ptr statement;
858-
QString sql = QStringLiteral( "SELECT epsg_nr,source_crs_code,target_crs_code,remarks,scope,preferred,deprecated FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( datumTransform );
859-
int prepareRes;
860-
statement = database.prepare( sql, prepareRes );
861-
if ( prepareRes != SQLITE_OK )
862-
{
863-
return info;
864-
}
865-
866-
int srcCrsId, destCrsId;
867-
if ( statement.step() != SQLITE_ROW )
868-
{
869-
return info;
870-
}
871-
872-
info.datumTransformId = datumTransform;
873-
info.epsgCode = statement.columnAsInt64( 0 );
874-
srcCrsId = statement.columnAsInt64( 1 );
875-
destCrsId = statement.columnAsInt64( 2 );
876-
info.remarks = statement.columnAsText( 3 );
877-
info.scope = statement.columnAsText( 4 );
878-
info.preferred = statement.columnAsInt64( 5 ) != 0;
879-
info.deprecated = statement.columnAsInt64( 6 ) != 0;
880-
881-
QgsCoordinateReferenceSystem srcCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( srcCrsId ) );
882-
info.sourceCrsDescription = srcCrs.description();
883-
info.sourceCrsAuthId = srcCrs.authid();
884-
QgsCoordinateReferenceSystem destCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( destCrsId ) );
885-
info.destinationCrsDescription = destCrs.description();
886-
info.destinationCrsAuthId = destCrs.authid();
887-
888-
return info;
889-
}
890-
891745
int QgsCoordinateTransform::sourceDatumTransformId() const
892746
{
893747
return d->mSourceDatumTransform;

‎src/core/qgscoordinatetransform.h

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ class QgsProject;
4444
* operations are from the perspective of the layer. For example, a forward transformation
4545
* transforms coordinates from the layer's coordinate system to the map canvas.
4646
* \note Since QGIS 3.0 QgsCoordinateReferenceSystem objects are implicitly shared.
47+
*
48+
* \see QgsDatumTransform
49+
* \see QgsCoordinateTransformContext
4750
*/
4851
class CORE_EXPORT QgsCoordinateTransform
4952
{
@@ -104,7 +107,7 @@ class CORE_EXPORT QgsCoordinateTransform
104107
/**
105108
* Constructs a QgsCoordinateTransform to transform from the \a source
106109
* to \a destination coordinate reference system, with the specified
107-
* datum transforms.
110+
* datum transforms (see QgsDatumTransform).
108111
*
109112
* \since QGIS 3.0
110113
*/
@@ -312,45 +315,14 @@ class CORE_EXPORT QgsCoordinateTransform
312315
*/
313316
bool isShortCircuited() const;
314317

315-
/**
316-
* Returns a list of datum transformations which are available for the given \a source and \a destination CRS.
317-
* \see datumTransformToProj()
318-
* \see datumTransformInfo()
319-
*/
320-
static QList< QgsDatumTransform::TransformPair > datumTransformations( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination );
321-
322-
/**
323-
* Returns a proj string representing the specified \a datumTransformId datum transform ID.
324-
* \see datumTransformations()
325-
* \see datumTransformInfo()
326-
* \see projStringToDatumTransformId()
327-
*/
328-
static QString datumTransformToProj( int datumTransformId );
329-
330-
/**
331-
* Returns the datum transform ID corresponding to a specified proj \a string.
332-
* Returns -1 if matching datum ID was not found.
333-
* \see datumTransformToProj()
334-
* \since QGIS 3.0
335-
*/
336-
static int projStringToDatumTransformId( const QString &string );
337-
338-
/**
339-
* Returns detailed information about the specified \a datumTransformId.
340-
* If \a datumTransformId was not a valid transform ID, a TransformInfo with TransformInfo::datumTransformId of
341-
* -1 will be returned.
342-
* \see datumTransformations()
343-
* \see datumTransformToProj()
344-
*/
345-
static QgsDatumTransform::TransformInfo datumTransformInfo( int datumTransformId );
346-
347318
/**
348319
* Returns the ID of the datum transform to use when projecting from the source
349320
* CRS.
350321
*
351322
* This is usually calculated automatically from the transform's QgsCoordinateTransformContext,
352323
* but can be manually overwritten by a call to setSourceDatumTransformId().
353324
*
325+
* \see QgsDatumTransform
354326
* \see setSourceDatumTransformId()
355327
* \see destinationDatumTransformId()
356328
* \see datumTransformInfo()
@@ -364,6 +336,7 @@ class CORE_EXPORT QgsCoordinateTransform
364336
* This is usually calculated automatically from the transform's QgsCoordinateTransformContext.
365337
* Calling this method will overwrite any automatically calculated datum transform.
366338
*
339+
* \see QgsDatumTransform
367340
* \see sourceDatumTransformId()
368341
* \see setDestinationDatumTransformId()
369342
* \see datumTransformInfo()
@@ -377,6 +350,7 @@ class CORE_EXPORT QgsCoordinateTransform
377350
* This is usually calculated automatically from the transform's QgsCoordinateTransformContext,
378351
* but can be manually overwritten by a call to setDestinationDatumTransformId().
379352
*
353+
* \see QgsDatumTransform
380354
* \see setDestinationDatumTransformId()
381355
* \see sourceDatumTransformId()
382356
* \see datumTransformInfo()
@@ -390,6 +364,7 @@ class CORE_EXPORT QgsCoordinateTransform
390364
* This is usually calculated automatically from the transform's QgsCoordinateTransformContext.
391365
* Calling this method will overwrite any automatically calculated datum transform.
392366
*
367+
* \see QgsDatumTransform
393368
* \see destinationDatumTransformId()
394369
* \see setSourceDatumTransformId()
395370
* \see datumTransformInfo()
@@ -406,8 +381,6 @@ class CORE_EXPORT QgsCoordinateTransform
406381

407382
private:
408383

409-
static void searchDatumTransform( const QString &sql, QList< int > &transforms );
410-
411384
mutable QExplicitlySharedDataPointer<QgsCoordinateTransformPrivate> d;
412385

413386
//! Transform context

‎src/core/qgscoordinatetransform_p.cpp

Lines changed: 2 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ bool QgsCoordinateTransformPrivate::initialize()
140140
}
141141
if ( sourceDatumTransform != -1 )
142142
{
143-
mSourceProjString += ( ' ' + datumTransformString( sourceDatumTransform ) );
143+
mSourceProjString += ( ' ' + QgsDatumTransform::datumTransformToProj( sourceDatumTransform ) );
144144
}
145145

146146
mDestProjString = mDestCRS.toProj4();
@@ -150,7 +150,7 @@ bool QgsCoordinateTransformPrivate::initialize()
150150
}
151151
if ( destDatumTransform != -1 )
152152
{
153-
mDestProjString += ( ' ' + datumTransformString( destDatumTransform ) );
153+
mDestProjString += ( ' ' + QgsDatumTransform::datumTransformToProj( destDatumTransform ) );
154154
}
155155

156156
if ( !useDefaultDatumTransform )
@@ -284,114 +284,6 @@ QString QgsCoordinateTransformPrivate::stripDatumTransform( const QString &proj4
284284
return newProjString;
285285
}
286286

287-
QString QgsCoordinateTransformPrivate::datumTransformString( int datumTransform )
288-
{
289-
QString transformString;
290-
291-
sqlite3_database_unique_ptr database;
292-
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
293-
if ( openResult != SQLITE_OK )
294-
{
295-
return transformString;
296-
}
297-
298-
sqlite3_statement_unique_ptr statement;
299-
QString sql = QStringLiteral( "SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7 FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( datumTransform );
300-
int prepareRes;
301-
statement = database.prepare( sql, prepareRes );
302-
if ( prepareRes != SQLITE_OK )
303-
{
304-
return transformString;
305-
}
306-
307-
if ( statement.step() == SQLITE_ROW )
308-
{
309-
//coord_op_methode_code
310-
int methodCode = statement.columnAsInt64( 0 );
311-
if ( methodCode == 9615 ) //ntv2
312-
{
313-
transformString = "+nadgrids=" + statement.columnAsText( 1 );
314-
}
315-
else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
316-
{
317-
transformString += QLatin1String( "+towgs84=" );
318-
double p1 = statement.columnAsDouble( 1 );
319-
double p2 = statement.columnAsDouble( 2 );
320-
double p3 = statement.columnAsDouble( 3 );
321-
double p4 = statement.columnAsDouble( 4 );
322-
double p5 = statement.columnAsDouble( 5 );
323-
double p6 = statement.columnAsDouble( 6 );
324-
double p7 = statement.columnAsDouble( 7 );
325-
if ( methodCode == 9603 ) //3 parameter transformation
326-
{
327-
transformString += QStringLiteral( "%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
328-
}
329-
else //7 parameter transformation
330-
{
331-
transformString += QStringLiteral( "%1,%2,%3,%4,%5,%6,%7" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ), QString::number( p4 ), QString::number( p5 ), QString::number( p6 ), QString::number( p7 ) );
332-
}
333-
}
334-
}
335-
336-
return transformString;
337-
}
338-
339-
int QgsCoordinateTransformPrivate::transformIdFromString( const QString &string )
340-
{
341-
sqlite3_database_unique_ptr database;
342-
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
343-
if ( openResult != SQLITE_OK )
344-
{
345-
return -1;
346-
}
347-
348-
sqlite3_statement_unique_ptr statement;
349-
QString sql = QStringLiteral( "SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7,coord_op_code FROM tbl_datum_transform" );
350-
int prepareRes;
351-
statement = database.prepare( sql, prepareRes );
352-
if ( prepareRes != SQLITE_OK )
353-
{
354-
return -1;
355-
}
356-
357-
while ( statement.step() == SQLITE_ROW )
358-
{
359-
QString transformString;
360-
//coord_op_methode_code
361-
int methodCode = statement.columnAsInt64( 0 );
362-
if ( methodCode == 9615 ) //ntv2
363-
{
364-
transformString = "+nadgrids=" + statement.columnAsText( 1 );
365-
}
366-
else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
367-
{
368-
transformString += QLatin1String( "+towgs84=" );
369-
double p1 = statement.columnAsDouble( 1 );
370-
double p2 = statement.columnAsDouble( 2 );
371-
double p3 = statement.columnAsDouble( 3 );
372-
double p4 = statement.columnAsDouble( 4 );
373-
double p5 = statement.columnAsDouble( 5 );
374-
double p6 = statement.columnAsDouble( 6 );
375-
double p7 = statement.columnAsDouble( 7 );
376-
if ( methodCode == 9603 ) //3 parameter transformation
377-
{
378-
transformString += QStringLiteral( "%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
379-
}
380-
else //7 parameter transformation
381-
{
382-
transformString += QStringLiteral( "%1,%2,%3,%4,%5,%6,%7" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ), QString::number( p4 ), QString::number( p5 ), QString::number( p6 ), QString::number( p7 ) );
383-
}
384-
}
385-
386-
if ( transformString.compare( string, Qt::CaseInsensitive ) == 0 )
387-
{
388-
return statement.columnAsInt64( 8 );
389-
}
390-
}
391-
392-
return -1;
393-
}
394-
395287
void QgsCoordinateTransformPrivate::addNullGridShifts( QString &srcProjString, QString &destProjString,
396288
int sourceDatumTransform, int destinationDatumTransform ) const
397289
{

‎src/core/qgscoordinatetransform_p.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -128,21 +128,6 @@ class QgsCoordinateTransformPrivate : public QSharedData
128128
QReadWriteLock mProjLock;
129129
QMap < uintptr_t, QPair< projPJ, projPJ > > mProjProjections;
130130

131-
/**
132-
* Returns the proj transform string corresponding to a
133-
* datum transform ID.
134-
* \see transformIdFromString()
135-
*/
136-
static QString datumTransformString( int transformId );
137-
138-
/**
139-
* Attempts to match a proj datum transform string to a datum ID.
140-
* Returns -1 if datum ID was not found.
141-
* \see datumTransformString()
142-
* \since QGIS 3.0
143-
*/
144-
static int transformIdFromString( const QString &string );
145-
146131
private:
147132

148133
//! Removes +nadgrids and +towgs84 from proj4 string

‎src/core/qgscoordinatetransformcontext.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ bool QgsCoordinateTransformContext::readXml( const QDomElement &element, const Q
203203
//warn if value1 or value2 is non-empty, yet no matching transform was found
204204
if ( !value1.isEmpty() )
205205
{
206-
datumId1 = QgsCoordinateTransform::projStringToDatumTransformId( value1 );
206+
datumId1 = QgsDatumTransform::projStringToDatumTransformId( value1 );
207207
if ( datumId1 < 0 )
208208
{
209209
result = false;
@@ -212,7 +212,7 @@ bool QgsCoordinateTransformContext::readXml( const QDomElement &element, const Q
212212
}
213213
if ( !value2.isEmpty() )
214214
{
215-
datumId2 = QgsCoordinateTransform::projStringToDatumTransformId( value2 );
215+
datumId2 = QgsDatumTransform::projStringToDatumTransformId( value2 );
216216
if ( datumId2 < 0 )
217217
{
218218
result = false;
@@ -271,8 +271,8 @@ void QgsCoordinateTransformContext::writeXml( QDomElement &element, const QgsRea
271271
QDomElement transformElem = element.ownerDocument().createElement( QStringLiteral( "srcDest" ) );
272272
transformElem.setAttribute( QStringLiteral( "source" ), it.key().first );
273273
transformElem.setAttribute( QStringLiteral( "dest" ), it.key().second );
274-
transformElem.setAttribute( QStringLiteral( "sourceTransform" ), it.value().sourceTransformId < 0 ? QString() : QgsCoordinateTransform::datumTransformToProj( it.value().sourceTransformId ) );
275-
transformElem.setAttribute( QStringLiteral( "destTransform" ), it.value().destinationTransformId < 0 ? QString() : QgsCoordinateTransform::datumTransformToProj( it.value().destinationTransformId ) );
274+
transformElem.setAttribute( QStringLiteral( "sourceTransform" ), it.value().sourceTransformId < 0 ? QString() : QgsDatumTransform::datumTransformToProj( it.value().sourceTransformId ) );
275+
transformElem.setAttribute( QStringLiteral( "destTransform" ), it.value().destinationTransformId < 0 ? QString() : QgsDatumTransform::datumTransformToProj( it.value().destinationTransformId ) );
276276
contextElem.appendChild( transformElem );
277277
}
278278

@@ -334,7 +334,7 @@ void QgsCoordinateTransformContext::readSettings()
334334
}
335335

336336
QString proj = settings.value( *pkeyIt ).toString();
337-
int datumId = QgsCoordinateTransform::projStringToDatumTransformId( proj );
337+
int datumId = QgsDatumTransform::projStringToDatumTransformId( proj );
338338
if ( pkeyIt->contains( QLatin1String( "srcTransform" ) ) )
339339
{
340340
transforms[ qMakePair( srcAuthId, destAuthId )].first = datumId;
@@ -378,11 +378,11 @@ void QgsCoordinateTransformContext::writeSettings()
378378
int sourceDatumTransform = transformIt.value().sourceTransformId;
379379
QString sourceDatumProj;
380380
if ( sourceDatumTransform >= 0 )
381-
sourceDatumProj = QgsCoordinateTransform::datumTransformToProj( sourceDatumTransform );
381+
sourceDatumProj = QgsDatumTransform::datumTransformToProj( sourceDatumTransform );
382382
int destinationDatumTransform = transformIt.value().destinationTransformId;
383383
QString destinationDatumProj;
384384
if ( destinationDatumTransform >= 0 )
385-
destinationDatumProj = QgsCoordinateTransform::datumTransformToProj( destinationDatumTransform );
385+
destinationDatumProj = QgsDatumTransform::datumTransformToProj( destinationDatumTransform );
386386

387387
settings.setValue( srcAuthId + "//" + destAuthId + "_srcTransform", sourceDatumProj );
388388
settings.setValue( srcAuthId + "//" + destAuthId + "_destTransform", destinationDatumProj );

‎src/core/qgscoordinatetransformcontext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ class QDomElement;
5353
*
5454
* \note QgsCoordinateTransformContext objects are implicitly shared.
5555
*
56+
* \see QgsDatumTransform
57+
* \see QgsCoordinateTransform
58+
*
5659
* \since QGIS 3.0
5760
*/
5861

‎src/core/qgsdatumtransform.cpp

Lines changed: 263 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,263 @@
1+
/***************************************************************************
2+
qgsdatumtransform.cpp
3+
------------------------
4+
begin : Dec 2017
5+
copyright : (C) 2017 Nyall Dawson
6+
email : nyall dot dawson at gmail dot com
7+
***************************************************************************/
8+
9+
/***************************************************************************
10+
* *
11+
* This program is free software; you can redistribute it and/or modify *
12+
* it under the terms of the GNU General Public License as published by *
13+
* the Free Software Foundation; either version 2 of the License, or *
14+
* (at your option) any later version. *
15+
* *
16+
***************************************************************************/
17+
#include "qgsdatumtransform.h"
18+
#include "qgscoordinatereferencesystem.h"
19+
#include "qgsapplication.h"
20+
#include "qgssqliteutils.h"
21+
#include <sqlite3.h>
22+
23+
QList< QgsDatumTransform::TransformPair > QgsDatumTransform::datumTransformations( const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS )
24+
{
25+
QList< QgsDatumTransform::TransformPair > transformations;
26+
27+
QString srcGeoId = srcCRS.geographicCrsAuthId();
28+
QString destGeoId = destCRS.geographicCrsAuthId();
29+
30+
if ( srcGeoId.isEmpty() || destGeoId.isEmpty() )
31+
{
32+
return transformations;
33+
}
34+
35+
QStringList srcSplit = srcGeoId.split( ':' );
36+
QStringList destSplit = destGeoId.split( ':' );
37+
38+
if ( srcSplit.size() < 2 || destSplit.size() < 2 )
39+
{
40+
return transformations;
41+
}
42+
43+
int srcAuthCode = srcSplit.at( 1 ).toInt();
44+
int destAuthCode = destSplit.at( 1 ).toInt();
45+
46+
if ( srcAuthCode == destAuthCode )
47+
{
48+
return transformations; //crs have the same datum
49+
}
50+
51+
QList<int> directTransforms;
52+
searchDatumTransform( QStringLiteral( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code=%1 AND target_crs_code=%2 ORDER BY deprecated ASC,preferred DESC" ).arg( srcAuthCode ).arg( destAuthCode ),
53+
directTransforms );
54+
QList<int> reverseDirectTransforms;
55+
searchDatumTransform( QStringLiteral( "SELECT coord_op_code FROM tbl_datum_transform WHERE source_crs_code = %1 AND target_crs_code=%2 ORDER BY deprecated ASC,preferred DESC" ).arg( destAuthCode ).arg( srcAuthCode ),
56+
reverseDirectTransforms );
57+
QList<int> srcToWgs84;
58+
searchDatumTransform( QStringLiteral( "SELECT coord_op_code FROM tbl_datum_transform WHERE (source_crs_code=%1 AND target_crs_code=%2) OR (source_crs_code=%2 AND target_crs_code=%1) ORDER BY deprecated ASC,preferred DESC" ).arg( srcAuthCode ).arg( 4326 ),
59+
srcToWgs84 );
60+
QList<int> destToWgs84;
61+
searchDatumTransform( QStringLiteral( "SELECT coord_op_code FROM tbl_datum_transform WHERE (source_crs_code=%1 AND target_crs_code=%2) OR (source_crs_code=%2 AND target_crs_code=%1) ORDER BY deprecated ASC,preferred DESC" ).arg( destAuthCode ).arg( 4326 ),
62+
destToWgs84 );
63+
64+
//add direct datum transformations
65+
for ( int transform : qgis::as_const( directTransforms ) )
66+
{
67+
transformations.push_back( QgsDatumTransform::TransformPair( transform, -1 ) );
68+
}
69+
70+
//add direct datum transformations
71+
for ( int transform : qgis::as_const( reverseDirectTransforms ) )
72+
{
73+
transformations.push_back( QgsDatumTransform::TransformPair( -1, transform ) );
74+
}
75+
76+
for ( int srcTransform : qgis::as_const( srcToWgs84 ) )
77+
{
78+
for ( int destTransform : qgis::as_const( destToWgs84 ) )
79+
{
80+
transformations.push_back( QgsDatumTransform::TransformPair( srcTransform, destTransform ) );
81+
}
82+
}
83+
84+
return transformations;
85+
}
86+
87+
void QgsDatumTransform::searchDatumTransform( const QString &sql, QList< int > &transforms )
88+
{
89+
sqlite3_database_unique_ptr database;
90+
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
91+
if ( openResult != SQLITE_OK )
92+
{
93+
return;
94+
}
95+
96+
sqlite3_statement_unique_ptr statement;
97+
int prepareRes;
98+
statement = database.prepare( sql, prepareRes );
99+
if ( prepareRes != SQLITE_OK )
100+
{
101+
return;
102+
}
103+
104+
QString cOpCode;
105+
while ( statement.step() == SQLITE_ROW )
106+
{
107+
cOpCode = statement.columnAsText( 0 );
108+
transforms.push_back( cOpCode.toInt() );
109+
}
110+
}
111+
112+
QString QgsDatumTransform::datumTransformToProj( int datumTransform )
113+
{
114+
QString transformString;
115+
116+
sqlite3_database_unique_ptr database;
117+
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
118+
if ( openResult != SQLITE_OK )
119+
{
120+
return transformString;
121+
}
122+
123+
sqlite3_statement_unique_ptr statement;
124+
QString sql = QStringLiteral( "SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7 FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( datumTransform );
125+
int prepareRes;
126+
statement = database.prepare( sql, prepareRes );
127+
if ( prepareRes != SQLITE_OK )
128+
{
129+
return transformString;
130+
}
131+
132+
if ( statement.step() == SQLITE_ROW )
133+
{
134+
//coord_op_methode_code
135+
int methodCode = statement.columnAsInt64( 0 );
136+
if ( methodCode == 9615 ) //ntv2
137+
{
138+
transformString = "+nadgrids=" + statement.columnAsText( 1 );
139+
}
140+
else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
141+
{
142+
transformString += QLatin1String( "+towgs84=" );
143+
double p1 = statement.columnAsDouble( 1 );
144+
double p2 = statement.columnAsDouble( 2 );
145+
double p3 = statement.columnAsDouble( 3 );
146+
double p4 = statement.columnAsDouble( 4 );
147+
double p5 = statement.columnAsDouble( 5 );
148+
double p6 = statement.columnAsDouble( 6 );
149+
double p7 = statement.columnAsDouble( 7 );
150+
if ( methodCode == 9603 ) //3 parameter transformation
151+
{
152+
transformString += QStringLiteral( "%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
153+
}
154+
else //7 parameter transformation
155+
{
156+
transformString += QStringLiteral( "%1,%2,%3,%4,%5,%6,%7" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ), QString::number( p4 ), QString::number( p5 ), QString::number( p6 ), QString::number( p7 ) );
157+
}
158+
}
159+
}
160+
161+
return transformString;
162+
}
163+
164+
int QgsDatumTransform::projStringToDatumTransformId( const QString &string )
165+
{
166+
sqlite3_database_unique_ptr database;
167+
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
168+
if ( openResult != SQLITE_OK )
169+
{
170+
return -1;
171+
}
172+
173+
sqlite3_statement_unique_ptr statement;
174+
QString sql = QStringLiteral( "SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7,coord_op_code FROM tbl_datum_transform" );
175+
int prepareRes;
176+
statement = database.prepare( sql, prepareRes );
177+
if ( prepareRes != SQLITE_OK )
178+
{
179+
return -1;
180+
}
181+
182+
while ( statement.step() == SQLITE_ROW )
183+
{
184+
QString transformString;
185+
//coord_op_methode_code
186+
int methodCode = statement.columnAsInt64( 0 );
187+
if ( methodCode == 9615 ) //ntv2
188+
{
189+
transformString = "+nadgrids=" + statement.columnAsText( 1 );
190+
}
191+
else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
192+
{
193+
transformString += QLatin1String( "+towgs84=" );
194+
double p1 = statement.columnAsDouble( 1 );
195+
double p2 = statement.columnAsDouble( 2 );
196+
double p3 = statement.columnAsDouble( 3 );
197+
double p4 = statement.columnAsDouble( 4 );
198+
double p5 = statement.columnAsDouble( 5 );
199+
double p6 = statement.columnAsDouble( 6 );
200+
double p7 = statement.columnAsDouble( 7 );
201+
if ( methodCode == 9603 ) //3 parameter transformation
202+
{
203+
transformString += QStringLiteral( "%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
204+
}
205+
else //7 parameter transformation
206+
{
207+
transformString += QStringLiteral( "%1,%2,%3,%4,%5,%6,%7" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ), QString::number( p4 ), QString::number( p5 ), QString::number( p6 ), QString::number( p7 ) );
208+
}
209+
}
210+
211+
if ( transformString.compare( string, Qt::CaseInsensitive ) == 0 )
212+
{
213+
return statement.columnAsInt64( 8 );
214+
}
215+
}
216+
217+
return -1;
218+
}
219+
220+
QgsDatumTransform::TransformInfo QgsDatumTransform::datumTransformInfo( int datumTransform )
221+
{
222+
QgsDatumTransform::TransformInfo info;
223+
224+
sqlite3_database_unique_ptr database;
225+
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
226+
if ( openResult != SQLITE_OK )
227+
{
228+
return info;
229+
}
230+
231+
sqlite3_statement_unique_ptr statement;
232+
QString sql = QStringLiteral( "SELECT epsg_nr,source_crs_code,target_crs_code,remarks,scope,preferred,deprecated FROM tbl_datum_transform WHERE coord_op_code=%1" ).arg( datumTransform );
233+
int prepareRes;
234+
statement = database.prepare( sql, prepareRes );
235+
if ( prepareRes != SQLITE_OK )
236+
{
237+
return info;
238+
}
239+
240+
int srcCrsId, destCrsId;
241+
if ( statement.step() != SQLITE_ROW )
242+
{
243+
return info;
244+
}
245+
246+
info.datumTransformId = datumTransform;
247+
info.epsgCode = statement.columnAsInt64( 0 );
248+
srcCrsId = statement.columnAsInt64( 1 );
249+
destCrsId = statement.columnAsInt64( 2 );
250+
info.remarks = statement.columnAsText( 3 );
251+
info.scope = statement.columnAsText( 4 );
252+
info.preferred = statement.columnAsInt64( 5 ) != 0;
253+
info.deprecated = statement.columnAsInt64( 6 ) != 0;
254+
255+
QgsCoordinateReferenceSystem srcCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( srcCrsId ) );
256+
info.sourceCrsDescription = srcCrs.description();
257+
info.sourceCrsAuthId = srcCrs.authid();
258+
QgsCoordinateReferenceSystem destCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( destCrsId ) );
259+
info.destinationCrsDescription = destCrs.description();
260+
info.destinationCrsAuthId = destCrs.authid();
261+
262+
return info;
263+
}

‎src/core/qgsdatumtransform.h

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,16 @@
2020
#include "qgis_core.h"
2121
#include <QString>
2222

23+
class QgsCoordinateReferenceSystem;
24+
25+
2326
/**
2427
* Contains methods and classes relating the datum transformations.
2528
* \ingroup core
29+
*
30+
* \see QgsCoordinateTransformContext
31+
* \see QgsCoordinateTransform
32+
*
2633
* \since QGIS 3.0
2734
*/
2835
class CORE_EXPORT QgsDatumTransform
@@ -107,6 +114,43 @@ class CORE_EXPORT QgsDatumTransform
107114
bool deprecated = false;
108115

109116
};
117+
118+
/**
119+
* Returns a list of datum transformations which are available for the given \a source and \a destination CRS.
120+
* \see datumTransformToProj()
121+
* \see datumTransformInfo()
122+
*/
123+
static QList< QgsDatumTransform::TransformPair > datumTransformations( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination );
124+
125+
/**
126+
* Returns a proj string representing the specified \a datumTransformId datum transform ID.
127+
* \see datumTransformations()
128+
* \see datumTransformInfo()
129+
* \see projStringToDatumTransformId()
130+
*/
131+
static QString datumTransformToProj( int datumTransformId );
132+
133+
/**
134+
* Returns the datum transform ID corresponding to a specified proj \a string.
135+
* Returns -1 if matching datum ID was not found.
136+
* \see datumTransformToProj()
137+
*/
138+
static int projStringToDatumTransformId( const QString &string );
139+
140+
/**
141+
* Returns detailed information about the specified \a datumTransformId.
142+
* If \a datumTransformId was not a valid transform ID, a TransformInfo with TransformInfo::datumTransformId of
143+
* -1 will be returned.
144+
* \see datumTransformations()
145+
* \see datumTransformToProj()
146+
*/
147+
static QgsDatumTransform::TransformInfo datumTransformInfo( int datumTransformId );
148+
149+
private:
150+
151+
static void searchDatumTransform( const QString &sql, QList< int > &transforms );
152+
153+
110154
};
111155

112156
#endif // QGSDATUMTRANSFORM_H

‎src/gui/qgsdatumtransformdialog.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ QgsDatumTransformDialog::QgsDatumTransformDialog( const QgsCoordinateReferenceSy
4646
//get list of datum transforms
4747
mSourceCrs = sourceCrs;
4848
mDestinationCrs = destinationCrs;
49-
mDatumTransforms = QgsCoordinateTransform::datumTransformations( sourceCrs, destinationCrs );
49+
mDatumTransforms = QgsDatumTransform::datumTransformations( sourceCrs, destinationCrs );
5050

5151
QApplication::setOverrideCursor( Qt::ArrowCursor );
5252

@@ -84,10 +84,10 @@ void QgsDatumTransformDialog::load( const QPair<int, int> &selectedDatumTransfor
8484
if ( nr == -1 )
8585
continue;
8686

87-
item->setText( i, QgsCoordinateTransform::datumTransformToProj( nr ) );
87+
item->setText( i, QgsDatumTransform::datumTransformToProj( nr ) );
8888

8989
//Describe datums in a tooltip
90-
QgsDatumTransform::TransformInfo info = QgsCoordinateTransform::datumTransformInfo( nr );
90+
QgsDatumTransform::TransformInfo info = QgsDatumTransform::datumTransformInfo( nr );
9191
if ( info.datumTransformId == -1 )
9292
continue;
9393

@@ -266,15 +266,15 @@ void QgsDatumTransformDialog::mDatumTransformTreeWidget_currentItemChanged( QTre
266266
void QgsDatumTransformDialog::setSourceCrs( const QgsCoordinateReferenceSystem &sourceCrs )
267267
{
268268
mSourceCrs = sourceCrs;
269-
mDatumTransforms = QgsCoordinateTransform::datumTransformations( mSourceCrs, mDestinationCrs );
269+
mDatumTransforms = QgsDatumTransform::datumTransformations( mSourceCrs, mDestinationCrs );
270270
load();
271271
setOKButtonEnabled();
272272
}
273273

274274
void QgsDatumTransformDialog::setDestinationCrs( const QgsCoordinateReferenceSystem &destinationCrs )
275275
{
276276
mDestinationCrs = destinationCrs;
277-
mDatumTransforms = QgsCoordinateTransform::datumTransformations( mSourceCrs, mDestinationCrs );
277+
mDatumTransforms = QgsDatumTransform::datumTransformations( mSourceCrs, mDestinationCrs );
278278
load();
279279
setOKButtonEnabled();
280280
}

‎tests/src/python/test_qgscoordinatetransform.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
QgsCoordinateReferenceSystem,
1919
QgsCoordinateTransform,
2020
QgsCoordinateTransformContext,
21+
QgsDatumTransform,
2122
QgsProject)
2223
from qgis.testing import start_app, unittest
2324

@@ -209,27 +210,38 @@ def testProjectContext(self):
209210

210211
def testTransformInfo(self):
211212
# hopefully this transform is available on all platforms!
212-
transforms = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4613), QgsCoordinateReferenceSystem(4326))
213+
transforms = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4613), QgsCoordinateReferenceSystem(4326))
213214
self.assertTrue(len(transforms) > 0)
214-
self.assertIn('+towgs84=-403,684,41', [QgsCoordinateTransform.datumTransformToProj(t.sourceTransformId) for t in transforms])
215-
self.assertIn('+towgs84=-403,684,41', [QgsCoordinateTransform.datumTransformToProj(t.destinationTransformId) for t in transforms])
216-
self.assertIn('EPSG:4613', [QgsCoordinateTransform.datumTransformInfo(t.destinationTransformId).sourceCrsAuthId for t in
215+
self.assertIn('+towgs84=-403,684,41', [QgsDatumTransform.datumTransformToProj(t.sourceTransformId) for t in transforms])
216+
self.assertEqual([''] * len(transforms), [QgsDatumTransform.datumTransformToProj(t.destinationTransformId) for t in transforms])
217+
self.assertIn('EPSG:4613', [QgsDatumTransform.datumTransformInfo(t.sourceTransformId).sourceCrsAuthId for t in
217218
transforms])
218-
self.assertIn('EPSG:4326', [QgsCoordinateTransform.datumTransformInfo(t.destinationTransformId).destinationCrsAuthId for t in
219+
self.assertEqual([''] * len(transforms), [QgsDatumTransform.datumTransformInfo(t.destinationTransformId).destinationCrsAuthId for t in
220+
transforms])
221+
222+
# and the reverse
223+
transforms = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4326), QgsCoordinateReferenceSystem(4613))
224+
self.assertTrue(len(transforms) > 0)
225+
self.assertEqual([''] * len(transforms), [QgsDatumTransform.datumTransformToProj(t.sourceTransformId) for t in transforms])
226+
self.assertIn('+towgs84=-403,684,41',
227+
[QgsDatumTransform.datumTransformToProj(t.destinationTransformId) for t in transforms])
228+
self.assertEqual([''] * len(transforms), [QgsDatumTransform.datumTransformInfo(t.sourceTransformId).destinationCrsAuthId for t in
229+
transforms])
230+
self.assertIn('EPSG:4613', [QgsDatumTransform.datumTransformInfo(t.destinationTransformId).sourceCrsAuthId for t in
219231
transforms])
220232

221233
def testStringToTransformId(self):
222234
"""
223235
Test converting proj strings to corresponding datum IDs
224236
"""
225-
self.assertEqual(QgsCoordinateTransform.projStringToDatumTransformId(''), -1)
226-
self.assertEqual(QgsCoordinateTransform.projStringToDatumTransformId('not'), -1)
237+
self.assertEqual(QgsDatumTransform.projStringToDatumTransformId(''), -1)
238+
self.assertEqual(QgsDatumTransform.projStringToDatumTransformId('not'), -1)
227239
test_string = '+towgs84=-403,684,41'
228-
id = QgsCoordinateTransform.projStringToDatumTransformId(test_string)
240+
id = QgsDatumTransform.projStringToDatumTransformId(test_string)
229241
self.assertNotEqual(id, -1)
230-
string = QgsCoordinateTransform.datumTransformToProj(id)
242+
string = QgsDatumTransform.datumTransformToProj(id)
231243
self.assertEqual(string, test_string)
232-
self.assertEqual(QgsCoordinateTransform.projStringToDatumTransformId(test_string.upper()), id)
244+
self.assertEqual(QgsDatumTransform.projStringToDatumTransformId(test_string.upper()), id)
233245

234246

235247
if __name__ == '__main__':

‎tests/src/python/test_qgscoordinatetransformcontext.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -302,15 +302,15 @@ def testWriteReadXml(self):
302302
# setup a context
303303
context = QgsCoordinateTransformContext()
304304

305-
source_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
306-
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
307-
dest_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
308-
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
305+
source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
306+
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
307+
dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
308+
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
309309

310-
source_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
311-
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
312-
dest_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
313-
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
310+
source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
311+
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
312+
dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
313+
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
314314

315315
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4204),
316316
QgsCoordinateReferenceSystem(4326), source_id_1, dest_id_1))
@@ -373,15 +373,15 @@ def testReadWriteSettings(self):
373373
context = QgsCoordinateTransformContext()
374374
context.readSettings()
375375

376-
source_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
377-
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
378-
dest_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
379-
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
376+
source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
377+
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
378+
dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
379+
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
380380

381-
source_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
382-
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
383-
dest_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
384-
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
381+
source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
382+
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
383+
dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
384+
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
385385

386386
# should be empty
387387
self.assertEqual(context.sourceDestinationDatumTransforms(), {})

0 commit comments

Comments
 (0)
Please sign in to comment.