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;
 
 
  129void 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.
 
PJ * projObject() const
Returns the underlying PROJ PJ object corresponding to the CRS, or nullptr if the CRS is invalid.
 
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)
Set the minimum y value.
 
void setXMinimum(double x)
Set the minimum x value.
 
void setYMaximum(double y)
Set the maximum y value.
 
void setXMaximum(double x)
Set the maximum x 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