28   QList< QgsDatumTransform::TransformDetails > res;
 
   34   PJ_OPERATION_FACTORY_CONTEXT *operationContext = proj_create_operation_factory_context( pjContext, 
nullptr );
 
   37   proj_operation_factory_context_set_grid_availability_use( pjContext, operationContext, PROJ_GRID_AVAILABILITY_IGNORED );
 
   40   proj_operation_factory_context_set_spatial_criterion( pjContext, operationContext,  PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION );
 
   42   if ( includeSuperseded )
 
   43     proj_operation_factory_context_set_discard_superseded( pjContext, operationContext, 
false );
 
   45   if ( PJ_OBJ_LIST *ops = proj_create_operations( pjContext, source.
projObject(), destination.
projObject(), operationContext ) )
 
   47     int count = proj_list_get_count( ops );
 
   48     for ( 
int i = 0; i < count; ++i )
 
   55       if ( !details.
proj.isEmpty() )
 
   56         res.push_back( details );
 
   59     proj_list_destroy( ops );
 
   61   proj_operation_factory_context_destroy( operationContext );
 
   67   QList< QgsDatumTransform::TransformPair > transformations;
 
   72   if ( srcGeoId.isEmpty() || destGeoId.isEmpty() )
 
   74     return transformations;
 
   77   QStringList srcSplit = srcGeoId.split( 
':' );
 
   78   QStringList destSplit = destGeoId.split( 
':' );
 
   80   if ( srcSplit.size() < 2 || destSplit.size() < 2 )
 
   82     return transformations;
 
   85   int srcAuthCode = srcSplit.at( 1 ).toInt();
 
   86   int destAuthCode = destSplit.at( 1 ).toInt();
 
   88   if ( srcAuthCode == destAuthCode )
 
   90     return transformations; 
 
   93   QList<int> directTransforms;
 
   94   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 ),
 
   96   QList<int> reverseDirectTransforms;
 
   97   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 ),
 
   98                         reverseDirectTransforms );
 
   99   QList<int> srcToWgs84;
 
  100   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 ),
 
  102   QList<int> destToWgs84;
 
  103   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 ),
 
  107   for ( 
int transform : std::as_const( directTransforms ) )
 
  113   for ( 
int transform : std::as_const( reverseDirectTransforms ) )
 
  118   for ( 
int srcTransform : std::as_const( srcToWgs84 ) )
 
  120     for ( 
int destTransform : std::as_const( destToWgs84 ) )
 
  126   return transformations;
 
  129 void QgsDatumTransform::searchDatumTransform( 
const QString &sql, QList< int > &transforms )
 
  133   if ( openResult != SQLITE_OK )
 
  140   statement = database.
prepare( sql, prepareRes );
 
  141   if ( prepareRes != SQLITE_OK )
 
  147   while ( statement.
step() == SQLITE_ROW )
 
  150     transforms.push_back( cOpCode.toInt() );
 
  156   QString transformString;
 
  160   if ( openResult != SQLITE_OK )
 
  162     return transformString;
 
  166   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 );
 
  168   statement = database.
prepare( sql, prepareRes );
 
  169   if ( prepareRes != SQLITE_OK )
 
  171     return transformString;
 
  174   if ( statement.
step() == SQLITE_ROW )
 
  178     if ( methodCode == 9615 ) 
 
  180       transformString = 
"+nadgrids=" + statement.
columnAsText( 1 );
 
  182     else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
 
  184       transformString += QLatin1String( 
"+towgs84=" );
 
  192       if ( methodCode == 9603 ) 
 
  194         transformString += QStringLiteral( 
"%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
 
  198         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 ) );
 
  203   return transformString;
 
  210   if ( openResult != SQLITE_OK )
 
  216   QString sql = QStringLiteral( 
"SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7,coord_op_code FROM tbl_datum_transform" );
 
  218   statement = database.
prepare( sql, prepareRes );
 
  219   if ( prepareRes != SQLITE_OK )
 
  224   while ( statement.
step() == SQLITE_ROW )
 
  226     QString transformString;
 
  229     if ( methodCode == 9615 ) 
 
  231       transformString = 
"+nadgrids=" + statement.
columnAsText( 1 );
 
  233     else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
 
  235       transformString += QLatin1String( 
"+towgs84=" );
 
  243       if ( methodCode == 9603 ) 
 
  245         transformString += QStringLiteral( 
"%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
 
  249         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 ) );
 
  253     if ( transformString.compare( 
string, Qt::CaseInsensitive ) == 0 )
 
  268   if ( openResult != SQLITE_OK )
 
  274   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 );
 
  276   statement = database.
prepare( sql, prepareRes );
 
  277   if ( prepareRes != SQLITE_OK )
 
  282   int srcCrsId, destCrsId;
 
  283   if ( statement.
step() != SQLITE_ROW )
 
  316     details.
proj = QString( proj_as_proj_string( pjContext, normalized.get(), PJ_PROJ_5, 
nullptr ) );
 
  318   if ( details.
proj.isEmpty() )
 
  319     details.
proj = QString( proj_as_proj_string( pjContext, op, PJ_PROJ_5, 
nullptr ) );
 
  321   if ( details.
proj.isEmpty() )
 
  324   details.
name = QString( proj_get_name( op ) );
 
  325   details.
accuracy = proj_coordoperation_get_accuracy( pjContext, op );
 
  326   details.
isAvailable = proj_coordoperation_is_instantiable( pjContext, op );
 
  328   details.
authority = QString( proj_get_id_auth_name( op, 0 ) );
 
  329   details.
code = QString( proj_get_id_code( op, 0 ) );
 
  331   const char *areaOfUseName = 
nullptr;
 
  336   if ( proj_get_area_of_use( pjContext, op, &westLon, &southLat, &eastLon, &northLat, &areaOfUseName ) )
 
  338     details.
areaOfUse = QString( areaOfUseName );
 
  346   details.
remarks = QString( proj_get_remarks( op ) );
 
  347   details.
scope = QString( proj_get_scope( op ) );
 
  349   for ( 
int j = 0; j < proj_coordoperation_get_grid_used_count( pjContext, op ); ++j )
 
  351     const char *shortName = 
nullptr;
 
  352     const char *fullName = 
nullptr;
 
  353     const char *packageName = 
nullptr;
 
  354     const char *url = 
nullptr;
 
  355     int directDownload = 0;
 
  358     proj_coordoperation_get_grid_used( pjContext, op, j, &shortName, &fullName, &packageName, &url, &directDownload, &openLicense, &isAvailable );
 
  360     gridDetails.
shortName = QString( shortName );
 
  361     gridDetails.
fullName = QString( fullName );
 
  363     gridDetails.
url = QString( url );
 
  368     details.
grids.append( gridDetails );
 
  371   if ( proj_get_type( op ) == PJ_TYPE_CONCATENATED_OPERATION )
 
  373     for ( 
int j = 0; j < proj_concatoperation_get_step_count( pjContext, op ); ++j )
 
  379         singleOpDetails.
remarks = QString( proj_get_remarks( step.get() ) );
 
  380         singleOpDetails.
scope = QString( proj_get_scope( step.get() ) );
 
  381         singleOpDetails.
authority = QString( proj_get_id_auth_name( step.get(), 0 ) );
 
  382         singleOpDetails.
code = QString( proj_get_id_code( step.get(), 0 ) );
 
  384         const char *areaOfUseName = 
nullptr;
 
  385         if ( proj_get_area_of_use( pjContext, step.get(), 
nullptr, 
nullptr, 
nullptr, 
nullptr, &areaOfUseName ) )
 
  387           singleOpDetails.
areaOfUse = QString( areaOfUseName );
 
  396     singleOpDetails.
remarks = QString( proj_get_remarks( op ) );
 
  397     singleOpDetails.
scope = QString( proj_get_scope( op ) );
 
  398     singleOpDetails.
authority = QString( proj_get_id_auth_name( op, 0 ) );
 
  399     singleOpDetails.
code = QString( proj_get_id_code( op, 0 ) );
 
  401     const char *areaOfUseName = 
nullptr;
 
  402     if ( proj_get_area_of_use( pjContext, op, 
nullptr, 
nullptr, 
nullptr, 
nullptr, &areaOfUseName ) )
 
  404       singleOpDetails.
areaOfUse = QString( areaOfUseName );
 
static QString srsDatabaseFilePath()
Returns the path to the srs.db file.
This class represents a coordinate reference system (CRS).
static QgsCoordinateReferenceSystem fromOgcWmsCrs(const QString &ogcCrs)
Creates a CRS from a given OGC WMS-format Coordinate Reference System string.
QString description() const
Returns the descriptive name of the CRS, e.g., "WGS 84" or "GDA 94 / Vicgrid94".
PJ * projObject() const
Returns the underlying PROJ PJ object corresponding to the CRS, or nullptr if the CRS is invalid.
QString authid() const
Returns the authority identifier for the CRS.
QString geographicCrsAuthId() const
Returns auth id of related geographic CRS.
static PJ_CONTEXT * get()
Returns a thread local instance of a proj context, safe for use in the current thread.
std::unique_ptr< PJ, ProjPJDeleter > proj_pj_unique_ptr
Scoped Proj PJ object.
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Unique pointer for sqlite3 databases, which automatically closes the database when the pointer goes o...
sqlite3_statement_unique_ptr prepare(const QString &sql, int &resultCode) const
Prepares a sql statement, returning the result.
int open_v2(const QString &path, int flags, const char *zVfs)
Opens the database at the specified file path.
Unique pointer for sqlite3 prepared statements, which automatically finalizes the statement when the ...
QString columnAsText(int column) const
Returns the column value from the current statement row as a string.
double columnAsDouble(int column) const
Gets column value from the current statement row as a double.
int step()
Steps to the next record in the statement, returning the sqlite3 result code.
qlonglong columnAsInt64(int column) const
Gets column value from the current statement row as a long long integer (64 bits).
struct projCtx_t PJ_CONTEXT