Skip to content
Permalink
Browse files

raster save as raw/image mode, pipe clone

  • Loading branch information
blazek committed Aug 16, 2012
1 parent ec88c9d commit ac4486a7a15ea06ecea39564a3ac4d2a4d3e3cd9
Showing with 447 additions and 30 deletions.
  1. +1 −0 python/core/core.sip
  2. +3 −0 python/core/qgsrasterdataprovider.sip
  3. +73 −0 python/core/qgsrasterinterface.sip
  4. +6 −0 python/core/qgsrasterrenderer.sip
  5. +3 −0 python/core/qgsrasterresampler.sip
  6. +47 −8 src/app/qgisapp.cpp
  7. +1 −1 src/core/qgsrasterdataprovider.h
  8. +10 −2 src/core/qgsrasterprojector.cpp
  9. +2 −0 src/core/qgsrasterprojector.h
  10. +5 −0 src/core/raster/qgsbilinearrasterresampler.cpp
  11. +1 −0 src/core/raster/qgsbilinearrasterresampler.h
  12. +29 −0 src/core/raster/qgscontrastenhancement.cpp
  13. +1 −0 src/core/raster/qgscontrastenhancement.h
  14. +7 −0 src/core/raster/qgscontrastenhancementfunction.cpp
  15. +1 −0 src/core/raster/qgscontrastenhancementfunction.h
  16. +5 −0 src/core/raster/qgscubicrasterresampler.cpp
  17. +1 −0 src/core/raster/qgscubicrasterresampler.h
  18. +18 −0 src/core/raster/qgsmultibandcolorrenderer.cpp
  19. +1 −0 src/core/raster/qgsmultibandcolorrenderer.h
  20. +6 −0 src/core/raster/qgspalettedrasterrenderer.cpp
  21. +1 −0 src/core/raster/qgspalettedrasterrenderer.h
  22. +24 −6 src/core/raster/qgsrasterfilewriter.cpp
  23. +1 −0 src/core/raster/qgsrasterfilewriter.h
  24. +5 −1 src/core/raster/qgsrasterinterface.h
  25. +21 −0 src/core/raster/qgsrasterpipe.cpp
  26. +4 −3 src/core/raster/qgsrasterpipe.h
  27. +2 −0 src/core/raster/qgsrasterrenderer.h
  28. +16 −0 src/core/raster/qgsrasterresamplefilter.cpp
  29. +2 −0 src/core/raster/qgsrasterresamplefilter.h
  30. +1 −0 src/core/raster/qgsrasterresampler.h
  31. +6 −0 src/core/raster/qgssinglebandcolordatarenderer.cpp
  32. +1 −0 src/core/raster/qgssinglebandcolordatarenderer.h
  33. +10 −0 src/core/raster/qgssinglebandgrayrenderer.cpp
  34. +1 −0 src/core/raster/qgssinglebandgrayrenderer.h
  35. +11 −0 src/core/raster/qgssinglebandpseudocolorrenderer.cpp
  36. +1 −0 src/core/raster/qgssinglebandpseudocolorrenderer.h
  37. +23 −9 src/gui/qgsrasterlayersaveasdialog.cpp
  38. +6 −0 src/gui/qgsrasterlayersaveasdialog.h
  39. +7 −0 src/providers/gdal/qgsgdalprovider.cpp
  40. +2 −0 src/providers/gdal/qgsgdalprovider.h
  41. +6 −0 src/providers/grass/qgsgrassrasterprovider.cpp
  42. +2 −0 src/providers/grass/qgsgrassrasterprovider.h
  43. +6 −0 src/providers/wcs/qgswcsprovider.cpp
  44. +2 −0 src/providers/wcs/qgswcsprovider.h
  45. +10 −0 src/providers/wms/qgswmsprovider.cpp
  46. +2 −0 src/providers/wms/qgswmsprovider.h
  47. +53 −0 src/ui/qgsrasterlayersaveasdialogbase.ui
@@ -63,6 +63,7 @@
%Include qgsproviderregistry.sip
%Include qgsrasterbandstats.sip
%Include qgsrasterdataprovider.sip
%Include qgsrasterinterface.sip
%Include qgsrasterlayer.sip
%Include qgsrasterpyramid.sip
%Include qgsrasterrenderer.sip
@@ -10,6 +10,7 @@ class QgsRasterDataProvider : QgsDataProvider
{
%TypeHeaderCode
#include <qgsrasterdataprovider.h>
#include <qgsrasterinterface.h>
%End

public:
@@ -29,6 +30,8 @@ class QgsRasterDataProvider : QgsDataProvider

virtual ~QgsRasterDataProvider();

virtual QgsRasterInterface * clone() const = 0;

/**
* Add the list of WMS layer names to be rendered by this server
*/
@@ -0,0 +1,73 @@

/** Base class for processing modules.
*
*/

class QgsRasterInterface
{
%TypeHeaderCode
#include <qgsrasterinterface.h>
%End
public:

enum DataType
{
/*! Unknown or unspecified type */ UnknownDataType = 0,
/*! Eight bit unsigned integer */ Byte = 1,
/*! Sixteen bit unsigned integer */ UInt16 = 2,
/*! Sixteen bit signed integer */ Int16 = 3,
/*! Thirty two bit unsigned integer */ UInt32 = 4,
/*! Thirty two bit signed integer */ Int32 = 5,
/*! Thirty two bit floating point */ Float32 = 6,
/*! Sixty four bit floating point */ Float64 = 7,
/*! Complex Int16 */ CInt16 = 8,
/*! Complex Int32 */ CInt32 = 9,
/*! Complex Float32 */ CFloat32 = 10,
/*! Complex Float64 */ CFloat64 = 11,
/*! Color, alpha, red, green, blue, 4 bytes the same as
QImage::Format_ARGB32 */ ARGB32 = 12,
/*! Color, alpha, red, green, blue, 4 bytes the same as
QImage::Format_ARGB32_Premultiplied */ ARGB32_Premultiplied = 13,

TypeCount = 14 /* maximum type # + 1 */
};

QgsRasterInterface( QgsRasterInterface * input = 0 );

virtual ~QgsRasterInterface();

int typeSize( int dataType ) const;

virtual QgsRasterInterface *clone() const = 0;

int dataTypeSize( int bandNo ) const;

bool typeIsNumeric( DataType type ) const;

bool typeIsColor( DataType type ) const;

virtual DataType dataType( int bandNo ) const;

virtual int bandCount() const;

virtual double noDataValue() const;

//void * block( int bandNo, QgsRectangle const & extent, int width, int height );

//virtual void * readBlock( int bandNo, QgsRectangle const & extent, int width, int height );

virtual bool setInput( QgsRasterInterface* input );

virtual bool on( );

virtual void setOn( bool on );

virtual QgsRasterInterface * srcInput();

QImage * createImage( int width, int height, QImage::Format format );

void setStatsOn( bool on );

double time( bool cumulative = false );
};

@@ -27,6 +27,7 @@ class QgsRasterRenderer
public:
QgsRasterRenderer( QgsRasterDataProvider* provider, const QString& type );
virtual ~QgsRasterRenderer();
virtual QgsRasterInterface * clone() const = 0;

virtual QString type() const;
virtual void * readBlock( int bandNo, const QgsRectangle & extent, int width, int height );
@@ -63,6 +64,7 @@ class QgsPalettedRasterRenderer: QgsRasterRenderer
/**Renderer owns color array*/
QgsPalettedRasterRenderer( QgsRasterDataProvider* provider, int bandNumber, QColor* colorArray, int nColors );
~QgsPalettedRasterRenderer();
QgsRasterInterface * clone();
static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

void * readBlock( int bandNo, const QgsRectangle & extent, int width, int height );
@@ -87,6 +89,7 @@ class QgsMultiBandColorRenderer: QgsRasterRenderer
QgsContrastEnhancement* redEnhancement = 0, QgsContrastEnhancement* greenEnhancement = 0,
QgsContrastEnhancement* blueEnhancement = 0 );
~QgsMultiBandColorRenderer();
QgsRasterInterface * clone();

static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

@@ -123,6 +126,7 @@ class QgsSingleBandPseudoColorRenderer: QgsRasterRenderer
/**Note: takes ownership of QgsRasterShader*/
QgsSingleBandPseudoColorRenderer( QgsRasterDataProvider* provider, int band, QgsRasterShader* shader );
~QgsSingleBandPseudoColorRenderer();
QgsRasterInterface * clone();

static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

@@ -145,6 +149,7 @@ class QgsSingleBandGrayRenderer: QgsRasterRenderer
public:
QgsSingleBandGrayRenderer( QgsRasterDataProvider* provider, int grayBand );
~QgsSingleBandGrayRenderer();
QgsRasterInterface * clone();

static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

@@ -169,6 +174,7 @@ class QgsSingleBandColorDataRenderer: QgsRasterRenderer
public:
QgsSingleBandColorDataRenderer( QgsRasterDataProvider* provider, int band );
~QgsSingleBandColorDataRenderer();
QgsRasterInterface * clone();

static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider );

@@ -19,6 +19,7 @@ class QgsRasterResampler
public:
virtual void resample( const QImage& srcImage, QImage& dstImage ) = 0;
virtual QString type() const = 0;
virtual QgsRasterResampler * clone() const = 0;
};

class QgsBilinearRasterResampler: QgsRasterResampler
@@ -32,6 +33,7 @@ class QgsBilinearRasterResampler: QgsRasterResampler

void resample( const QImage& srcImage, QImage& dstImage );
QString type() const;
QgsRasterResampler * clone() const;
};

class QgsCubicRasterResampler: QgsRasterResampler
@@ -44,4 +46,5 @@ class QgsCubicRasterResampler: QgsRasterResampler
~QgsCubicRasterResampler();
void resample( const QImage& srcImage, QImage& dstImage );
QString type() const;
QgsRasterResampler * clone() const;
};
@@ -3937,20 +3937,59 @@ void QgisApp::saveAsRasterFile()

QProgressDialog pd( 0, tr( "Abort..." ), 0, 0 );
pd.setWindowModality( Qt::WindowModal );
QgsRasterDataProvider* provider = rasterLayer->dataProvider();
if ( !provider )

// TODO: show error dialogs
// TODO: this code should go somewhere else, but probably not into QgsRasterFileWriter
// clone pipe/provider is not really necessary, ready for threads
QgsRasterPipe* pipe = 0;

if ( d.mode() == QgsRasterLayerSaveAsDialog::RawDataMode )
{
return;
QgsDebugMsg( "Writing raw data" );
//QgsDebugMsg( QString( "Writing raw data" ).arg( pos ) );
pipe = new QgsRasterPipe();
if ( !pipe->set( rasterLayer->dataProvider()->clone() ) )
{
QgsDebugMsg( "Cannot set pipe provider" );
return;
}
// add projector if necessary
if ( d.outputCrs() != rasterLayer->dataProvider()->crs() )
{
QgsRasterProjector * projector = new QgsRasterProjector;
projector->setCRS( rasterLayer->dataProvider()->crs(), d.outputCrs() );
if ( !pipe->set( projector ) )
{
QgsDebugMsg( "Cannot set pipe projector" );
return;
}
}
}
else // RenderedImageMode
{
// clone the whole pipe
QgsDebugMsg( "Writing rendered image" );
pipe = new QgsRasterPipe( *rasterLayer->pipe() );
QgsRasterProjector *projector = pipe->projector();
if ( !projector )
{
QgsDebugMsg( "Cannot get pipe projector" );
delete pipe;
return;
}
projector->setCRS( rasterLayer->dataProvider()->crs(), d.outputCrs() );
}
QgsRasterIterator iterator( provider );
int nRows = -1; //calculate number of rows such that pixels are squares
if ( provider->capabilities() & QgsRasterDataProvider::ExactResolution )

if ( !pipe->last() )
{
nRows = d.nRows();
delete pipe;
return;
}
QgsRasterIterator iterator( pipe->last() );
fileWriter.setCreateOptions( d.createOptions() );

fileWriter.writeRaster( &iterator, d.nColumns(), nRows, d.outputRectangle(), d.outputCrs(), &pd );
fileWriter.writeRaster( &iterator, d.nColumns(), d.nRows(), d.outputRectangle(), d.outputCrs(), &pd );
delete pipe;
}
}

@@ -108,7 +108,7 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast

virtual ~QgsRasterDataProvider() {};

QgsRasterInterface * srcInput() { return this; }
virtual QgsRasterInterface * clone() const = 0;

/* It makes no sense to set input on provider */
bool setInput( QgsRasterInterface* input ) { Q_UNUSED( input ); return false; }
@@ -66,6 +66,13 @@ QgsRasterProjector::QgsRasterProjector()
QgsDebugMsg( "Entered" );
}

QgsRasterInterface * QgsRasterProjector::clone() const
{
QgsDebugMsg( "Entered" );
QgsRasterProjector * projector = new QgsRasterProjector( mSrcCRS, mDestCRS, mMaxSrcXRes, mMaxSrcYRes, mExtent );
return projector;
}

QgsRasterProjector::~QgsRasterProjector()
{
delete[] pHelperTop;
@@ -104,6 +111,8 @@ void QgsRasterProjector::calc()
pHelperBottom = 0;

// Get max source resolution if possible
mMaxSrcXRes = 0;
mMaxSrcYRes = 0;
if ( mInput )
{
QgsRasterDataProvider *provider = dynamic_cast<QgsRasterDataProvider*>( mInput->srcInput() );
@@ -622,8 +631,7 @@ void * QgsRasterProjector::readBlock( int bandNo, QgsRectangle const & extent,

if ( !inputData ) return 0;

// ARGB32 only for now
int pixelSize = 4;
int pixelSize = mInput->typeSize( mInput->dataType( bandNo ) ) / 8;

int inputSize = pixelSize * srcCols() * srcRows();

@@ -61,6 +61,8 @@ class CORE_EXPORT QgsRasterProjector : public QgsRasterInterface
/** \brief The destructor */
~QgsRasterProjector();

QgsRasterInterface * clone() const;

int bandCount() const;

QgsRasterInterface::DataType dataType( int bandNo ) const;
@@ -27,6 +27,11 @@ QgsBilinearRasterResampler::~QgsBilinearRasterResampler()
{
}

QgsRasterResampler * QgsBilinearRasterResampler::clone() const
{
return new QgsBilinearRasterResampler();
}

void QgsBilinearRasterResampler::resample( const QImage& srcImage, QImage& dstImage )
{
dstImage = srcImage.scaled( dstImage.width(), dstImage.height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
@@ -29,6 +29,7 @@ class CORE_EXPORT QgsBilinearRasterResampler: public QgsRasterResampler

void resample( const QImage& srcImage, QImage& dstImage );
QString type() const { return "bilinear"; }
QgsRasterResampler * clone() const;
};

#endif // QGSBILINEARRASTERRESAMPLER_H
@@ -52,6 +52,35 @@ QgsContrastEnhancement::QgsContrastEnhancement( QgsRasterDataType theDataType )

}

QgsContrastEnhancement::QgsContrastEnhancement( const QgsContrastEnhancement& ce )
{
mLookupTable = 0;
mEnhancementDirty = ce.mEnhancementDirty;
mContrastEnhancementAlgorithm = ce.mContrastEnhancementAlgorithm;
mRasterDataType = ce.mRasterDataType;

mMinimumValue = ce.mMinimumValue;
mMaximumValue = ce.mMaximumValue;
mRasterDataTypeRange = ce.mRasterDataTypeRange;

mLookupTableOffset = ce.mLookupTableOffset;

mContrastEnhancementFunction = new QgsContrastEnhancementFunction( mRasterDataType, mMinimumValue, mMaximumValue );

//If the data type is larger than 16-bit do not generate a lookup table
if ( mRasterDataTypeRange <= 65535.0 )
{
mLookupTable = new int[static_cast <int>( mRasterDataTypeRange+1 )];
if ( !ce.mEnhancementDirty )
{
for ( int myIterator = 0; myIterator <= mRasterDataTypeRange; myIterator++ )
{
mLookupTable[myIterator] = ce.mLookupTable[myIterator];
}
}
}
}

QgsContrastEnhancement::~QgsContrastEnhancement()
{
}
@@ -73,6 +73,7 @@ class CORE_EXPORT QgsContrastEnhancement
};

QgsContrastEnhancement( QgsContrastEnhancement::QgsRasterDataType theDatatype = QGS_Byte );
QgsContrastEnhancement( const QgsContrastEnhancement& ce );
~QgsContrastEnhancement();

/*
@@ -26,6 +26,13 @@ QgsContrastEnhancementFunction::QgsContrastEnhancementFunction( QgsContrastEnhan
mMinimumMaximumRange = mMaximumValue - mMinimumValue;
}

QgsContrastEnhancementFunction::QgsContrastEnhancementFunction( const QgsContrastEnhancementFunction& f )
{
mQgsRasterDataType = f.mQgsRasterDataType;
mMaximumValue = f.mMaximumValue;
mMinimumValue = f.mMinimumValue;
mMinimumMaximumRange = f.mMinimumMaximumRange;
}

int QgsContrastEnhancementFunction::enhance( double theValue )
{
@@ -32,6 +32,7 @@ class CORE_EXPORT QgsContrastEnhancementFunction

public:
QgsContrastEnhancementFunction( QgsContrastEnhancement::QgsRasterDataType, double, double );
QgsContrastEnhancementFunction( const QgsContrastEnhancementFunction& f );
virtual ~QgsContrastEnhancementFunction() {}

/** \brief A customizable method that takes in a double and returns a int between 0 and 255 */
@@ -27,6 +27,11 @@ QgsCubicRasterResampler::~QgsCubicRasterResampler()
{
}

QgsRasterResampler * QgsCubicRasterResampler::clone() const
{
return new QgsCubicRasterResampler();
}

void QgsCubicRasterResampler::resample( const QImage& srcImage, QImage& dstImage )
{
int nCols = srcImage.width();
@@ -26,6 +26,7 @@ class CORE_EXPORT QgsCubicRasterResampler: public QgsRasterResampler
public:
QgsCubicRasterResampler();
~QgsCubicRasterResampler();
QgsRasterResampler * clone() const;
void resample( const QImage& srcImage, QImage& dstImage );
QString type() const { return "cubic"; }

0 comments on commit ac4486a

Please sign in to comment.
You can’t perform that action at this time.