23 #if PROJ_VERSION_MAJOR>=6 
   30   QList< QgsDatumTransform::TransformDetails > res;
 
   31 #if PROJ_VERSION_MAJOR<6 
   33   Q_UNUSED( destination )
 
   34   Q_UNUSED( includeSuperseded )
 
   36   if ( !source.projObject() || !destination.projObject() )
 
   41   PJ_OPERATION_FACTORY_CONTEXT *operationContext = proj_create_operation_factory_context( pjContext, 
nullptr );
 
   44   proj_operation_factory_context_set_grid_availability_use( pjContext, operationContext, PROJ_GRID_AVAILABILITY_IGNORED );
 
   47   proj_operation_factory_context_set_spatial_criterion( pjContext, operationContext,  PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION );
 
   49   if ( includeSuperseded )
 
   50     proj_operation_factory_context_set_discard_superseded( pjContext, operationContext, 
false );
 
   52   if ( PJ_OBJ_LIST *ops = proj_create_operations( pjContext, source.projObject(), destination.projObject(), operationContext ) )
 
   54     int count = proj_list_get_count( ops );
 
   55     for ( 
int i = 0; i < count; ++i )
 
   57       QgsProjUtils::proj_pj_unique_ptr op( proj_list_get( pjContext, ops, i ) );
 
   62       if ( !details.
proj.isEmpty() )
 
   63         res.push_back( details );
 
   66     proj_list_destroy( ops );
 
   68   proj_operation_factory_context_destroy( operationContext );
 
   75   QList< QgsDatumTransform::TransformPair > transformations;
 
   80   if ( srcGeoId.isEmpty() || destGeoId.isEmpty() )
 
   82     return transformations;
 
   85   QStringList srcSplit = srcGeoId.split( 
':' );
 
   86   QStringList destSplit = destGeoId.split( 
':' );
 
   88   if ( srcSplit.size() < 2 || destSplit.size() < 2 )
 
   90     return transformations;
 
   93   int srcAuthCode = srcSplit.at( 1 ).toInt();
 
   94   int destAuthCode = destSplit.at( 1 ).toInt();
 
   96   if ( srcAuthCode == destAuthCode )
 
   98     return transformations; 
 
  101   QList<int> directTransforms;
 
  102   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 ),
 
  104   QList<int> reverseDirectTransforms;
 
  105   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 ),
 
  106                         reverseDirectTransforms );
 
  107   QList<int> srcToWgs84;
 
  108   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 ),
 
  110   QList<int> destToWgs84;
 
  111   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 ),
 
  115   for ( 
int transform : qgis::as_const( directTransforms ) )
 
  121   for ( 
int transform : qgis::as_const( reverseDirectTransforms ) )
 
  126   for ( 
int srcTransform : qgis::as_const( srcToWgs84 ) )
 
  128     for ( 
int destTransform : qgis::as_const( destToWgs84 ) )
 
  134   return transformations;
 
  137 void QgsDatumTransform::searchDatumTransform( 
const QString &sql, QList< int > &transforms )
 
  141   if ( openResult != SQLITE_OK )
 
  148   statement = database.
prepare( sql, prepareRes );
 
  149   if ( prepareRes != SQLITE_OK )
 
  155   while ( statement.
step() == SQLITE_ROW )
 
  158     transforms.push_back( cOpCode.toInt() );
 
  164   QString transformString;
 
  168   if ( openResult != SQLITE_OK )
 
  170     return transformString;
 
  174   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 );
 
  176   statement = database.
prepare( sql, prepareRes );
 
  177   if ( prepareRes != SQLITE_OK )
 
  179     return transformString;
 
  182   if ( statement.
step() == SQLITE_ROW )
 
  186     if ( methodCode == 9615 ) 
 
  188       transformString = 
"+nadgrids=" + statement.
columnAsText( 1 );
 
  190     else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
 
  192       transformString += QLatin1String( 
"+towgs84=" );
 
  200       if ( methodCode == 9603 ) 
 
  202         transformString += QStringLiteral( 
"%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
 
  206         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 ) );
 
  211   return transformString;
 
  218   if ( openResult != SQLITE_OK )
 
  224   QString sql = QStringLiteral( 
"SELECT coord_op_method_code,p1,p2,p3,p4,p5,p6,p7,coord_op_code FROM tbl_datum_transform" );
 
  226   statement = database.
prepare( sql, prepareRes );
 
  227   if ( prepareRes != SQLITE_OK )
 
  232   while ( statement.
step() == SQLITE_ROW )
 
  234     QString transformString;
 
  237     if ( methodCode == 9615 ) 
 
  239       transformString = 
"+nadgrids=" + statement.
columnAsText( 1 );
 
  241     else if ( methodCode == 9603 || methodCode == 9606 || methodCode == 9607 )
 
  243       transformString += QLatin1String( 
"+towgs84=" );
 
  251       if ( methodCode == 9603 ) 
 
  253         transformString += QStringLiteral( 
"%1,%2,%3" ).arg( QString::number( p1 ), QString::number( p2 ), QString::number( p3 ) );
 
  257         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 ) );
 
  261     if ( transformString.compare( 
string, Qt::CaseInsensitive ) == 0 )
 
  276   if ( openResult != SQLITE_OK )
 
  282   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 );
 
  284   statement = database.
prepare( sql, prepareRes );
 
  285   if ( prepareRes != SQLITE_OK )
 
  290   int srcCrsId, destCrsId;
 
  291   if ( statement.
step() != SQLITE_ROW )
 
  315 #if PROJ_VERSION_MAJOR>=6 
  319   TransformDetails details;
 
  323   QgsProjUtils::proj_pj_unique_ptr normalized( proj_normalize_for_visualization( pjContext, op ) );
 
  325     details.proj = QString( proj_as_proj_string( pjContext, normalized.get(), PJ_PROJ_5, 
nullptr ) );
 
  327   if ( details.proj.isEmpty() )
 
  328     details.proj = QString( proj_as_proj_string( pjContext, op, PJ_PROJ_5, 
nullptr ) );
 
  330   if ( details.proj.isEmpty() )
 
  333   details.name = QString( proj_get_name( op ) );
 
  334   details.accuracy = proj_coordoperation_get_accuracy( pjContext, op );
 
  335   details.isAvailable = proj_coordoperation_is_instantiable( pjContext, op );
 
  337   details.authority = QString( proj_get_id_auth_name( op, 0 ) );
 
  338   details.code = QString( proj_get_id_code( op, 0 ) );
 
  340   const char *areaOfUseName = 
nullptr;
 
  345   if ( proj_get_area_of_use( pjContext, op, &westLon, &southLat, &eastLon, &northLat, &areaOfUseName ) )
 
  347     details.areaOfUse = QString( areaOfUseName );
 
  349     details.bounds.setXMinimum( westLon );
 
  350     details.bounds.setYMinimum( southLat );
 
  351     details.bounds.setXMaximum( eastLon );
 
  352     details.bounds.setYMaximum( northLat );
 
  355   details.remarks = QString( proj_get_remarks( op ) );
 
  356   details.scope = QString( proj_get_scope( op ) );
 
  358   for ( 
int j = 0; j < proj_coordoperation_get_grid_used_count( pjContext, op ); ++j )
 
  360     const char *shortName = 
nullptr;
 
  361     const char *fullName = 
nullptr;
 
  362     const char *packageName = 
nullptr;
 
  363     const char *url = 
nullptr;
 
  364     int directDownload = 0;
 
  367     proj_coordoperation_get_grid_used( pjContext, op, j, &shortName, &fullName, &packageName, &url, &directDownload, &openLicense, &isAvailable );
 
  368     GridDetails gridDetails;
 
  369     gridDetails.shortName = QString( shortName );
 
  370     gridDetails.fullName = QString( fullName );
 
  371     gridDetails.packageName = QString( packageName );
 
  372     gridDetails.url = QString( url );
 
  373     gridDetails.directDownload = directDownload;
 
  374     gridDetails.openLicense = openLicense;
 
  375     gridDetails.isAvailable = isAvailable;
 
  377     details.grids.append( gridDetails );
 
  380   if ( proj_get_type( op ) == PJ_TYPE_CONCATENATED_OPERATION )
 
  382     for ( 
int j = 0; j < proj_concatoperation_get_step_count( pjContext, op ); ++j )
 
  384       QgsProjUtils::proj_pj_unique_ptr step( proj_concatoperation_get_step( pjContext, op, j ) );
 
  387         SingleOperationDetails singleOpDetails;
 
  388         singleOpDetails.remarks = QString( proj_get_remarks( step.get() ) );
 
  389         singleOpDetails.scope = QString( proj_get_scope( step.get() ) );
 
  390         singleOpDetails.authority = QString( proj_get_id_auth_name( step.get(), 0 ) );
 
  391         singleOpDetails.code = QString( proj_get_id_code( step.get(), 0 ) );
 
  393         const char *areaOfUseName = 
nullptr;
 
  394         if ( proj_get_area_of_use( pjContext, step.get(), 
nullptr, 
nullptr, 
nullptr, 
nullptr, &areaOfUseName ) )
 
  396           singleOpDetails.areaOfUse = QString( areaOfUseName );
 
  398         details.operationDetails.append( singleOpDetails );
 
  404     SingleOperationDetails singleOpDetails;
 
  405     singleOpDetails.remarks = QString( proj_get_remarks( op ) );
 
  406     singleOpDetails.scope = QString( proj_get_scope( op ) );
 
  407     singleOpDetails.authority = QString( proj_get_id_auth_name( op, 0 ) );
 
  408     singleOpDetails.code = QString( proj_get_id_code( op, 0 ) );
 
  410     const char *areaOfUseName = 
nullptr;
 
  411     if ( proj_get_area_of_use( pjContext, op, 
nullptr, 
nullptr, 
nullptr, 
nullptr, &areaOfUseName ) )
 
  413       singleOpDetails.areaOfUse = QString( areaOfUseName );
 
  415     details.operationDetails.append( singleOpDetails );