QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgsgdalutils.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsgdalutils.cpp
3  ----------------
4  begin : September 2018
5  copyright : (C) 2018 Even Rouault
6  email : even.rouault at spatialys.com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsgdalutils.h"
17 #include "qgslogger.h"
19 #include "qgssettings.h"
20 
21 #define CPL_SUPRESS_CPLUSPLUS //#spellok
22 #include "gdal.h"
23 #include "gdalwarper.h"
24 #include "cpl_string.h"
25 
26 #include <QNetworkProxy>
27 #include <QString>
28 #include <QImage>
29 
30 bool QgsGdalUtils::supportsRasterCreate( GDALDriverH driver )
31 {
32  QString driverShortName = GDALGetDriverShortName( driver );
33  if ( driverShortName == QLatin1String( "SQLite" ) )
34  {
35  // it supports Create() but only for vector side
36  return false;
37  }
38  char **driverMetadata = GDALGetMetadata( driver, nullptr );
39  return CSLFetchBoolean( driverMetadata, GDAL_DCAP_CREATE, false ) &&
40  CSLFetchBoolean( driverMetadata, GDAL_DCAP_RASTER, false );
41 }
42 
43 gdal::dataset_unique_ptr QgsGdalUtils::createSingleBandMemoryDataset( GDALDataType dataType, const QgsRectangle &extent, int width, int height, const QgsCoordinateReferenceSystem &crs )
44 {
45  return createMultiBandMemoryDataset( dataType, 1, extent, width, height, crs );
46 }
47 
48 gdal::dataset_unique_ptr QgsGdalUtils::createMultiBandMemoryDataset( GDALDataType dataType, int bands, const QgsRectangle &extent, int width, int height, const QgsCoordinateReferenceSystem &crs )
49 {
50  GDALDriverH hDriverMem = GDALGetDriverByName( "MEM" );
51  if ( !hDriverMem )
52  {
53  return gdal::dataset_unique_ptr();
54  }
55 
56  gdal::dataset_unique_ptr hSrcDS( GDALCreate( hDriverMem, "", width, height, bands, dataType, nullptr ) );
57 
58  double cellSizeX = extent.width() / width;
59  double cellSizeY = extent.height() / height;
60  double geoTransform[6];
61  geoTransform[0] = extent.xMinimum();
62  geoTransform[1] = cellSizeX;
63  geoTransform[2] = 0;
64  geoTransform[3] = extent.yMinimum() + ( cellSizeY * height );
65  geoTransform[4] = 0;
66  geoTransform[5] = -cellSizeY;
67 
68  GDALSetProjection( hSrcDS.get(), crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED_GDAL ).toLatin1().constData() );
69  GDALSetGeoTransform( hSrcDS.get(), geoTransform );
70  return hSrcDS;
71 }
72 
73 gdal::dataset_unique_ptr QgsGdalUtils::createSingleBandTiffDataset( const QString &filename, GDALDataType dataType, const QgsRectangle &extent, int width, int height, const QgsCoordinateReferenceSystem &crs )
74 {
75  double cellSizeX = extent.width() / width;
76  double cellSizeY = extent.height() / height;
77  double geoTransform[6];
78  geoTransform[0] = extent.xMinimum();
79  geoTransform[1] = cellSizeX;
80  geoTransform[2] = 0;
81  geoTransform[3] = extent.yMinimum() + ( cellSizeY * height );
82  geoTransform[4] = 0;
83  geoTransform[5] = -cellSizeY;
84 
85  GDALDriverH hDriver = GDALGetDriverByName( "GTiff" );
86  if ( !hDriver )
87  {
88  return gdal::dataset_unique_ptr();
89  }
90 
91  // Create the output file.
92  gdal::dataset_unique_ptr hDstDS( GDALCreate( hDriver, filename.toLocal8Bit().constData(), width, height, 1, dataType, nullptr ) );
93  if ( !hDstDS )
94  {
95  return gdal::dataset_unique_ptr();
96  }
97 
98  // Write out the projection definition.
99  GDALSetProjection( hDstDS.get(), crs.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED_GDAL ).toLatin1().constData() );
100  GDALSetGeoTransform( hDstDS.get(), geoTransform );
101  return hDstDS;
102 }
103 
105 {
106  if ( image.isNull() )
107  return nullptr;
108 
109  const QRgb *rgb = reinterpret_cast<const QRgb *>( image.constBits() );
110  GDALDriverH hDriverMem = GDALGetDriverByName( "MEM" );
111  if ( !hDriverMem )
112  {
113  return nullptr;
114  }
115  gdal::dataset_unique_ptr hSrcDS( GDALCreate( hDriverMem, "", image.width(), image.height(), 0, GDT_Byte, nullptr ) );
116 
117  char **papszOptions = QgsGdalUtils::papszFromStringList( QStringList()
118  << QStringLiteral( "PIXELOFFSET=%1" ).arg( sizeof( QRgb ) )
119  << QStringLiteral( "LINEOFFSET=%1" ).arg( image.bytesPerLine() )
120  << QStringLiteral( "DATAPOINTER=%1" ).arg( reinterpret_cast< qulonglong >( rgb ) + 2 ) );
121  GDALAddBand( hSrcDS.get(), GDT_Byte, papszOptions );
122  CSLDestroy( papszOptions );
123 
124  papszOptions = QgsGdalUtils::papszFromStringList( QStringList()
125  << QStringLiteral( "PIXELOFFSET=%1" ).arg( sizeof( QRgb ) )
126  << QStringLiteral( "LINEOFFSET=%1" ).arg( image.bytesPerLine() )
127  << QStringLiteral( "DATAPOINTER=%1" ).arg( reinterpret_cast< qulonglong >( rgb ) + 1 ) );
128  GDALAddBand( hSrcDS.get(), GDT_Byte, papszOptions );
129  CSLDestroy( papszOptions );
130 
131  papszOptions = QgsGdalUtils::papszFromStringList( QStringList()
132  << QStringLiteral( "PIXELOFFSET=%1" ).arg( sizeof( QRgb ) )
133  << QStringLiteral( "LINEOFFSET=%1" ).arg( image.bytesPerLine() )
134  << QStringLiteral( "DATAPOINTER=%1" ).arg( reinterpret_cast< qulonglong >( rgb ) ) );
135  GDALAddBand( hSrcDS.get(), GDT_Byte, papszOptions );
136  CSLDestroy( papszOptions );
137 
138  papszOptions = QgsGdalUtils::papszFromStringList( QStringList()
139  << QStringLiteral( "PIXELOFFSET=%1" ).arg( sizeof( QRgb ) )
140  << QStringLiteral( "LINEOFFSET=%1" ).arg( image.bytesPerLine() )
141  << QStringLiteral( "DATAPOINTER=%1" ).arg( reinterpret_cast< qulonglong >( rgb ) + 3 ) );
142  GDALAddBand( hSrcDS.get(), GDT_Byte, papszOptions );
143  CSLDestroy( papszOptions );
144 
145  return hSrcDS;
146 }
147 
148 void QgsGdalUtils::resampleSingleBandRaster( GDALDatasetH hSrcDS, GDALDatasetH hDstDS, GDALResampleAlg resampleAlg )
149 {
150  gdal::warp_options_unique_ptr psWarpOptions( GDALCreateWarpOptions() );
151  psWarpOptions->hSrcDS = hSrcDS;
152  psWarpOptions->hDstDS = hDstDS;
153 
154  psWarpOptions->nBandCount = 1;
155  psWarpOptions->panSrcBands = reinterpret_cast< int * >( CPLMalloc( sizeof( int ) * 1 ) );
156  psWarpOptions->panDstBands = reinterpret_cast< int * >( CPLMalloc( sizeof( int ) * 1 ) );
157  psWarpOptions->panSrcBands[0] = 1;
158  psWarpOptions->panDstBands[0] = 1;
159 
160  psWarpOptions->eResampleAlg = resampleAlg;
161 
162  // Establish reprojection transformer.
163  psWarpOptions->pTransformerArg =
164  GDALCreateGenImgProjTransformer( hSrcDS, GDALGetProjectionRef( hSrcDS ),
165  hDstDS, GDALGetProjectionRef( hDstDS ),
166  FALSE, 0.0, 1 );
167  psWarpOptions->pfnTransformer = GDALGenImgProjTransform;
168 
169  // Initialize and execute the warp operation.
170  GDALWarpOperation oOperation;
171  oOperation.Initialize( psWarpOptions.get() );
172 
173  oOperation.ChunkAndWarpImage( 0, 0, GDALGetRasterXSize( hDstDS ), GDALGetRasterYSize( hDstDS ) );
174 
175  GDALDestroyGenImgProjTransformer( psWarpOptions->pTransformerArg );
176 }
177 
178 QImage QgsGdalUtils::resampleImage( const QImage &image, QSize outputSize, GDALRIOResampleAlg resampleAlg )
179 {
181  if ( !srcDS )
182  return QImage();
183 
184  GDALRasterIOExtraArg extra;
185  INIT_RASTERIO_EXTRA_ARG( extra );
186  extra.eResampleAlg = resampleAlg;
187 
188  QImage res( outputSize, image.format() );
189  if ( res.isNull() )
190  return QImage();
191 
192  GByte *rgb = reinterpret_cast<GByte *>( res.bits() );
193 
194  CPLErr err = GDALRasterIOEx( GDALGetRasterBand( srcDS.get(), 1 ), GF_Read, 0, 0, image.width(), image.height(), rgb + 2, outputSize.width(),
195  outputSize.height(), GDT_Byte, sizeof( QRgb ), res.bytesPerLine(), &extra );
196  if ( err != CE_None )
197  {
198  QgsDebugMsg( QStringLiteral( "failed to read red band" ) );
199  return QImage();
200  }
201 
202  err = GDALRasterIOEx( GDALGetRasterBand( srcDS.get(), 2 ), GF_Read, 0, 0, image.width(), image.height(), rgb + 1, outputSize.width(),
203  outputSize.height(), GDT_Byte, sizeof( QRgb ), res.bytesPerLine(), &extra );
204  if ( err != CE_None )
205  {
206  QgsDebugMsg( QStringLiteral( "failed to read green band" ) );
207  return QImage();
208  }
209 
210  err = GDALRasterIOEx( GDALGetRasterBand( srcDS.get(), 3 ), GF_Read, 0, 0, image.width(), image.height(), rgb, outputSize.width(),
211  outputSize.height(), GDT_Byte, sizeof( QRgb ), res.bytesPerLine(), &extra );
212  if ( err != CE_None )
213  {
214  QgsDebugMsg( QStringLiteral( "failed to read blue band" ) );
215  return QImage();
216  }
217 
218  err = GDALRasterIOEx( GDALGetRasterBand( srcDS.get(), 4 ), GF_Read, 0, 0, image.width(), image.height(), rgb + 3, outputSize.width(),
219  outputSize.height(), GDT_Byte, sizeof( QRgb ), res.bytesPerLine(), &extra );
220  if ( err != CE_None )
221  {
222  QgsDebugMsg( QStringLiteral( "failed to read alpha band" ) );
223  return QImage();
224  }
225 
226  return res;
227 }
228 
229 QString QgsGdalUtils::helpCreationOptionsFormat( const QString &format )
230 {
231  QString message;
232  GDALDriverH myGdalDriver = GDALGetDriverByName( format.toLocal8Bit().constData() );
233  if ( myGdalDriver )
234  {
235  // first report details and help page
236  char **GDALmetadata = GDALGetMetadata( myGdalDriver, nullptr );
237  message += QLatin1String( "Format Details:\n" );
238  message += QStringLiteral( " Extension: %1\n" ).arg( CSLFetchNameValue( GDALmetadata, GDAL_DMD_EXTENSION ) );
239  message += QStringLiteral( " Short Name: %1" ).arg( GDALGetDriverShortName( myGdalDriver ) );
240  message += QStringLiteral( " / Long Name: %1\n" ).arg( GDALGetDriverLongName( myGdalDriver ) );
241  message += QStringLiteral( " Help page: http://www.gdal.org/%1\n\n" ).arg( CSLFetchNameValue( GDALmetadata, GDAL_DMD_HELPTOPIC ) );
242 
243  // next get creation options
244  // need to serialize xml to get newlines, should we make the basic xml prettier?
245  CPLXMLNode *psCOL = CPLParseXMLString( GDALGetMetadataItem( myGdalDriver,
246  GDAL_DMD_CREATIONOPTIONLIST, "" ) );
247  char *pszFormattedXML = CPLSerializeXMLTree( psCOL );
248  if ( pszFormattedXML )
249  message += QString( pszFormattedXML );
250  if ( psCOL )
251  CPLDestroyXMLNode( psCOL );
252  if ( pszFormattedXML )
253  CPLFree( pszFormattedXML );
254  }
255  return message;
256 }
257 
258 char **QgsGdalUtils::papszFromStringList( const QStringList &list )
259 {
260  char **papszRetList = nullptr;
261  const auto constList = list;
262  for ( const QString &elem : constList )
263  {
264  papszRetList = CSLAddString( papszRetList, elem.toLocal8Bit().constData() );
265  }
266  return papszRetList;
267 }
268 
269 QString QgsGdalUtils::validateCreationOptionsFormat( const QStringList &createOptions, const QString &format )
270 {
271  GDALDriverH myGdalDriver = GDALGetDriverByName( format.toLocal8Bit().constData() );
272  if ( ! myGdalDriver )
273  return QStringLiteral( "invalid GDAL driver" );
274 
275  char **papszOptions = papszFromStringList( createOptions );
276  // get error string?
277  int ok = GDALValidateCreationOptions( myGdalDriver, papszOptions );
278  CSLDestroy( papszOptions );
279 
280  if ( !ok )
281  return QStringLiteral( "Failed GDALValidateCreationOptions() test" );
282  return QString();
283 }
284 
285 #if GDAL_VERSION_NUM < GDAL_COMPUTE_VERSION(2,3,0)
286 // GDAL < 2.3 does not come with GDALWarpInitDefaultBandMapping and GDALWarpInitNoDataReal
287 // in the public API so we define them here for rpcAwareAutoCreateWarpedVrt()
288 
289 static void GDALWarpInitDefaultBandMapping( GDALWarpOptions *psOptionsIn, int nBandCount )
290 {
291  if ( psOptionsIn->nBandCount != 0 ) { return; }
292 
293  psOptionsIn->nBandCount = nBandCount;
294 
295  psOptionsIn->panSrcBands = static_cast<int *>(
296  CPLMalloc( sizeof( int ) * psOptionsIn->nBandCount ) );
297  psOptionsIn->panDstBands = static_cast<int *>(
298  CPLMalloc( sizeof( int ) * psOptionsIn->nBandCount ) );
299 
300  for ( int i = 0; i < psOptionsIn->nBandCount; i++ )
301  {
302  psOptionsIn->panSrcBands[i] = i + 1;
303  psOptionsIn->panDstBands[i] = i + 1;
304  }
305 }
306 
307 static void InitNoData( int nBandCount, double **ppdNoDataReal, double dDataReal )
308 {
309  if ( nBandCount <= 0 ) { return; }
310  if ( *ppdNoDataReal != nullptr ) { return; }
311 
312  *ppdNoDataReal = static_cast<double *>(
313  CPLMalloc( sizeof( double ) * nBandCount ) );
314 
315  for ( int i = 0; i < nBandCount; ++i )
316  {
317  ( *ppdNoDataReal )[i] = dDataReal;
318  }
319 }
320 
321 static void GDALWarpInitNoDataReal( GDALWarpOptions *psOptionsIn, double dNoDataReal )
322 {
323  InitNoData( psOptionsIn->nBandCount, &psOptionsIn->padfDstNoDataReal, dNoDataReal );
324  InitNoData( psOptionsIn->nBandCount, &psOptionsIn->padfSrcNoDataReal, dNoDataReal );
325  // older GDAL also requires imaginary values to be set
326  InitNoData( psOptionsIn->nBandCount, &psOptionsIn->padfDstNoDataImag, 0 );
327  InitNoData( psOptionsIn->nBandCount, &psOptionsIn->padfSrcNoDataImag, 0 );
328 }
329 #endif
330 
331 #if GDAL_VERSION_NUM < GDAL_COMPUTE_VERSION(3,2,0)
332 
333 GDALDatasetH GDALAutoCreateWarpedVRTEx( GDALDatasetH hSrcDS, const char *pszSrcWKT, const char *pszDstWKT, GDALResampleAlg eResampleAlg,
334  double dfMaxError, const GDALWarpOptions *psOptionsIn, char **papszTransformerOptions )
335 {
336  VALIDATE_POINTER1( hSrcDS, "GDALAutoCreateWarpedVRT", nullptr );
337 
338  /* -------------------------------------------------------------------- */
339  /* Populate the warp options. */
340  /* -------------------------------------------------------------------- */
341  GDALWarpOptions *psWO = nullptr;
342  if ( psOptionsIn != nullptr )
343  psWO = GDALCloneWarpOptions( psOptionsIn );
344  else
345  psWO = GDALCreateWarpOptions();
346 
347  psWO->eResampleAlg = eResampleAlg;
348 
349  psWO->hSrcDS = hSrcDS;
350 
351  GDALWarpInitDefaultBandMapping( psWO, GDALGetRasterCount( hSrcDS ) );
352 
353  /* -------------------------------------------------------------------- */
354  /* Setup no data values */
355  /* -------------------------------------------------------------------- */
356  for ( int i = 0; i < psWO->nBandCount; i++ )
357  {
358  GDALRasterBandH rasterBand = GDALGetRasterBand( psWO->hSrcDS, psWO->panSrcBands[i] );
359 
360  int hasNoDataValue;
361  double noDataValue = GDALGetRasterNoDataValue( rasterBand, &hasNoDataValue );
362 
363  if ( hasNoDataValue )
364  {
365  // Check if the nodata value is out of range
366  int bClamped = FALSE;
367  int bRounded = FALSE;
368  CPL_IGNORE_RET_VAL(
369  GDALAdjustValueToDataType( GDALGetRasterDataType( rasterBand ),
370  noDataValue, &bClamped, &bRounded ) );
371  if ( !bClamped )
372  {
373  GDALWarpInitNoDataReal( psWO, -1e10 );
374 
375  psWO->padfSrcNoDataReal[i] = noDataValue;
376  psWO->padfDstNoDataReal[i] = noDataValue;
377  }
378  }
379  }
380 
381  if ( psWO->padfDstNoDataReal != nullptr )
382  {
383  if ( CSLFetchNameValue( psWO->papszWarpOptions, "INIT_DEST" ) == nullptr )
384  {
385  psWO->papszWarpOptions =
386  CSLSetNameValue( psWO->papszWarpOptions, "INIT_DEST", "NO_DATA" );
387  }
388  }
389 
390  /* -------------------------------------------------------------------- */
391  /* Create the transformer. */
392  /* -------------------------------------------------------------------- */
393  psWO->pfnTransformer = GDALGenImgProjTransform;
394 
395  char **papszOptions = nullptr;
396  if ( pszSrcWKT != nullptr )
397  papszOptions = CSLSetNameValue( papszOptions, "SRC_SRS", pszSrcWKT );
398  if ( pszDstWKT != nullptr )
399  papszOptions = CSLSetNameValue( papszOptions, "DST_SRS", pszDstWKT );
400  papszOptions = CSLMerge( papszOptions, papszTransformerOptions );
401  psWO->pTransformerArg =
402  GDALCreateGenImgProjTransformer2( psWO->hSrcDS, nullptr,
403  papszOptions );
404  CSLDestroy( papszOptions );
405 
406  if ( psWO->pTransformerArg == nullptr )
407  {
408  GDALDestroyWarpOptions( psWO );
409  return nullptr;
410  }
411 
412  /* -------------------------------------------------------------------- */
413  /* Figure out the desired output bounds and resolution. */
414  /* -------------------------------------------------------------------- */
415  double adfDstGeoTransform[6] = { 0.0 };
416  int nDstPixels = 0;
417  int nDstLines = 0;
418  CPLErr eErr =
419  GDALSuggestedWarpOutput( hSrcDS, psWO->pfnTransformer,
420  psWO->pTransformerArg,
421  adfDstGeoTransform, &nDstPixels, &nDstLines );
422  if ( eErr != CE_None )
423  {
424  GDALDestroyTransformer( psWO->pTransformerArg );
425  GDALDestroyWarpOptions( psWO );
426  return nullptr;
427  }
428 
429  /* -------------------------------------------------------------------- */
430  /* Update the transformer to include an output geotransform */
431  /* back to pixel/line coordinates. */
432  /* */
433  /* -------------------------------------------------------------------- */
434  GDALSetGenImgProjTransformerDstGeoTransform(
435  psWO->pTransformerArg, adfDstGeoTransform );
436 
437  /* -------------------------------------------------------------------- */
438  /* Do we want to apply an approximating transformation? */
439  /* -------------------------------------------------------------------- */
440  if ( dfMaxError > 0.0 )
441  {
442  psWO->pTransformerArg =
443  GDALCreateApproxTransformer( psWO->pfnTransformer,
444  psWO->pTransformerArg,
445  dfMaxError );
446  psWO->pfnTransformer = GDALApproxTransform;
447  GDALApproxTransformerOwnsSubtransformer( psWO->pTransformerArg, TRUE );
448  }
449 
450  /* -------------------------------------------------------------------- */
451  /* Create the VRT file. */
452  /* -------------------------------------------------------------------- */
453  GDALDatasetH hDstDS
454  = GDALCreateWarpedVRT( hSrcDS, nDstPixels, nDstLines,
455  adfDstGeoTransform, psWO );
456 
457  GDALDestroyWarpOptions( psWO );
458 
459  if ( pszDstWKT != nullptr )
460  GDALSetProjection( hDstDS, pszDstWKT );
461  else if ( pszSrcWKT != nullptr )
462  GDALSetProjection( hDstDS, pszSrcWKT );
463  else if ( GDALGetGCPCount( hSrcDS ) > 0 )
464  GDALSetProjection( hDstDS, GDALGetGCPProjection( hSrcDS ) );
465  else
466  GDALSetProjection( hDstDS, GDALGetProjectionRef( hSrcDS ) );
467 
468  return hDstDS;
469 }
470 #endif
471 
472 
474  GDALDatasetH hSrcDS,
475  const char *pszSrcWKT,
476  const char *pszDstWKT,
477  GDALResampleAlg eResampleAlg,
478  double dfMaxError,
479  const GDALWarpOptions *psOptionsIn )
480 {
481  char **opts = nullptr;
482  if ( GDALGetMetadata( hSrcDS, "RPC" ) )
483  {
484  // well-behaved RPC should have height offset a good value for RPC_HEIGHT
485  const char *heightOffStr = GDALGetMetadataItem( hSrcDS, "HEIGHT_OFF", "RPC" );
486  if ( heightOffStr )
487  opts = CSLAddNameValue( opts, "RPC_HEIGHT", heightOffStr );
488  }
489 
490  return GDALAutoCreateWarpedVRTEx( hSrcDS, pszSrcWKT, pszDstWKT, eResampleAlg, dfMaxError, psOptionsIn, opts );
491 }
492 
493 void *QgsGdalUtils::rpcAwareCreateTransformer( GDALDatasetH hSrcDS, GDALDatasetH hDstDS, char **papszOptions )
494 {
495  char **opts = CSLDuplicate( papszOptions );
496  if ( GDALGetMetadata( hSrcDS, "RPC" ) )
497  {
498  // well-behaved RPC should have height offset a good value for RPC_HEIGHT
499  const char *heightOffStr = GDALGetMetadataItem( hSrcDS, "HEIGHT_OFF", "RPC" );
500  if ( heightOffStr )
501  opts = CSLAddNameValue( opts, "RPC_HEIGHT", heightOffStr );
502  }
503  void *transformer = GDALCreateGenImgProjTransformer2( hSrcDS, hDstDS, opts );
504  CSLDestroy( opts );
505  return transformer;
506 }
507 
508 #ifndef QT_NO_NETWORKPROXY
510 {
511  // Check proxy configuration, they are application level but
512  // instead of adding an API and complex signal/slot connections
513  // given the limited cost of checking them on every provider instantiation
514  // we can do it here so that new settings are applied whenever a new layer
515  // is created.
516  QgsSettings settings;
517  // Check that proxy is enabled
518  if ( settings.value( QStringLiteral( "proxy/proxyEnabled" ), false ).toBool() )
519  {
520  // Get the first configured proxy
521  QList<QNetworkProxy> proxies( QgsNetworkAccessManager::instance()->proxyFactory()->queryProxy( ) );
522  if ( ! proxies.isEmpty() )
523  {
524  QNetworkProxy proxy( proxies.first() );
525  // TODO/FIXME: check excludes (the GDAL config options are global, we need a per-connection config option)
526  //QStringList excludes;
527  //excludes = settings.value( QStringLiteral( "proxy/proxyExcludedUrls" ), "" ).toStringList();
528 
529  QString proxyHost( proxy.hostName() );
530  qint16 proxyPort( proxy.port() );
531 
532  QString proxyUser( proxy.user() );
533  QString proxyPassword( proxy.password() );
534 
535  if ( ! proxyHost.isEmpty() )
536  {
537  QString connection( proxyHost );
538  if ( proxyPort )
539  {
540  connection += ':' + QString::number( proxyPort );
541  }
542  CPLSetConfigOption( "GDAL_HTTP_PROXY", connection.toUtf8() );
543  if ( ! proxyUser.isEmpty( ) )
544  {
545  QString credentials( proxyUser );
546  if ( ! proxyPassword.isEmpty( ) )
547  {
548  credentials += ':' + proxyPassword;
549  }
550  CPLSetConfigOption( "GDAL_HTTP_PROXYUSERPWD", credentials.toUtf8() );
551  }
552  }
553  }
554  }
555 }
556 #endif
QgsGdalUtils::imageToMemoryDataset
static gdal::dataset_unique_ptr imageToMemoryDataset(const QImage &image)
Converts an image to a GDAL memory dataset by borrowing image data.
Definition: qgsgdalutils.cpp:104
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:209
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsCoordinateReferenceSystem::WKT_PREFERRED_GDAL
@ WKT_PREFERRED_GDAL
Preferred format for conversion of CRS to WKT for use with the GDAL library.
Definition: qgscoordinatereferencesystem.h:681
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:51
qgsgdalutils.h
QgsRectangle::yMinimum
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QgsGdalUtils::supportsRasterCreate
static bool supportsRasterCreate(GDALDriverH driver)
Reads whether a driver supports GDALCreate() for raster purposes.
Definition: qgsgdalutils.cpp:30
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsRectangle
A rectangle specified with double values.
Definition: qgsrectangle.h:42
QgsGdalUtils::validateCreationOptionsFormat
static QString validateCreationOptionsFormat(const QStringList &createOptions, const QString &format)
Validates creation options for a given format, regardless of layer.
Definition: qgsgdalutils.cpp:269
gdal::dataset_unique_ptr
std::unique_ptr< std::remove_pointer< GDALDatasetH >::type, GDALDatasetCloser > dataset_unique_ptr
Scoped GDAL dataset.
Definition: qgsogrutils.h:134
qgsnetworkaccessmanager.h
QgsGdalUtils::createSingleBandMemoryDataset
static gdal::dataset_unique_ptr createSingleBandMemoryDataset(GDALDataType dataType, const QgsRectangle &extent, int width, int height, const QgsCoordinateReferenceSystem &crs)
Creates a new single band memory dataset with given parameters.
Definition: qgsgdalutils.cpp:43
QgsCoordinateReferenceSystem::toWkt
QString toWkt(WktVariant variant=WKT1_GDAL, bool multiline=false, int indentationWidth=4) const
Returns a WKT representation of this CRS.
Definition: qgscoordinatereferencesystem.cpp:1954
QgsGdalUtils::createMultiBandMemoryDataset
static gdal::dataset_unique_ptr createMultiBandMemoryDataset(GDALDataType dataType, int bands, const QgsRectangle &extent, int width, int height, const QgsCoordinateReferenceSystem &crs)
Creates a new multi band memory dataset with given parameters.
Definition: qgsgdalutils.cpp:48
QgsGdalUtils::papszFromStringList
static char ** papszFromStringList(const QStringList &list)
Helper function.
Definition: qgsgdalutils.cpp:258
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsNetworkAccessManager::instance
static QgsNetworkAccessManager * instance(Qt::ConnectionType connectionType=Qt::BlockingQueuedConnection)
Returns a pointer to the active QgsNetworkAccessManager for the current thread.
Definition: qgsnetworkaccessmanager.cpp:121
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:206
QgsGdalUtils::createSingleBandTiffDataset
static gdal::dataset_unique_ptr createSingleBandTiffDataset(const QString &filename, GDALDataType dataType, const QgsRectangle &extent, int width, int height, const QgsCoordinateReferenceSystem &crs)
Creates a new single band TIFF dataset with given parameters.
Definition: qgsgdalutils.cpp:73
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
qgssettings.h
QgsGdalUtils::resampleImage
static QImage resampleImage(const QImage &image, QSize outputSize, GDALRIOResampleAlg resampleAlg)
Resamples a QImage image using GDAL resampler.
Definition: qgsgdalutils.cpp:178
QgsGdalUtils::setupProxy
static void setupProxy()
Sets the gdal proxy variables.
Definition: qgsgdalutils.cpp:509
qgslogger.h
QgsGdalUtils::helpCreationOptionsFormat
static QString helpCreationOptionsFormat(const QString &format)
Gets creation options metadata for a given format.
Definition: qgsgdalutils.cpp:229
QgsGdalUtils::rpcAwareAutoCreateWarpedVrt
static GDALDatasetH rpcAwareAutoCreateWarpedVrt(GDALDatasetH hSrcDS, const char *pszSrcWKT, const char *pszDstWKT, GDALResampleAlg eResampleAlg, double dfMaxError, const GDALWarpOptions *psOptionsIn)
This is a copy of GDALAutoCreateWarpedVRT optimized for imagery using RPC georeferencing that also se...
Definition: qgsgdalutils.cpp:473
QgsGdalUtils::resampleSingleBandRaster
static void resampleSingleBandRaster(GDALDatasetH hSrcDS, GDALDatasetH hDstDS, GDALResampleAlg resampleAlg)
Resamples a single band raster to the destination dataset with different resolution (and possibly wit...
Definition: qgsgdalutils.cpp:148
QgsGdalUtils::rpcAwareCreateTransformer
static void * rpcAwareCreateTransformer(GDALDatasetH hSrcDS, GDALDatasetH hDstDS=nullptr, char **papszOptions=nullptr)
This is a wrapper around GDALCreateGenImgProjTransformer2() that takes into account RPC georeferencin...
Definition: qgsgdalutils.cpp:493
gdal::warp_options_unique_ptr
std::unique_ptr< GDALWarpOptions, GDALWarpOptionsDeleter > warp_options_unique_ptr
Scoped GDAL warp options.
Definition: qgsogrutils.h:149
GDALDatasetH
void * GDALDatasetH
Definition: qgsalignraster.h:28