mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Move all datum transform related methods to QgsDatumTransform
This commit is contained in:
parent
e678bfa042
commit
f216b188d6
@ -935,9 +935,9 @@ plugins calling these methods will need to be updated.
|
|||||||
- 'theNode', 'theDoc' parameters in readXML and writeXML have been renamed to 'node' and 'document' respectively
|
- 'theNode', 'theDoc' parameters in readXML and writeXML have been renamed to 'node' and 'document' respectively
|
||||||
- readXML() and writeXML() have been removed.
|
- readXML() and writeXML() have been removed.
|
||||||
- initialize() was removed.
|
- initialize() was removed.
|
||||||
- datumTransformations() now returns a list of QgsCoordinateTransform.TransformPair instead of a list of lists.
|
- datumTransformations() was moved to QgsDatumTransform, and now returns a list of QgsDatumTransform.TransformPair instead of a list of lists.
|
||||||
- datumTransformString() was renamed to datumTransformToProj()
|
- datumTransformString() was moved to QgsDatumTransform and renamed to datumTransformToProj()
|
||||||
- datumTransformCrsInfo() was renamed to datumTransformInfo(), and now returns a QgsCoordinateTransform.TransformInfo object.
|
- datumTransformCrsInfo() was moved to QgsDatumTransform and renamed to datumTransformInfo(), and now returns a QgsDatumTransform.TransformInfo object.
|
||||||
- sourceDatumTransform() was renamed to sourceDatumTransformId()
|
- sourceDatumTransform() was renamed to sourceDatumTransformId()
|
||||||
- setSourceDatumTransform() was renamed to setSourceDatumTransformId()
|
- setSourceDatumTransform() was renamed to setSourceDatumTransformId()
|
||||||
- destinationDatumTransform() was renamed to destinationDatumTransformId()
|
- destinationDatumTransform() was renamed to destinationDatumTransformId()
|
||||||
|
@ -28,6 +28,10 @@ transforms coordinates from the layer's coordinate system to the map canvas.
|
|||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Since QGIS 3.0 QgsCoordinateReferenceSystem objects are implicitly shared.
|
Since QGIS 3.0 QgsCoordinateReferenceSystem objects are implicitly shared.
|
||||||
|
|
||||||
|
.. seealso:: :py:class:`QgsDatumTransform`
|
||||||
|
|
||||||
|
.. seealso:: :py:class:`QgsCoordinateTransformContext`
|
||||||
%End
|
%End
|
||||||
|
|
||||||
%TypeHeaderCode
|
%TypeHeaderCode
|
||||||
@ -252,47 +256,6 @@ otherwise points are transformed from destination to source CRS.
|
|||||||
bool isShortCircuited() const;
|
bool isShortCircuited() const;
|
||||||
%Docstring
|
%Docstring
|
||||||
Returns true if the transform short circuits because the source and destination are equivalent.
|
Returns true if the transform short circuits because the source and destination are equivalent.
|
||||||
%End
|
|
||||||
|
|
||||||
static QList< QgsDatumTransform::TransformPair > datumTransformations( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination );
|
|
||||||
%Docstring
|
|
||||||
Returns a list of datum transformations which are available for the given ``source`` and ``destination`` CRS.
|
|
||||||
|
|
||||||
.. seealso:: :py:func:`datumTransformToProj()`
|
|
||||||
|
|
||||||
.. seealso:: :py:func:`datumTransformInfo()`
|
|
||||||
%End
|
|
||||||
|
|
||||||
static QString datumTransformToProj( int datumTransformId );
|
|
||||||
%Docstring
|
|
||||||
Returns a proj string representing the specified ``datumTransformId`` datum transform ID.
|
|
||||||
|
|
||||||
.. seealso:: :py:func:`datumTransformations()`
|
|
||||||
|
|
||||||
.. seealso:: :py:func:`datumTransformInfo()`
|
|
||||||
|
|
||||||
.. seealso:: :py:func:`projStringToDatumTransformId()`
|
|
||||||
%End
|
|
||||||
|
|
||||||
static int projStringToDatumTransformId( const QString &string );
|
|
||||||
%Docstring
|
|
||||||
Returns the datum transform ID corresponding to a specified proj ``string``.
|
|
||||||
Returns -1 if matching datum ID was not found.
|
|
||||||
|
|
||||||
.. seealso:: :py:func:`datumTransformToProj()`
|
|
||||||
|
|
||||||
.. versionadded:: 3.0
|
|
||||||
%End
|
|
||||||
|
|
||||||
static QgsDatumTransform::TransformInfo datumTransformInfo( int datumTransformId );
|
|
||||||
%Docstring
|
|
||||||
Returns detailed information about the specified ``datumTransformId``.
|
|
||||||
If ``datumTransformId`` was not a valid transform ID, a TransformInfo with TransformInfo.datumTransformId of
|
|
||||||
-1 will be returned.
|
|
||||||
|
|
||||||
.. seealso:: :py:func:`datumTransformations()`
|
|
||||||
|
|
||||||
.. seealso:: :py:func:`datumTransformToProj()`
|
|
||||||
%End
|
%End
|
||||||
|
|
||||||
int sourceDatumTransformId() const;
|
int sourceDatumTransformId() const;
|
||||||
|
@ -37,6 +37,11 @@ applies for destination CRS transforms set using addDestinationDatumTransform().
|
|||||||
QgsCoordinateTransformContext objects are implicitly shared.
|
QgsCoordinateTransformContext objects are implicitly shared.
|
||||||
|
|
||||||
|
|
||||||
|
.. seealso:: :py:class:`QgsDatumTransform`
|
||||||
|
|
||||||
|
.. seealso:: :py:class:`QgsCoordinateTransform`
|
||||||
|
|
||||||
|
|
||||||
.. versionadded:: 3.0
|
.. versionadded:: 3.0
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
@ -8,11 +8,17 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class QgsDatumTransform
|
class QgsDatumTransform
|
||||||
{
|
{
|
||||||
%Docstring
|
%Docstring
|
||||||
Contains methods and classes relating the datum transformations.
|
Contains methods and classes relating the datum transformations.
|
||||||
|
|
||||||
|
.. seealso:: :py:class:`QgsCoordinateTransformContext`
|
||||||
|
|
||||||
|
.. seealso:: :py:class:`QgsCoordinateTransform`
|
||||||
|
|
||||||
.. versionadded:: 3.0
|
.. versionadded:: 3.0
|
||||||
%End
|
%End
|
||||||
|
|
||||||
@ -103,6 +109,46 @@ True if transform is deprecated
|
|||||||
%End
|
%End
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static QList< QgsDatumTransform::TransformPair > datumTransformations( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination );
|
||||||
|
%Docstring
|
||||||
|
Returns a list of datum transformations which are available for the given ``source`` and ``destination`` CRS.
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`datumTransformToProj()`
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`datumTransformInfo()`
|
||||||
|
%End
|
||||||
|
|
||||||
|
static QString datumTransformToProj( int datumTransformId );
|
||||||
|
%Docstring
|
||||||
|
Returns a proj string representing the specified ``datumTransformId`` datum transform ID.
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`datumTransformations()`
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`datumTransformInfo()`
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`projStringToDatumTransformId()`
|
||||||
|
%End
|
||||||
|
|
||||||
|
static int projStringToDatumTransformId( const QString &string );
|
||||||
|
%Docstring
|
||||||
|
Returns the datum transform ID corresponding to a specified proj ``string``.
|
||||||
|
Returns -1 if matching datum ID was not found.
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`datumTransformToProj()`
|
||||||
|
%End
|
||||||
|
|
||||||
|
static QgsDatumTransform::TransformInfo datumTransformInfo( int datumTransformId );
|
||||||
|
%Docstring
|
||||||
|
Returns detailed information about the specified ``datumTransformId``.
|
||||||
|
If ``datumTransformId`` was not a valid transform ID, a TransformInfo with TransformInfo.datumTransformId of
|
||||||
|
-1 will be returned.
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`datumTransformations()`
|
||||||
|
|
||||||
|
.. seealso:: :py:func:`datumTransformToProj()`
|
||||||
|
%End
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -9151,7 +9151,7 @@ void QgisApp::projectCrsChanged()
|
|||||||
if ( !transformsToAskFor.contains( it.value()->crs() ) &&
|
if ( !transformsToAskFor.contains( it.value()->crs() ) &&
|
||||||
it.value()->crs() != QgsProject::instance()->crs() &&
|
it.value()->crs() != QgsProject::instance()->crs() &&
|
||||||
!QgsProject::instance()->transformContext().hasTransform( it.value()->crs(), QgsProject::instance()->crs() ) &&
|
!QgsProject::instance()->transformContext().hasTransform( it.value()->crs(), QgsProject::instance()->crs() ) &&
|
||||||
QgsCoordinateTransform::datumTransformations( it.value()->crs(), QgsProject::instance()->crs() ).count() > 1 )
|
QgsDatumTransform::datumTransformations( it.value()->crs(), QgsProject::instance()->crs() ).count() > 1 )
|
||||||
{
|
{
|
||||||
transformsToAskFor.append( it.value()->crs() );
|
transformsToAskFor.append( it.value()->crs() );
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ QVariant QgsDatumTransformTableModel::data( const QModelIndex &index, int role )
|
|||||||
case SourceTransformColumn:
|
case SourceTransformColumn:
|
||||||
if ( sourceTransform != -1 )
|
if ( sourceTransform != -1 )
|
||||||
{
|
{
|
||||||
return QgsCoordinateTransform::datumTransformToProj( sourceTransform );
|
return QgsDatumTransform::datumTransformToProj( sourceTransform );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DestinationCrsColumn:
|
case DestinationCrsColumn:
|
||||||
@ -119,7 +119,7 @@ QVariant QgsDatumTransformTableModel::data( const QModelIndex &index, int role )
|
|||||||
case DestinationTransformColumn:
|
case DestinationTransformColumn:
|
||||||
if ( destinationTransform != -1 )
|
if ( destinationTransform != -1 )
|
||||||
{
|
{
|
||||||
return QgsCoordinateTransform::datumTransformToProj( destinationTransform );
|
return QgsDatumTransform::datumTransformToProj( destinationTransform );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -161,6 +161,7 @@ SET(QGIS_CORE_SRCS
|
|||||||
qgsdatasourceuri.cpp
|
qgsdatasourceuri.cpp
|
||||||
qgsdataprovider.cpp
|
qgsdataprovider.cpp
|
||||||
qgsdatetimestatisticalsummary.cpp
|
qgsdatetimestatisticalsummary.cpp
|
||||||
|
qgsdatumtransform.cpp
|
||||||
qgsdbfilterproxymodel.cpp
|
qgsdbfilterproxymodel.cpp
|
||||||
qgsdefaultvalue.cpp
|
qgsdefaultvalue.cpp
|
||||||
qgsdiagramrenderer.cpp
|
qgsdiagramrenderer.cpp
|
||||||
|
@ -700,97 +700,6 @@ const char *finder( const char *name )
|
|||||||
return proj.toUtf8();
|
return proj.toUtf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QList< QgsDatumTransform::TransformPair > QgsCoordinateTransform::datumTransformations( const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS )
|
|
||||||
{
|
|
||||||
QList< QgsDatumTransform::TransformPair > transformations;
|
|
||||||
|
|
||||||
QString srcGeoId = srcCRS.geographicCrsAuthId();
|
|
||||||
QString destGeoId = destCRS.geographicCrsAuthId();
|
|
||||||
|
|
||||||
if ( srcGeoId.isEmpty() || destGeoId.isEmpty() )
|
|
||||||
{
|
|
||||||
return transformations;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList srcSplit = srcGeoId.split( ':' );
|
|
||||||
QStringList destSplit = destGeoId.split( ':' );
|
|
||||||
|
|
||||||
if ( srcSplit.size() < 2 || destSplit.size() < 2 )
|
|
||||||
{
|
|
||||||
return transformations;
|
|
||||||
}
|
|
||||||
|
|
||||||
int srcAuthCode = srcSplit.at( 1 ).toInt();
|
|
||||||
int destAuthCode = destSplit.at( 1 ).toInt();
|
|
||||||
|
|
||||||
if ( srcAuthCode == destAuthCode )
|
|
||||||
{
|
|
||||||
return transformations; //crs have the same datum
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<int> directTransforms;
|
|
||||||
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 ),
|
|
||||||
directTransforms );
|
|
||||||
QList<int> reverseDirectTransforms;
|
|
||||||
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 ),
|
|
||||||
reverseDirectTransforms );
|
|
||||||
QList<int> srcToWgs84;
|
|
||||||
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 ),
|
|
||||||
srcToWgs84 );
|
|
||||||
QList<int> destToWgs84;
|
|
||||||
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 ),
|
|
||||||
destToWgs84 );
|
|
||||||
|
|
||||||
//add direct datum transformations
|
|
||||||
for ( int transform : qgis::as_const( directTransforms ) )
|
|
||||||
{
|
|
||||||
transformations.push_back( QgsDatumTransform::TransformPair( transform, -1 ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
//add direct datum transformations
|
|
||||||
for ( int transform : qgis::as_const( directTransforms ) )
|
|
||||||
{
|
|
||||||
transformations.push_back( QgsDatumTransform::TransformPair( -1, transform ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int srcTransform : qgis::as_const( srcToWgs84 ) )
|
|
||||||
{
|
|
||||||
for ( int destTransform : qgis::as_const( destToWgs84 ) )
|
|
||||||
{
|
|
||||||
transformations.push_back( QgsDatumTransform::TransformPair( srcTransform, destTransform ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return transformations;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QgsCoordinateTransform::searchDatumTransform( const QString &sql, QList< int > &transforms )
|
|
||||||
{
|
|
||||||
sqlite3_database_unique_ptr database;
|
|
||||||
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
|
|
||||||
if ( openResult != SQLITE_OK )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_statement_unique_ptr statement;
|
|
||||||
int prepareRes;
|
|
||||||
statement = database.prepare( sql, prepareRes );
|
|
||||||
if ( prepareRes != SQLITE_OK )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString cOpCode;
|
|
||||||
while ( statement.step() == SQLITE_ROW )
|
|
||||||
{
|
|
||||||
cOpCode = statement.columnAsText( 0 );
|
|
||||||
transforms.push_back( cOpCode.toInt() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool QgsCoordinateTransform::setFromCache( const QgsCoordinateReferenceSystem &src, const QgsCoordinateReferenceSystem &dest, int srcDatumTransform, int destDatumTransform )
|
bool QgsCoordinateTransform::setFromCache( const QgsCoordinateReferenceSystem &src, const QgsCoordinateReferenceSystem &dest, int srcDatumTransform, int destDatumTransform )
|
||||||
{
|
{
|
||||||
if ( !src.isValid() || !dest.isValid() )
|
if ( !src.isValid() || !dest.isValid() )
|
||||||
@ -833,61 +742,6 @@ void QgsCoordinateTransform::addToCache()
|
|||||||
sCacheLock.unlock();
|
sCacheLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QgsCoordinateTransform::datumTransformToProj( int datumTransform )
|
|
||||||
{
|
|
||||||
return QgsCoordinateTransformPrivate::datumTransformString( datumTransform );
|
|
||||||
}
|
|
||||||
|
|
||||||
int QgsCoordinateTransform::projStringToDatumTransformId( const QString &string )
|
|
||||||
{
|
|
||||||
return QgsCoordinateTransformPrivate::transformIdFromString( string );
|
|
||||||
}
|
|
||||||
|
|
||||||
QgsDatumTransform::TransformInfo QgsCoordinateTransform::datumTransformInfo( int datumTransform )
|
|
||||||
{
|
|
||||||
QgsDatumTransform::TransformInfo info;
|
|
||||||
|
|
||||||
sqlite3_database_unique_ptr database;
|
|
||||||
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
|
|
||||||
if ( openResult != SQLITE_OK )
|
|
||||||
{
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_statement_unique_ptr statement;
|
|
||||||
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 );
|
|
||||||
int prepareRes;
|
|
||||||
statement = database.prepare( sql, prepareRes );
|
|
||||||
if ( prepareRes != SQLITE_OK )
|
|
||||||
{
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
int srcCrsId, destCrsId;
|
|
||||||
if ( statement.step() != SQLITE_ROW )
|
|
||||||
{
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
info.datumTransformId = datumTransform;
|
|
||||||
info.epsgCode = statement.columnAsInt64( 0 );
|
|
||||||
srcCrsId = statement.columnAsInt64( 1 );
|
|
||||||
destCrsId = statement.columnAsInt64( 2 );
|
|
||||||
info.remarks = statement.columnAsText( 3 );
|
|
||||||
info.scope = statement.columnAsText( 4 );
|
|
||||||
info.preferred = statement.columnAsInt64( 5 ) != 0;
|
|
||||||
info.deprecated = statement.columnAsInt64( 6 ) != 0;
|
|
||||||
|
|
||||||
QgsCoordinateReferenceSystem srcCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( srcCrsId ) );
|
|
||||||
info.sourceCrsDescription = srcCrs.description();
|
|
||||||
info.sourceCrsAuthId = srcCrs.authid();
|
|
||||||
QgsCoordinateReferenceSystem destCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( destCrsId ) );
|
|
||||||
info.destinationCrsDescription = destCrs.description();
|
|
||||||
info.destinationCrsAuthId = destCrs.authid();
|
|
||||||
|
|
||||||
return info;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QgsCoordinateTransform::sourceDatumTransformId() const
|
int QgsCoordinateTransform::sourceDatumTransformId() const
|
||||||
{
|
{
|
||||||
return d->mSourceDatumTransform;
|
return d->mSourceDatumTransform;
|
||||||
|
@ -44,6 +44,9 @@ class QgsProject;
|
|||||||
* operations are from the perspective of the layer. For example, a forward transformation
|
* operations are from the perspective of the layer. For example, a forward transformation
|
||||||
* transforms coordinates from the layer's coordinate system to the map canvas.
|
* transforms coordinates from the layer's coordinate system to the map canvas.
|
||||||
* \note Since QGIS 3.0 QgsCoordinateReferenceSystem objects are implicitly shared.
|
* \note Since QGIS 3.0 QgsCoordinateReferenceSystem objects are implicitly shared.
|
||||||
|
*
|
||||||
|
* \see QgsDatumTransform
|
||||||
|
* \see QgsCoordinateTransformContext
|
||||||
*/
|
*/
|
||||||
class CORE_EXPORT QgsCoordinateTransform
|
class CORE_EXPORT QgsCoordinateTransform
|
||||||
{
|
{
|
||||||
@ -312,38 +315,6 @@ class CORE_EXPORT QgsCoordinateTransform
|
|||||||
*/
|
*/
|
||||||
bool isShortCircuited() const;
|
bool isShortCircuited() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of datum transformations which are available for the given \a source and \a destination CRS.
|
|
||||||
* \see datumTransformToProj()
|
|
||||||
* \see datumTransformInfo()
|
|
||||||
*/
|
|
||||||
static QList< QgsDatumTransform::TransformPair > datumTransformations( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a proj string representing the specified \a datumTransformId datum transform ID.
|
|
||||||
* \see datumTransformations()
|
|
||||||
* \see datumTransformInfo()
|
|
||||||
* \see projStringToDatumTransformId()
|
|
||||||
*/
|
|
||||||
static QString datumTransformToProj( int datumTransformId );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the datum transform ID corresponding to a specified proj \a string.
|
|
||||||
* Returns -1 if matching datum ID was not found.
|
|
||||||
* \see datumTransformToProj()
|
|
||||||
* \since QGIS 3.0
|
|
||||||
*/
|
|
||||||
static int projStringToDatumTransformId( const QString &string );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns detailed information about the specified \a datumTransformId.
|
|
||||||
* If \a datumTransformId was not a valid transform ID, a TransformInfo with TransformInfo::datumTransformId of
|
|
||||||
* -1 will be returned.
|
|
||||||
* \see datumTransformations()
|
|
||||||
* \see datumTransformToProj()
|
|
||||||
*/
|
|
||||||
static QgsDatumTransform::TransformInfo datumTransformInfo( int datumTransformId );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the ID of the datum transform to use when projecting from the source
|
* Returns the ID of the datum transform to use when projecting from the source
|
||||||
* CRS.
|
* CRS.
|
||||||
@ -406,8 +377,6 @@ class CORE_EXPORT QgsCoordinateTransform
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static void searchDatumTransform( const QString &sql, QList< int > &transforms );
|
|
||||||
|
|
||||||
mutable QExplicitlySharedDataPointer<QgsCoordinateTransformPrivate> d;
|
mutable QExplicitlySharedDataPointer<QgsCoordinateTransformPrivate> d;
|
||||||
|
|
||||||
//! Transform context
|
//! Transform context
|
||||||
|
@ -140,7 +140,7 @@ bool QgsCoordinateTransformPrivate::initialize()
|
|||||||
}
|
}
|
||||||
if ( sourceDatumTransform != -1 )
|
if ( sourceDatumTransform != -1 )
|
||||||
{
|
{
|
||||||
mSourceProjString += ( ' ' + datumTransformString( sourceDatumTransform ) );
|
mSourceProjString += ( ' ' + QgsDatumTransform::datumTransformToProj( sourceDatumTransform ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
mDestProjString = mDestCRS.toProj4();
|
mDestProjString = mDestCRS.toProj4();
|
||||||
@ -150,7 +150,7 @@ bool QgsCoordinateTransformPrivate::initialize()
|
|||||||
}
|
}
|
||||||
if ( destDatumTransform != -1 )
|
if ( destDatumTransform != -1 )
|
||||||
{
|
{
|
||||||
mDestProjString += ( ' ' + datumTransformString( destDatumTransform ) );
|
mDestProjString += ( ' ' + QgsDatumTransform::datumTransformToProj( destDatumTransform ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !useDefaultDatumTransform )
|
if ( !useDefaultDatumTransform )
|
||||||
@ -284,114 +284,6 @@ QString QgsCoordinateTransformPrivate::stripDatumTransform( const QString &proj4
|
|||||||
return newProjString;
|
return newProjString;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QgsCoordinateTransformPrivate::datumTransformString( int datumTransform )
|
|
||||||
{
|
|
||||||
QString transformString;
|
|
||||||
|
|
||||||
sqlite3_database_unique_ptr database;
|
|
||||||
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
|
|
||||||
if ( openResult != SQLITE_OK )
|
|
||||||
{
|
|
||||||
return transformString;
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_statement_unique_ptr statement;
|
|
||||||
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 );
|
|
||||||
int prepareRes;
|
|
||||||
statement = database.prepare( sql, prepareRes );
|
|
||||||
if ( prepareRes != SQLITE_OK )
|
|
||||||
{
|
|
||||||
return transformString;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( statement.step() == SQLITE_ROW )
|
|
||||||
{
|
|
||||||
//coord_op_methode_code
|
|
||||||
int methodCode = statement.columnAsInt64( 0 );
|
|
||||||
if ( methodCode == 9615 ) //ntv2
|
|
||||||
{
|
|
||||||
transformString = "+nadgrids=" + statement.columnAsText( 1 );
|
|
||||||
}
|
|
||||||
else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
|
|
||||||
{
|
|
||||||
transformString += QLatin1String( "+towgs84=" );
|
|
||||||
double p1 = statement.columnAsDouble( 1 );
|
|
||||||
double p2 = statement.columnAsDouble( 2 );
|
|
||||||
double p3 = statement.columnAsDouble( 3 );
|
|
||||||
double p4 = statement.columnAsDouble( 4 );
|
|
||||||
double p5 = statement.columnAsDouble( 5 );
|
|
||||||
double p6 = statement.columnAsDouble( 6 );
|
|
||||||
double p7 = statement.columnAsDouble( 7 );
|
|
||||||
if ( methodCode == 9603 ) //3 parameter transformation
|
|
||||||
{
|
|
||||||
transformString += QStringLiteral( "%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
|
|
||||||
}
|
|
||||||
else //7 parameter transformation
|
|
||||||
{
|
|
||||||
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 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return transformString;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QgsCoordinateTransformPrivate::transformIdFromString( const QString &string )
|
|
||||||
{
|
|
||||||
sqlite3_database_unique_ptr database;
|
|
||||||
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
|
|
||||||
if ( openResult != SQLITE_OK )
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_statement_unique_ptr statement;
|
|
||||||
QString sql = QStringLiteral( "SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7,coord_op_code FROM tbl_datum_transform" );
|
|
||||||
int prepareRes;
|
|
||||||
statement = database.prepare( sql, prepareRes );
|
|
||||||
if ( prepareRes != SQLITE_OK )
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ( statement.step() == SQLITE_ROW )
|
|
||||||
{
|
|
||||||
QString transformString;
|
|
||||||
//coord_op_methode_code
|
|
||||||
int methodCode = statement.columnAsInt64( 0 );
|
|
||||||
if ( methodCode == 9615 ) //ntv2
|
|
||||||
{
|
|
||||||
transformString = "+nadgrids=" + statement.columnAsText( 1 );
|
|
||||||
}
|
|
||||||
else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
|
|
||||||
{
|
|
||||||
transformString += QLatin1String( "+towgs84=" );
|
|
||||||
double p1 = statement.columnAsDouble( 1 );
|
|
||||||
double p2 = statement.columnAsDouble( 2 );
|
|
||||||
double p3 = statement.columnAsDouble( 3 );
|
|
||||||
double p4 = statement.columnAsDouble( 4 );
|
|
||||||
double p5 = statement.columnAsDouble( 5 );
|
|
||||||
double p6 = statement.columnAsDouble( 6 );
|
|
||||||
double p7 = statement.columnAsDouble( 7 );
|
|
||||||
if ( methodCode == 9603 ) //3 parameter transformation
|
|
||||||
{
|
|
||||||
transformString += QStringLiteral( "%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
|
|
||||||
}
|
|
||||||
else //7 parameter transformation
|
|
||||||
{
|
|
||||||
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 ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( transformString.compare( string, Qt::CaseInsensitive ) == 0 )
|
|
||||||
{
|
|
||||||
return statement.columnAsInt64( 8 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QgsCoordinateTransformPrivate::addNullGridShifts( QString &srcProjString, QString &destProjString,
|
void QgsCoordinateTransformPrivate::addNullGridShifts( QString &srcProjString, QString &destProjString,
|
||||||
int sourceDatumTransform, int destinationDatumTransform ) const
|
int sourceDatumTransform, int destinationDatumTransform ) const
|
||||||
{
|
{
|
||||||
|
@ -128,21 +128,6 @@ class QgsCoordinateTransformPrivate : public QSharedData
|
|||||||
QReadWriteLock mProjLock;
|
QReadWriteLock mProjLock;
|
||||||
QMap < uintptr_t, QPair< projPJ, projPJ > > mProjProjections;
|
QMap < uintptr_t, QPair< projPJ, projPJ > > mProjProjections;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the proj transform string corresponding to a
|
|
||||||
* datum transform ID.
|
|
||||||
* \see transformIdFromString()
|
|
||||||
*/
|
|
||||||
static QString datumTransformString( int transformId );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Attempts to match a proj datum transform string to a datum ID.
|
|
||||||
* Returns -1 if datum ID was not found.
|
|
||||||
* \see datumTransformString()
|
|
||||||
* \since QGIS 3.0
|
|
||||||
*/
|
|
||||||
static int transformIdFromString( const QString &string );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! Removes +nadgrids and +towgs84 from proj4 string
|
//! Removes +nadgrids and +towgs84 from proj4 string
|
||||||
|
@ -203,7 +203,7 @@ bool QgsCoordinateTransformContext::readXml( const QDomElement &element, const Q
|
|||||||
//warn if value1 or value2 is non-empty, yet no matching transform was found
|
//warn if value1 or value2 is non-empty, yet no matching transform was found
|
||||||
if ( !value1.isEmpty() )
|
if ( !value1.isEmpty() )
|
||||||
{
|
{
|
||||||
datumId1 = QgsCoordinateTransform::projStringToDatumTransformId( value1 );
|
datumId1 = QgsDatumTransform::projStringToDatumTransformId( value1 );
|
||||||
if ( datumId1 < 0 )
|
if ( datumId1 < 0 )
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
@ -212,7 +212,7 @@ bool QgsCoordinateTransformContext::readXml( const QDomElement &element, const Q
|
|||||||
}
|
}
|
||||||
if ( !value2.isEmpty() )
|
if ( !value2.isEmpty() )
|
||||||
{
|
{
|
||||||
datumId2 = QgsCoordinateTransform::projStringToDatumTransformId( value2 );
|
datumId2 = QgsDatumTransform::projStringToDatumTransformId( value2 );
|
||||||
if ( datumId2 < 0 )
|
if ( datumId2 < 0 )
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
@ -271,8 +271,8 @@ void QgsCoordinateTransformContext::writeXml( QDomElement &element, const QgsRea
|
|||||||
QDomElement transformElem = element.ownerDocument().createElement( QStringLiteral( "srcDest" ) );
|
QDomElement transformElem = element.ownerDocument().createElement( QStringLiteral( "srcDest" ) );
|
||||||
transformElem.setAttribute( QStringLiteral( "source" ), it.key().first );
|
transformElem.setAttribute( QStringLiteral( "source" ), it.key().first );
|
||||||
transformElem.setAttribute( QStringLiteral( "dest" ), it.key().second );
|
transformElem.setAttribute( QStringLiteral( "dest" ), it.key().second );
|
||||||
transformElem.setAttribute( QStringLiteral( "sourceTransform" ), it.value().sourceTransformId < 0 ? QString() : QgsCoordinateTransform::datumTransformToProj( it.value().sourceTransformId ) );
|
transformElem.setAttribute( QStringLiteral( "sourceTransform" ), it.value().sourceTransformId < 0 ? QString() : QgsDatumTransform::datumTransformToProj( it.value().sourceTransformId ) );
|
||||||
transformElem.setAttribute( QStringLiteral( "destTransform" ), it.value().destinationTransformId < 0 ? QString() : QgsCoordinateTransform::datumTransformToProj( it.value().destinationTransformId ) );
|
transformElem.setAttribute( QStringLiteral( "destTransform" ), it.value().destinationTransformId < 0 ? QString() : QgsDatumTransform::datumTransformToProj( it.value().destinationTransformId ) );
|
||||||
contextElem.appendChild( transformElem );
|
contextElem.appendChild( transformElem );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ void QgsCoordinateTransformContext::readSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QString proj = settings.value( *pkeyIt ).toString();
|
QString proj = settings.value( *pkeyIt ).toString();
|
||||||
int datumId = QgsCoordinateTransform::projStringToDatumTransformId( proj );
|
int datumId = QgsDatumTransform::projStringToDatumTransformId( proj );
|
||||||
if ( pkeyIt->contains( QLatin1String( "srcTransform" ) ) )
|
if ( pkeyIt->contains( QLatin1String( "srcTransform" ) ) )
|
||||||
{
|
{
|
||||||
transforms[ qMakePair( srcAuthId, destAuthId )].first = datumId;
|
transforms[ qMakePair( srcAuthId, destAuthId )].first = datumId;
|
||||||
@ -378,11 +378,11 @@ void QgsCoordinateTransformContext::writeSettings()
|
|||||||
int sourceDatumTransform = transformIt.value().sourceTransformId;
|
int sourceDatumTransform = transformIt.value().sourceTransformId;
|
||||||
QString sourceDatumProj;
|
QString sourceDatumProj;
|
||||||
if ( sourceDatumTransform >= 0 )
|
if ( sourceDatumTransform >= 0 )
|
||||||
sourceDatumProj = QgsCoordinateTransform::datumTransformToProj( sourceDatumTransform );
|
sourceDatumProj = QgsDatumTransform::datumTransformToProj( sourceDatumTransform );
|
||||||
int destinationDatumTransform = transformIt.value().destinationTransformId;
|
int destinationDatumTransform = transformIt.value().destinationTransformId;
|
||||||
QString destinationDatumProj;
|
QString destinationDatumProj;
|
||||||
if ( destinationDatumTransform >= 0 )
|
if ( destinationDatumTransform >= 0 )
|
||||||
destinationDatumProj = QgsCoordinateTransform::datumTransformToProj( destinationDatumTransform );
|
destinationDatumProj = QgsDatumTransform::datumTransformToProj( destinationDatumTransform );
|
||||||
|
|
||||||
settings.setValue( srcAuthId + "//" + destAuthId + "_srcTransform", sourceDatumProj );
|
settings.setValue( srcAuthId + "//" + destAuthId + "_srcTransform", sourceDatumProj );
|
||||||
settings.setValue( srcAuthId + "//" + destAuthId + "_destTransform", destinationDatumProj );
|
settings.setValue( srcAuthId + "//" + destAuthId + "_destTransform", destinationDatumProj );
|
||||||
|
@ -53,6 +53,9 @@ class QDomElement;
|
|||||||
*
|
*
|
||||||
* \note QgsCoordinateTransformContext objects are implicitly shared.
|
* \note QgsCoordinateTransformContext objects are implicitly shared.
|
||||||
*
|
*
|
||||||
|
* \see QgsDatumTransform
|
||||||
|
* \see QgsCoordinateTransform
|
||||||
|
*
|
||||||
* \since QGIS 3.0
|
* \since QGIS 3.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
263
src/core/qgsdatumtransform.cpp
Normal file
263
src/core/qgsdatumtransform.cpp
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
qgsdatumtransform.cpp
|
||||||
|
------------------------
|
||||||
|
begin : Dec 2017
|
||||||
|
copyright : (C) 2017 Nyall Dawson
|
||||||
|
email : nyall dot dawson at gmail dot com
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
***************************************************************************/
|
||||||
|
#include "qgsdatumtransform.h"
|
||||||
|
#include "qgscoordinatereferencesystem.h"
|
||||||
|
#include "qgsapplication.h"
|
||||||
|
#include "qgssqliteutils.h"
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
QList< QgsDatumTransform::TransformPair > QgsDatumTransform::datumTransformations( const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS )
|
||||||
|
{
|
||||||
|
QList< QgsDatumTransform::TransformPair > transformations;
|
||||||
|
|
||||||
|
QString srcGeoId = srcCRS.geographicCrsAuthId();
|
||||||
|
QString destGeoId = destCRS.geographicCrsAuthId();
|
||||||
|
|
||||||
|
if ( srcGeoId.isEmpty() || destGeoId.isEmpty() )
|
||||||
|
{
|
||||||
|
return transformations;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList srcSplit = srcGeoId.split( ':' );
|
||||||
|
QStringList destSplit = destGeoId.split( ':' );
|
||||||
|
|
||||||
|
if ( srcSplit.size() < 2 || destSplit.size() < 2 )
|
||||||
|
{
|
||||||
|
return transformations;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srcAuthCode = srcSplit.at( 1 ).toInt();
|
||||||
|
int destAuthCode = destSplit.at( 1 ).toInt();
|
||||||
|
|
||||||
|
if ( srcAuthCode == destAuthCode )
|
||||||
|
{
|
||||||
|
return transformations; //crs have the same datum
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> directTransforms;
|
||||||
|
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 ),
|
||||||
|
directTransforms );
|
||||||
|
QList<int> reverseDirectTransforms;
|
||||||
|
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 ),
|
||||||
|
reverseDirectTransforms );
|
||||||
|
QList<int> srcToWgs84;
|
||||||
|
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 ),
|
||||||
|
srcToWgs84 );
|
||||||
|
QList<int> destToWgs84;
|
||||||
|
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 ),
|
||||||
|
destToWgs84 );
|
||||||
|
|
||||||
|
//add direct datum transformations
|
||||||
|
for ( int transform : qgis::as_const( directTransforms ) )
|
||||||
|
{
|
||||||
|
transformations.push_back( QgsDatumTransform::TransformPair( transform, -1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//add direct datum transformations
|
||||||
|
for ( int transform : qgis::as_const( directTransforms ) )
|
||||||
|
{
|
||||||
|
transformations.push_back( QgsDatumTransform::TransformPair( -1, transform ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int srcTransform : qgis::as_const( srcToWgs84 ) )
|
||||||
|
{
|
||||||
|
for ( int destTransform : qgis::as_const( destToWgs84 ) )
|
||||||
|
{
|
||||||
|
transformations.push_back( QgsDatumTransform::TransformPair( srcTransform, destTransform ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return transformations;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QgsDatumTransform::searchDatumTransform( const QString &sql, QList< int > &transforms )
|
||||||
|
{
|
||||||
|
sqlite3_database_unique_ptr database;
|
||||||
|
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
|
||||||
|
if ( openResult != SQLITE_OK )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_statement_unique_ptr statement;
|
||||||
|
int prepareRes;
|
||||||
|
statement = database.prepare( sql, prepareRes );
|
||||||
|
if ( prepareRes != SQLITE_OK )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString cOpCode;
|
||||||
|
while ( statement.step() == SQLITE_ROW )
|
||||||
|
{
|
||||||
|
cOpCode = statement.columnAsText( 0 );
|
||||||
|
transforms.push_back( cOpCode.toInt() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QgsDatumTransform::datumTransformToProj( int datumTransform )
|
||||||
|
{
|
||||||
|
QString transformString;
|
||||||
|
|
||||||
|
sqlite3_database_unique_ptr database;
|
||||||
|
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
|
||||||
|
if ( openResult != SQLITE_OK )
|
||||||
|
{
|
||||||
|
return transformString;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_statement_unique_ptr statement;
|
||||||
|
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 );
|
||||||
|
int prepareRes;
|
||||||
|
statement = database.prepare( sql, prepareRes );
|
||||||
|
if ( prepareRes != SQLITE_OK )
|
||||||
|
{
|
||||||
|
return transformString;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( statement.step() == SQLITE_ROW )
|
||||||
|
{
|
||||||
|
//coord_op_methode_code
|
||||||
|
int methodCode = statement.columnAsInt64( 0 );
|
||||||
|
if ( methodCode == 9615 ) //ntv2
|
||||||
|
{
|
||||||
|
transformString = "+nadgrids=" + statement.columnAsText( 1 );
|
||||||
|
}
|
||||||
|
else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
|
||||||
|
{
|
||||||
|
transformString += QLatin1String( "+towgs84=" );
|
||||||
|
double p1 = statement.columnAsDouble( 1 );
|
||||||
|
double p2 = statement.columnAsDouble( 2 );
|
||||||
|
double p3 = statement.columnAsDouble( 3 );
|
||||||
|
double p4 = statement.columnAsDouble( 4 );
|
||||||
|
double p5 = statement.columnAsDouble( 5 );
|
||||||
|
double p6 = statement.columnAsDouble( 6 );
|
||||||
|
double p7 = statement.columnAsDouble( 7 );
|
||||||
|
if ( methodCode == 9603 ) //3 parameter transformation
|
||||||
|
{
|
||||||
|
transformString += QStringLiteral( "%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
|
||||||
|
}
|
||||||
|
else //7 parameter transformation
|
||||||
|
{
|
||||||
|
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 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return transformString;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QgsDatumTransform::projStringToDatumTransformId( const QString &string )
|
||||||
|
{
|
||||||
|
sqlite3_database_unique_ptr database;
|
||||||
|
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
|
||||||
|
if ( openResult != SQLITE_OK )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_statement_unique_ptr statement;
|
||||||
|
QString sql = QStringLiteral( "SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7,coord_op_code FROM tbl_datum_transform" );
|
||||||
|
int prepareRes;
|
||||||
|
statement = database.prepare( sql, prepareRes );
|
||||||
|
if ( prepareRes != SQLITE_OK )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ( statement.step() == SQLITE_ROW )
|
||||||
|
{
|
||||||
|
QString transformString;
|
||||||
|
//coord_op_methode_code
|
||||||
|
int methodCode = statement.columnAsInt64( 0 );
|
||||||
|
if ( methodCode == 9615 ) //ntv2
|
||||||
|
{
|
||||||
|
transformString = "+nadgrids=" + statement.columnAsText( 1 );
|
||||||
|
}
|
||||||
|
else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
|
||||||
|
{
|
||||||
|
transformString += QLatin1String( "+towgs84=" );
|
||||||
|
double p1 = statement.columnAsDouble( 1 );
|
||||||
|
double p2 = statement.columnAsDouble( 2 );
|
||||||
|
double p3 = statement.columnAsDouble( 3 );
|
||||||
|
double p4 = statement.columnAsDouble( 4 );
|
||||||
|
double p5 = statement.columnAsDouble( 5 );
|
||||||
|
double p6 = statement.columnAsDouble( 6 );
|
||||||
|
double p7 = statement.columnAsDouble( 7 );
|
||||||
|
if ( methodCode == 9603 ) //3 parameter transformation
|
||||||
|
{
|
||||||
|
transformString += QStringLiteral( "%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
|
||||||
|
}
|
||||||
|
else //7 parameter transformation
|
||||||
|
{
|
||||||
|
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 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( transformString.compare( string, Qt::CaseInsensitive ) == 0 )
|
||||||
|
{
|
||||||
|
return statement.columnAsInt64( 8 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QgsDatumTransform::TransformInfo QgsDatumTransform::datumTransformInfo( int datumTransform )
|
||||||
|
{
|
||||||
|
QgsDatumTransform::TransformInfo info;
|
||||||
|
|
||||||
|
sqlite3_database_unique_ptr database;
|
||||||
|
int openResult = database.open_v2( QgsApplication::srsDatabaseFilePath(), SQLITE_OPEN_READONLY, nullptr );
|
||||||
|
if ( openResult != SQLITE_OK )
|
||||||
|
{
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_statement_unique_ptr statement;
|
||||||
|
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 );
|
||||||
|
int prepareRes;
|
||||||
|
statement = database.prepare( sql, prepareRes );
|
||||||
|
if ( prepareRes != SQLITE_OK )
|
||||||
|
{
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srcCrsId, destCrsId;
|
||||||
|
if ( statement.step() != SQLITE_ROW )
|
||||||
|
{
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.datumTransformId = datumTransform;
|
||||||
|
info.epsgCode = statement.columnAsInt64( 0 );
|
||||||
|
srcCrsId = statement.columnAsInt64( 1 );
|
||||||
|
destCrsId = statement.columnAsInt64( 2 );
|
||||||
|
info.remarks = statement.columnAsText( 3 );
|
||||||
|
info.scope = statement.columnAsText( 4 );
|
||||||
|
info.preferred = statement.columnAsInt64( 5 ) != 0;
|
||||||
|
info.deprecated = statement.columnAsInt64( 6 ) != 0;
|
||||||
|
|
||||||
|
QgsCoordinateReferenceSystem srcCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( srcCrsId ) );
|
||||||
|
info.sourceCrsDescription = srcCrs.description();
|
||||||
|
info.sourceCrsAuthId = srcCrs.authid();
|
||||||
|
QgsCoordinateReferenceSystem destCrs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( QStringLiteral( "EPSG:%1" ).arg( destCrsId ) );
|
||||||
|
info.destinationCrsDescription = destCrs.description();
|
||||||
|
info.destinationCrsAuthId = destCrs.authid();
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
@ -20,9 +20,16 @@
|
|||||||
#include "qgis_core.h"
|
#include "qgis_core.h"
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
|
class QgsCoordinateReferenceSystem;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains methods and classes relating the datum transformations.
|
* Contains methods and classes relating the datum transformations.
|
||||||
* \ingroup core
|
* \ingroup core
|
||||||
|
*
|
||||||
|
* \see QgsCoordinateTransformContext
|
||||||
|
* \see QgsCoordinateTransform
|
||||||
|
*
|
||||||
* \since QGIS 3.0
|
* \since QGIS 3.0
|
||||||
*/
|
*/
|
||||||
class CORE_EXPORT QgsDatumTransform
|
class CORE_EXPORT QgsDatumTransform
|
||||||
@ -107,6 +114,43 @@ class CORE_EXPORT QgsDatumTransform
|
|||||||
bool deprecated = false;
|
bool deprecated = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of datum transformations which are available for the given \a source and \a destination CRS.
|
||||||
|
* \see datumTransformToProj()
|
||||||
|
* \see datumTransformInfo()
|
||||||
|
*/
|
||||||
|
static QList< QgsDatumTransform::TransformPair > datumTransformations( const QgsCoordinateReferenceSystem &source, const QgsCoordinateReferenceSystem &destination );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a proj string representing the specified \a datumTransformId datum transform ID.
|
||||||
|
* \see datumTransformations()
|
||||||
|
* \see datumTransformInfo()
|
||||||
|
* \see projStringToDatumTransformId()
|
||||||
|
*/
|
||||||
|
static QString datumTransformToProj( int datumTransformId );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the datum transform ID corresponding to a specified proj \a string.
|
||||||
|
* Returns -1 if matching datum ID was not found.
|
||||||
|
* \see datumTransformToProj()
|
||||||
|
*/
|
||||||
|
static int projStringToDatumTransformId( const QString &string );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns detailed information about the specified \a datumTransformId.
|
||||||
|
* If \a datumTransformId was not a valid transform ID, a TransformInfo with TransformInfo::datumTransformId of
|
||||||
|
* -1 will be returned.
|
||||||
|
* \see datumTransformations()
|
||||||
|
* \see datumTransformToProj()
|
||||||
|
*/
|
||||||
|
static QgsDatumTransform::TransformInfo datumTransformInfo( int datumTransformId );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static void searchDatumTransform( const QString &sql, QList< int > &transforms );
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QGSDATUMTRANSFORM_H
|
#endif // QGSDATUMTRANSFORM_H
|
||||||
|
@ -46,7 +46,7 @@ QgsDatumTransformDialog::QgsDatumTransformDialog( const QgsCoordinateReferenceSy
|
|||||||
//get list of datum transforms
|
//get list of datum transforms
|
||||||
mSourceCrs = sourceCrs;
|
mSourceCrs = sourceCrs;
|
||||||
mDestinationCrs = destinationCrs;
|
mDestinationCrs = destinationCrs;
|
||||||
mDatumTransforms = QgsCoordinateTransform::datumTransformations( sourceCrs, destinationCrs );
|
mDatumTransforms = QgsDatumTransform::datumTransformations( sourceCrs, destinationCrs );
|
||||||
|
|
||||||
QApplication::setOverrideCursor( Qt::ArrowCursor );
|
QApplication::setOverrideCursor( Qt::ArrowCursor );
|
||||||
|
|
||||||
@ -84,10 +84,10 @@ void QgsDatumTransformDialog::load( const QPair<int, int> &selectedDatumTransfor
|
|||||||
if ( nr == -1 )
|
if ( nr == -1 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
item->setText( i, QgsCoordinateTransform::datumTransformToProj( nr ) );
|
item->setText( i, QgsDatumTransform::datumTransformToProj( nr ) );
|
||||||
|
|
||||||
//Describe datums in a tooltip
|
//Describe datums in a tooltip
|
||||||
QgsDatumTransform::TransformInfo info = QgsCoordinateTransform::datumTransformInfo( nr );
|
QgsDatumTransform::TransformInfo info = QgsDatumTransform::datumTransformInfo( nr );
|
||||||
if ( info.datumTransformId == -1 )
|
if ( info.datumTransformId == -1 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -266,7 +266,7 @@ void QgsDatumTransformDialog::mDatumTransformTreeWidget_currentItemChanged( QTre
|
|||||||
void QgsDatumTransformDialog::setSourceCrs( const QgsCoordinateReferenceSystem &sourceCrs )
|
void QgsDatumTransformDialog::setSourceCrs( const QgsCoordinateReferenceSystem &sourceCrs )
|
||||||
{
|
{
|
||||||
mSourceCrs = sourceCrs;
|
mSourceCrs = sourceCrs;
|
||||||
mDatumTransforms = QgsCoordinateTransform::datumTransformations( mSourceCrs, mDestinationCrs );
|
mDatumTransforms = QgsDatumTransform::datumTransformations( mSourceCrs, mDestinationCrs );
|
||||||
load();
|
load();
|
||||||
setOKButtonEnabled();
|
setOKButtonEnabled();
|
||||||
}
|
}
|
||||||
@ -274,7 +274,7 @@ void QgsDatumTransformDialog::setSourceCrs( const QgsCoordinateReferenceSystem &
|
|||||||
void QgsDatumTransformDialog::setDestinationCrs( const QgsCoordinateReferenceSystem &destinationCrs )
|
void QgsDatumTransformDialog::setDestinationCrs( const QgsCoordinateReferenceSystem &destinationCrs )
|
||||||
{
|
{
|
||||||
mDestinationCrs = destinationCrs;
|
mDestinationCrs = destinationCrs;
|
||||||
mDatumTransforms = QgsCoordinateTransform::datumTransformations( mSourceCrs, mDestinationCrs );
|
mDatumTransforms = QgsDatumTransform::datumTransformations( mSourceCrs, mDestinationCrs );
|
||||||
load();
|
load();
|
||||||
setOKButtonEnabled();
|
setOKButtonEnabled();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ from qgis.core import (QgsRectangle,
|
|||||||
QgsCoordinateReferenceSystem,
|
QgsCoordinateReferenceSystem,
|
||||||
QgsCoordinateTransform,
|
QgsCoordinateTransform,
|
||||||
QgsCoordinateTransformContext,
|
QgsCoordinateTransformContext,
|
||||||
|
QgsDatumTransform,
|
||||||
QgsProject)
|
QgsProject)
|
||||||
from qgis.testing import start_app, unittest
|
from qgis.testing import start_app, unittest
|
||||||
|
|
||||||
@ -209,27 +210,27 @@ class TestQgsCoordinateTransform(unittest.TestCase):
|
|||||||
|
|
||||||
def testTransformInfo(self):
|
def testTransformInfo(self):
|
||||||
# hopefully this transform is available on all platforms!
|
# hopefully this transform is available on all platforms!
|
||||||
transforms = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4613), QgsCoordinateReferenceSystem(4326))
|
transforms = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4613), QgsCoordinateReferenceSystem(4326))
|
||||||
self.assertTrue(len(transforms) > 0)
|
self.assertTrue(len(transforms) > 0)
|
||||||
self.assertIn('+towgs84=-403,684,41', [QgsCoordinateTransform.datumTransformToProj(t.sourceTransformId) for t in transforms])
|
self.assertIn('+towgs84=-403,684,41', [QgsDatumTransform.datumTransformToProj(t.sourceTransformId) for t in transforms])
|
||||||
self.assertIn('+towgs84=-403,684,41', [QgsCoordinateTransform.datumTransformToProj(t.destinationTransformId) for t in transforms])
|
self.assertIn('+towgs84=-403,684,41', [QgsDatumTransform.datumTransformToProj(t.destinationTransformId) for t in transforms])
|
||||||
self.assertIn('EPSG:4613', [QgsCoordinateTransform.datumTransformInfo(t.destinationTransformId).sourceCrsAuthId for t in
|
self.assertIn('EPSG:4613', [QgsDatumTransform.datumTransformInfo(t.destinationTransformId).sourceCrsAuthId for t in
|
||||||
transforms])
|
transforms])
|
||||||
self.assertIn('EPSG:4326', [QgsCoordinateTransform.datumTransformInfo(t.destinationTransformId).destinationCrsAuthId for t in
|
self.assertIn('EPSG:4326', [QgsDatumTransform.datumTransformInfo(t.destinationTransformId).destinationCrsAuthId for t in
|
||||||
transforms])
|
transforms])
|
||||||
|
|
||||||
def testStringToTransformId(self):
|
def testStringToTransformId(self):
|
||||||
"""
|
"""
|
||||||
Test converting proj strings to corresponding datum IDs
|
Test converting proj strings to corresponding datum IDs
|
||||||
"""
|
"""
|
||||||
self.assertEqual(QgsCoordinateTransform.projStringToDatumTransformId(''), -1)
|
self.assertEqual(QgsDatumTransform.projStringToDatumTransformId(''), -1)
|
||||||
self.assertEqual(QgsCoordinateTransform.projStringToDatumTransformId('not'), -1)
|
self.assertEqual(QgsDatumTransform.projStringToDatumTransformId('not'), -1)
|
||||||
test_string = '+towgs84=-403,684,41'
|
test_string = '+towgs84=-403,684,41'
|
||||||
id = QgsCoordinateTransform.projStringToDatumTransformId(test_string)
|
id = QgsDatumTransform.projStringToDatumTransformId(test_string)
|
||||||
self.assertNotEqual(id, -1)
|
self.assertNotEqual(id, -1)
|
||||||
string = QgsCoordinateTransform.datumTransformToProj(id)
|
string = QgsDatumTransform.datumTransformToProj(id)
|
||||||
self.assertEqual(string, test_string)
|
self.assertEqual(string, test_string)
|
||||||
self.assertEqual(QgsCoordinateTransform.projStringToDatumTransformId(test_string.upper()), id)
|
self.assertEqual(QgsDatumTransform.projStringToDatumTransformId(test_string.upper()), id)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -302,15 +302,15 @@ class TestQgsCoordinateTransformContext(unittest.TestCase):
|
|||||||
# setup a context
|
# setup a context
|
||||||
context = QgsCoordinateTransformContext()
|
context = QgsCoordinateTransformContext()
|
||||||
|
|
||||||
source_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
|
source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
|
||||||
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
|
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
|
||||||
dest_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
|
dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
|
||||||
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
|
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
|
||||||
|
|
||||||
source_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
|
source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
|
||||||
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
|
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
|
||||||
dest_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
|
dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
|
||||||
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
|
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
|
||||||
|
|
||||||
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4204),
|
self.assertTrue(context.addSourceDestinationDatumTransform(QgsCoordinateReferenceSystem(4204),
|
||||||
QgsCoordinateReferenceSystem(4326), source_id_1, dest_id_1))
|
QgsCoordinateReferenceSystem(4326), source_id_1, dest_id_1))
|
||||||
@ -373,15 +373,15 @@ class TestQgsCoordinateTransformContext(unittest.TestCase):
|
|||||||
context = QgsCoordinateTransformContext()
|
context = QgsCoordinateTransformContext()
|
||||||
context.readSettings()
|
context.readSettings()
|
||||||
|
|
||||||
source_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
|
source_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
|
||||||
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
|
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
|
||||||
dest_id_1 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
|
dest_id_1 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4204),
|
||||||
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
|
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
|
||||||
|
|
||||||
source_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
|
source_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
|
||||||
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
|
QgsCoordinateReferenceSystem(4326))[0].sourceTransformId
|
||||||
dest_id_2 = QgsCoordinateTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
|
dest_id_2 = QgsDatumTransform.datumTransformations(QgsCoordinateReferenceSystem(4205),
|
||||||
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
|
QgsCoordinateReferenceSystem(4326))[0].destinationTransformId
|
||||||
|
|
||||||
# should be empty
|
# should be empty
|
||||||
self.assertEqual(context.sourceDestinationDatumTransforms(), {})
|
self.assertEqual(context.sourceDestinationDatumTransforms(), {})
|
||||||
|
Loading…
x
Reference in New Issue
Block a user