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 );