Skip to content

Commit

Permalink
Merge pull request #5423 from nyalldawson/gdal_ptr
Browse files Browse the repository at this point in the history
Implement scoped pointers for gdal handled objects
  • Loading branch information
nyalldawson authored Oct 26, 2017
2 parents a2f380b + 5300f69 commit 93f8abe
Show file tree
Hide file tree
Showing 35 changed files with 816 additions and 796 deletions.
1 change: 0 additions & 1 deletion python/analysis/raster/qgsalignraster.sip
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class QgsAlignRaster
%Docstring
Construct raster info with a path to a raster file
%End
~RasterInfo();


bool isValid() const;
Expand Down
3 changes: 3 additions & 0 deletions python/analysis/raster/qgskde.sip
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ Type of output value
to generate the surface. The output path and file format are also required.
%End


Result run();
%Docstring
Runs the KDE calculation across the whole layer at once. Either call this method, or manually
Expand Down Expand Up @@ -128,6 +129,8 @@ Type of output value
:rtype: Result
%End

private:
QgsKernelDensityEstimation( const QgsKernelDensityEstimation &other );
};


Expand Down
1 change: 0 additions & 1 deletion python/analysis/raster/qgsninecellfilter.sip
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@




class QgsNineCellFilter
{
%Docstring
Expand Down
65 changes: 25 additions & 40 deletions src/analysis/raster/qgsalignraster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ bool QgsAlignRaster::createAndWarp( const Item &raster )
}

// Open the source file.
GDALDatasetH hSrcDS = GDALOpen( raster.inputFilename.toLocal8Bit().constData(), GA_ReadOnly );
gdal::dataset_unique_ptr hSrcDS( GDALOpen( raster.inputFilename.toLocal8Bit().constData(), GA_ReadOnly ) );
if ( !hSrcDS )
{
mErrorMessage = QObject::tr( "Unable to open input file: %1" ).arg( raster.inputFilename );
Expand All @@ -435,37 +435,35 @@ bool QgsAlignRaster::createAndWarp( const Item &raster )

// Create output with same datatype as first input band.

int bandCount = GDALGetRasterCount( hSrcDS );
GDALDataType eDT = GDALGetRasterDataType( GDALGetRasterBand( hSrcDS, 1 ) );
int bandCount = GDALGetRasterCount( hSrcDS.get() );
GDALDataType eDT = GDALGetRasterDataType( GDALGetRasterBand( hSrcDS.get(), 1 ) );

// Create the output file.
GDALDatasetH hDstDS;
hDstDS = GDALCreate( hDriver, raster.outputFilename.toLocal8Bit().constData(), mXSize, mYSize,
bandCount, eDT, nullptr );
gdal::dataset_unique_ptr hDstDS( GDALCreate( hDriver, raster.outputFilename.toLocal8Bit().constData(), mXSize, mYSize,
bandCount, eDT, nullptr ) );
if ( !hDstDS )
{
GDALClose( hSrcDS );
mErrorMessage = QObject::tr( "Unable to create output file: %1" ).arg( raster.outputFilename );
return false;
}

// Write out the projection definition.
GDALSetProjection( hDstDS, mCrsWkt.toLatin1().constData() );
GDALSetGeoTransform( hDstDS, mGeoTransform );
GDALSetProjection( hDstDS.get(), mCrsWkt.toLatin1().constData() );
GDALSetGeoTransform( hDstDS.get(), mGeoTransform );

// Copy the color table, if required.
GDALColorTableH hCT = GDALGetRasterColorTable( GDALGetRasterBand( hSrcDS, 1 ) );
GDALColorTableH hCT = GDALGetRasterColorTable( GDALGetRasterBand( hSrcDS.get(), 1 ) );
if ( hCT )
GDALSetRasterColorTable( GDALGetRasterBand( hDstDS, 1 ), hCT );
GDALSetRasterColorTable( GDALGetRasterBand( hDstDS.get(), 1 ), hCT );

// -----------------------------------------------------------------------

// Setup warp options.
GDALWarpOptions *psWarpOptions = GDALCreateWarpOptions();
psWarpOptions->hSrcDS = hSrcDS;
psWarpOptions->hDstDS = hDstDS;
gdal::warp_options_unique_ptr psWarpOptions( GDALCreateWarpOptions() );
psWarpOptions->hSrcDS = hSrcDS.get();
psWarpOptions->hDstDS = hDstDS.get();

psWarpOptions->nBandCount = GDALGetRasterCount( hSrcDS );
psWarpOptions->nBandCount = GDALGetRasterCount( hSrcDS.get() );
psWarpOptions->panSrcBands = ( int * ) CPLMalloc( sizeof( int ) * psWarpOptions->nBandCount );
psWarpOptions->panDstBands = ( int * ) CPLMalloc( sizeof( int ) * psWarpOptions->nBandCount );
for ( int i = 0; i < psWarpOptions->nBandCount; ++i )
Expand All @@ -482,8 +480,8 @@ bool QgsAlignRaster::createAndWarp( const Item &raster )

// Establish reprojection transformer.
psWarpOptions->pTransformerArg =
GDALCreateGenImgProjTransformer( hSrcDS, GDALGetProjectionRef( hSrcDS ),
hDstDS, GDALGetProjectionRef( hDstDS ),
GDALCreateGenImgProjTransformer( hSrcDS.get(), GDALGetProjectionRef( hSrcDS.get() ),
hDstDS.get(), GDALGetProjectionRef( hDstDS.get() ),
FALSE, 0.0, 1 );
psWarpOptions->pfnTransformer = GDALGenImgProjTransform;

Expand All @@ -502,14 +500,10 @@ bool QgsAlignRaster::createAndWarp( const Item &raster )

// Initialize and execute the warp operation.
GDALWarpOperation oOperation;
oOperation.Initialize( psWarpOptions );
oOperation.Initialize( psWarpOptions.get() );
oOperation.ChunkAndWarpImage( 0, 0, mXSize, mYSize );

GDALDestroyGenImgProjTransformer( psWarpOptions->pTransformerArg );
GDALDestroyWarpOptions( psWarpOptions );

GDALClose( hDstDS );
GDALClose( hSrcDS );
return true;
}

Expand All @@ -519,7 +513,7 @@ bool QgsAlignRaster::suggestedWarpOutput( const QgsAlignRaster::RasterInfo &info
// to destination georeferenced coordinates (not destination
// pixel line). We do that by omitting the destination dataset
// handle (setting it to nullptr).
void *hTransformArg = GDALCreateGenImgProjTransformer( info.mDataset, info.mCrsWkt.toLatin1().constData(), nullptr, destWkt.toLatin1().constData(), FALSE, 0, 1 );
void *hTransformArg = GDALCreateGenImgProjTransformer( info.mDataset.get(), info.mCrsWkt.toLatin1().constData(), nullptr, destWkt.toLatin1().constData(), FALSE, 0, 1 );
if ( !hTransformArg )
return false;

Expand All @@ -528,7 +522,7 @@ bool QgsAlignRaster::suggestedWarpOutput( const QgsAlignRaster::RasterInfo &info
double extents[4];
int nPixels = 0, nLines = 0;
CPLErr eErr;
eErr = GDALSuggestedWarpOutput2( info.mDataset,
eErr = GDALSuggestedWarpOutput2( info.mDataset.get(),
GDALGenImgProjTransform, hTransformArg,
adfDstGeoTransform, &nPixels, &nLines, extents, 0 );
GDALDestroyGenImgProjTransformer( hTransformArg );
Expand All @@ -553,29 +547,20 @@ bool QgsAlignRaster::suggestedWarpOutput( const QgsAlignRaster::RasterInfo &info


QgsAlignRaster::RasterInfo::RasterInfo( const QString &layerpath )
: mXSize( 0 )
, mYSize( 0 )
, mBandCnt( 0 )
{
mDataset = GDALOpen( layerpath.toLocal8Bit().constData(), GA_ReadOnly );
mDataset.reset( GDALOpen( layerpath.toLocal8Bit().constData(), GA_ReadOnly ) );
if ( !mDataset )
return;

mXSize = GDALGetRasterXSize( mDataset );
mYSize = GDALGetRasterYSize( mDataset );
mXSize = GDALGetRasterXSize( mDataset.get() );
mYSize = GDALGetRasterYSize( mDataset.get() );

( void ) GDALGetGeoTransform( mDataset, mGeoTransform );
( void ) GDALGetGeoTransform( mDataset.get(), mGeoTransform );

// TODO: may be null or empty string
mCrsWkt = QString::fromLatin1( GDALGetProjectionRef( mDataset ) );

mBandCnt = GDALGetBandNumber( mDataset );
}
mCrsWkt = QString::fromLatin1( GDALGetProjectionRef( mDataset.get() ) );

QgsAlignRaster::RasterInfo::~RasterInfo()
{
if ( mDataset )
GDALClose( mDataset );
mBandCnt = GDALGetBandNumber( mDataset.get() );
}

QSizeF QgsAlignRaster::RasterInfo::cellSize() const
Expand Down Expand Up @@ -616,7 +601,7 @@ void QgsAlignRaster::RasterInfo::dump() const

double QgsAlignRaster::RasterInfo::identify( double mx, double my )
{
GDALRasterBandH hBand = GDALGetRasterBand( mDataset, 1 );
GDALRasterBandH hBand = GDALGetRasterBand( mDataset.get(), 1 );

// must not be rotated in order for this to work
int px = int( ( mx - mGeoTransform[0] ) / mGeoTransform[1] );
Expand Down
12 changes: 7 additions & 5 deletions src/analysis/raster/qgsalignraster.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <gdal_version.h>
#include "qgis_analysis.h"
#include "qgis.h"
#include "qgsogrutils.h"

class QgsRectangle;

Expand Down Expand Up @@ -54,7 +55,6 @@ class ANALYSIS_EXPORT QgsAlignRaster
public:
//! Construct raster info with a path to a raster file
RasterInfo( const QString &layerpath );
~RasterInfo();

RasterInfo( const RasterInfo &rh ) = delete;
RasterInfo &operator=( const RasterInfo &rh ) = delete;
Expand Down Expand Up @@ -85,15 +85,17 @@ class ANALYSIS_EXPORT QgsAlignRaster

protected:
//! handle to open GDAL dataset
GDALDatasetH mDataset;
gdal::dataset_unique_ptr mDataset;
//! CRS stored in WKT format
QString mCrsWkt;
//! geotransform coefficients
double mGeoTransform[6];
//! raster grid size
int mXSize, mYSize;
//! raster grid size X
int mXSize = 0;
//! raster grid size Y
int mYSize = 0;
//! number of raster's bands
int mBandCnt;
int mBandCnt = 0;

private:
#ifdef SIP_RUN
Expand Down
17 changes: 7 additions & 10 deletions src/analysis/raster/qgskde.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ QgsKernelDensityEstimation::Result QgsKernelDensityEstimation::prepare()
return FileCreationError;

// open the raster in GA_Update mode
mDatasetH = GDALOpen( mOutputFile.toUtf8().constData(), GA_Update );
mDatasetH.reset( GDALOpen( mOutputFile.toUtf8().constData(), GA_Update ) );
if ( !mDatasetH )
return FileCreationError;
mRasterBandH = GDALGetRasterBand( mDatasetH, 1 );
mRasterBandH = GDALGetRasterBand( mDatasetH.get(), 1 );
if ( !mRasterBandH )
return FileCreationError;

Expand Down Expand Up @@ -207,8 +207,7 @@ QgsKernelDensityEstimation::Result QgsKernelDensityEstimation::addFeature( const

QgsKernelDensityEstimation::Result QgsKernelDensityEstimation::finalise()
{
GDALClose( ( GDALDatasetH ) mDatasetH );
mDatasetH = nullptr;
mDatasetH.reset();
mRasterBandH = nullptr;
return Success;
}
Expand All @@ -226,18 +225,18 @@ int QgsKernelDensityEstimation::radiusSizeInPixels( double radius ) const
bool QgsKernelDensityEstimation::createEmptyLayer( GDALDriverH driver, const QgsRectangle &bounds, int rows, int columns ) const
{
double geoTransform[6] = { bounds.xMinimum(), mPixelSize, 0, bounds.yMaximum(), 0, -mPixelSize };
GDALDatasetH emptyDataset = GDALCreate( driver, mOutputFile.toUtf8(), columns, rows, 1, GDT_Float32, nullptr );
gdal::dataset_unique_ptr emptyDataset( GDALCreate( driver, mOutputFile.toUtf8(), columns, rows, 1, GDT_Float32, nullptr ) );
if ( !emptyDataset )
return false;

if ( GDALSetGeoTransform( emptyDataset, geoTransform ) != CE_None )
if ( GDALSetGeoTransform( emptyDataset.get(), geoTransform ) != CE_None )
return false;

// Set the projection on the raster destination to match the input layer
if ( GDALSetProjection( emptyDataset, mSource->sourceCrs().toWkt().toLocal8Bit().data() ) != CE_None )
if ( GDALSetProjection( emptyDataset.get(), mSource->sourceCrs().toWkt().toLocal8Bit().data() ) != CE_None )
return false;

GDALRasterBandH poBand = GDALGetRasterBand( emptyDataset, 1 );
GDALRasterBandH poBand = GDALGetRasterBand( emptyDataset.get(), 1 );
if ( !poBand )
return false;

Expand All @@ -259,8 +258,6 @@ bool QgsKernelDensityEstimation::createEmptyLayer( GDALDriverH driver, const Qgs
}

CPLFree( line );
//close the dataset
GDALClose( emptyDataset );
return true;
}

Expand Down
12 changes: 11 additions & 1 deletion src/analysis/raster/qgskde.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#define QGSKDE_H

#include "qgsrectangle.h"
#include "qgsogrutils.h"
#include <QString>

// GDAL includes
Expand Down Expand Up @@ -100,6 +101,11 @@ class ANALYSIS_EXPORT QgsKernelDensityEstimation
*/
QgsKernelDensityEstimation( const Parameters &parameters, const QString &outputFile, const QString &outputFormat );

//! QgsKernelDensityEstimation cannot be copied.
QgsKernelDensityEstimation( const QgsKernelDensityEstimation &other ) = delete;
//! QgsKernelDensityEstimation cannot be copied.
QgsKernelDensityEstimation &operator=( const QgsKernelDensityEstimation &other ) = delete;

/**
* Runs the KDE calculation across the whole layer at once. Either call this method, or manually
* call run(), addFeature() and finalise() separately.
Expand Down Expand Up @@ -162,12 +168,16 @@ class ANALYSIS_EXPORT QgsKernelDensityEstimation

int mBufferSize;

GDALDatasetH mDatasetH;
gdal::dataset_unique_ptr mDatasetH;
GDALRasterBandH mRasterBandH;

//! Creates a new raster layer and initializes it to the no data value
bool createEmptyLayer( GDALDriverH driver, const QgsRectangle &bounds, int rows, int columns ) const;
int radiusSizeInPixels( double radius ) const;

#ifdef SIP_RUN
QgsKernelDensityEstimation( const QgsKernelDensityEstimation &other );
#endif
};


Expand Down
Loading

0 comments on commit 93f8abe

Please sign in to comment.