| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| /*************************************************************************** | ||
| qgsbilinearrasterresampler.cpp | ||
| ------------------------------ | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #include "qgsbilinearrasterresampler.h" | ||
| #include <QImage> | ||
| #include <cmath> | ||
|
|
||
| QgsBilinearRasterResampler::QgsBilinearRasterResampler() | ||
| { | ||
| } | ||
|
|
||
| QgsBilinearRasterResampler::~QgsBilinearRasterResampler() | ||
| { | ||
| } | ||
|
|
||
| void QgsBilinearRasterResampler::resample( const QImage& srcImage, QImage& dstImage ) | ||
| { | ||
| dstImage = srcImage.scaled( dstImage.width(), dstImage.height(), Qt::KeepAspectRatio, Qt::SmoothTransformation ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| /*************************************************************************** | ||
| qgsbilinearrasterresampler.h | ||
| ---------------------------- | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSBILINEARRASTERRESAMPLER_H | ||
| #define QGSBILINEARRASTERRESAMPLER_H | ||
|
|
||
| #include "qgsrasterresampler.h" | ||
| #include <QColor> | ||
|
|
||
| class QgsBilinearRasterResampler: public QgsRasterResampler | ||
| { | ||
| public: | ||
| QgsBilinearRasterResampler(); | ||
| ~QgsBilinearRasterResampler(); | ||
|
|
||
| void resample( const QImage& srcImage, QImage& dstImage ); | ||
| QString type() const { return "bilinear"; } | ||
| }; | ||
|
|
||
| #endif // QGSBILINEARRASTERRESAMPLER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| /*************************************************************************** | ||
| qgscubicrasterresampler.h | ||
| ---------------------------- | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSCUBICRASTERRESAMPLER_H | ||
| #define QGSCUBICRASTERRESAMPLER_H | ||
|
|
||
| #include "qgsrasterresampler.h" | ||
| #include <QColor> | ||
|
|
||
| class QgsCubicRasterResampler: public QgsRasterResampler | ||
| { | ||
| public: | ||
| QgsCubicRasterResampler(); | ||
| ~QgsCubicRasterResampler(); | ||
| void resample( const QImage& srcImage, QImage& dstImage ); | ||
| QString type() const { return "cubic"; } | ||
|
|
||
| private: | ||
| static void xDerivativeMatrix( int nCols, int nRows, double* matrix, const int* colorMatrix ); | ||
| static void yDerivativeMatrix( int nCols, int nRows, double* matrix, const int* colorMatrix ); | ||
|
|
||
| void calculateControlPoints( int nCols, int nRows, int currentRow, int currentCol, int* redMatrix, int* greenMatrix, int* blueMatrix, | ||
| int* alphaMatrix, double* xDerivativeMatrixRed, double* xDerivativeMatrixGreen, double* xDerivativeMatrixBlue, | ||
| double* xDerivativeMatrixAlpha, double* yDerivativeMatrixRed, double* yDerivativeMatrixGreen, double* yDerivativeMatrixBlue, | ||
| double* yDerivativeMatrixAlpha ); | ||
|
|
||
| /**Use cubic curve interpoation at the borders of the raster*/ | ||
| QRgb curveInterpolation( QRgb pt1, QRgb pt2, double t, double d1red, double d1green, double d1blue, double d1alpha, double d2red, double d2green, | ||
| double d2blue, double d2alpha ); | ||
|
|
||
| static double calcBernsteinPoly( int n, int i, double t ); | ||
| static int lower( int n, int i ); | ||
| static double power( double a, int b );//calculates a power b | ||
| static int faculty( int n ); | ||
|
|
||
| //control points | ||
|
|
||
| //red | ||
| double cRed00; double cRed10; double cRed20; double cRed30; double cRed01; double cRed11; double cRed21; double cRed31; | ||
| double cRed02; double cRed12; double cRed22; double cRed32; double cRed03; double cRed13; double cRed23; double cRed33; | ||
| //green | ||
| double cGreen00; double cGreen10; double cGreen20; double cGreen30; double cGreen01; double cGreen11; double cGreen21; double cGreen31; | ||
| double cGreen02; double cGreen12; double cGreen22; double cGreen32; double cGreen03; double cGreen13; double cGreen23; double cGreen33; | ||
| //blue | ||
| double cBlue00; double cBlue10; double cBlue20; double cBlue30; double cBlue01; double cBlue11; double cBlue21; double cBlue31; | ||
| double cBlue02; double cBlue12; double cBlue22; double cBlue32; double cBlue03; double cBlue13; double cBlue23; double cBlue33; | ||
| //alpha | ||
| double cAlpha00; double cAlpha10; double cAlpha20; double cAlpha30; double cAlpha01; double cAlpha11; double cAlpha21; double cAlpha31; | ||
| double cAlpha02; double cAlpha12; double cAlpha22; double cAlpha32; double cAlpha03; double cAlpha13; double cAlpha23; double cAlpha33; | ||
| }; | ||
|
|
||
| #endif // QGSCUBICRASTERRESAMPLER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,353 @@ | ||
| /*************************************************************************** | ||
| qgsmultibandcolorrenderer.cpp | ||
| ----------------------------- | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #include "qgsmultibandcolorrenderer.h" | ||
| #include "qgscontrastenhancement.h" | ||
| #include "qgsrastertransparency.h" | ||
| #include "qgsrasterviewport.h" | ||
| #include <QDomDocument> | ||
| #include <QDomElement> | ||
| #include <QImage> | ||
| #include <QSet> | ||
|
|
||
| QgsMultiBandColorRenderer::QgsMultiBandColorRenderer( QgsRasterDataProvider* provider, int redBand, int greenBand, int blueBand, | ||
| QgsContrastEnhancement* redEnhancement, | ||
| QgsContrastEnhancement* greenEnhancement, | ||
| QgsContrastEnhancement* blueEnhancement ): | ||
| QgsRasterRenderer( provider, "multibandcolor" ), mRedBand( redBand ), mGreenBand( greenBand ), mBlueBand( blueBand ), | ||
| mRedContrastEnhancement( redEnhancement ), mGreenContrastEnhancement( greenEnhancement ), mBlueContrastEnhancement( blueEnhancement ) | ||
| { | ||
| } | ||
|
|
||
| QgsMultiBandColorRenderer::~QgsMultiBandColorRenderer() | ||
| { | ||
| delete mRedContrastEnhancement; | ||
| delete mGreenContrastEnhancement; | ||
| delete mBlueContrastEnhancement; | ||
| } | ||
|
|
||
| void QgsMultiBandColorRenderer::setRedContrastEnhancement( QgsContrastEnhancement* ce ) | ||
| { | ||
| delete mRedContrastEnhancement; mRedContrastEnhancement = ce; | ||
| } | ||
|
|
||
| void QgsMultiBandColorRenderer::setGreenContrastEnhancement( QgsContrastEnhancement* ce ) | ||
| { | ||
| delete mGreenContrastEnhancement; mGreenContrastEnhancement = ce; | ||
| } | ||
|
|
||
| void QgsMultiBandColorRenderer::setBlueContrastEnhancement( QgsContrastEnhancement* ce ) | ||
| { | ||
| delete mBlueContrastEnhancement; mBlueContrastEnhancement = ce; | ||
| } | ||
|
|
||
| QgsRasterRenderer* QgsMultiBandColorRenderer::create( const QDomElement& elem, QgsRasterDataProvider* provider ) | ||
| { | ||
| if ( elem.isNull() ) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| //red band, green band, blue band | ||
| int redBand = elem.attribute( "redBand", "-1" ).toInt(); | ||
| int greenBand = elem.attribute( "greenBand", "-1" ).toInt(); | ||
| int blueBand = elem.attribute( "blueBand", "-1" ).toInt(); | ||
|
|
||
| //contrast enhancements | ||
| QgsContrastEnhancement* redContrastEnhancement = 0; | ||
| QDomElement redContrastElem = elem.firstChildElement( "redContrastEnhancement" ); | ||
| if ( !redContrastElem.isNull() ) | ||
| { | ||
| redContrastEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )( | ||
| provider->dataType( redBand ) ) ); | ||
| redContrastEnhancement->readXML( redContrastElem ); | ||
| } | ||
|
|
||
| QgsContrastEnhancement* greenContrastEnhancement = 0; | ||
| QDomElement greenContrastElem = elem.firstChildElement( "greenContrastEnhancement" ); | ||
| if ( !greenContrastElem.isNull() ) | ||
| { | ||
| greenContrastEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )( | ||
| provider->dataType( greenBand ) ) ); | ||
| greenContrastEnhancement->readXML( greenContrastElem ); | ||
| } | ||
|
|
||
| QgsContrastEnhancement* blueContrastEnhancement = 0; | ||
| QDomElement blueContrastElem = elem.firstChildElement( "blueContrastEnhancement" ); | ||
| if ( !blueContrastElem.isNull() ) | ||
| { | ||
| blueContrastEnhancement = new QgsContrastEnhancement(( QgsContrastEnhancement::QgsRasterDataType )( | ||
| provider->dataType( blueBand ) ) ); | ||
| blueContrastEnhancement->readXML( blueContrastElem ); | ||
| } | ||
|
|
||
| QgsRasterRenderer* r = new QgsMultiBandColorRenderer( provider, redBand, greenBand, blueBand, redContrastEnhancement, | ||
| greenContrastEnhancement, blueContrastEnhancement ); | ||
| r->readXML( elem ); | ||
| return r; | ||
| } | ||
|
|
||
| void QgsMultiBandColorRenderer::draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel ) | ||
| { | ||
| if ( !p || !mProvider || !viewPort || !theQgsMapToPixel ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| //In some (common) cases, we can simplify the drawing loop considerably and save render time | ||
| bool fastDraw = ( | ||
| !usesTransparency( viewPort->mSrcCRS, viewPort->mDestCRS ) | ||
| && mRedBand > 0 && mGreenBand > 0 && mBlueBand > 0 | ||
| && mAlphaBand < 1 && !mRedContrastEnhancement && !mGreenContrastEnhancement && !mBlueContrastEnhancement | ||
| && !mInvertColor ); | ||
|
|
||
| QgsRasterDataProvider::DataType redType; | ||
| if ( mRedBand > 0 ) | ||
| { | ||
| redType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mRedBand ); | ||
| } | ||
| QgsRasterDataProvider::DataType greenType; | ||
| if ( mGreenBand > 0 ) | ||
| { | ||
| greenType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mGreenBand ); | ||
| } | ||
| QgsRasterDataProvider::DataType blueType; | ||
| if ( mBlueBand > 0 ) | ||
| { | ||
| blueType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mBlueBand ); | ||
| } | ||
| QgsRasterDataProvider::DataType transparencyType = QgsRasterDataProvider::UnknownDataType; | ||
| if ( mAlphaBand > 0 ) | ||
| { | ||
| transparencyType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mAlphaBand ); | ||
| } | ||
|
|
||
| double oversamplingX, oversamplingY; | ||
| QSet<int> bands; | ||
| if ( mRedBand > 0 ) | ||
| { | ||
| bands << mRedBand; | ||
| } | ||
| if ( mGreenBand > 0 ) | ||
| { | ||
| bands << mGreenBand; | ||
| } | ||
| if ( mBlueBand > 0 ) | ||
| { | ||
| bands << mBlueBand; | ||
| } | ||
| if ( bands.size() < 1 ) | ||
| { | ||
| return; //no need to draw anything if no band is set | ||
| } | ||
|
|
||
| if ( mAlphaBand > 0 ) | ||
| { | ||
| bands << mAlphaBand; | ||
| } | ||
|
|
||
| QMap<int, void*> bandData; | ||
| void* defaultPointer = 0; | ||
| QSet<int>::const_iterator bandIt = bands.constBegin(); | ||
| for ( ; bandIt != bands.constEnd(); ++bandIt ) | ||
| { | ||
| bandData.insert( *bandIt, defaultPointer ); | ||
| startRasterRead( *bandIt, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY ); | ||
| } | ||
|
|
||
| void* redData = 0; | ||
| void* greenData = 0; | ||
| void* blueData = 0; | ||
| void* alphaData = 0; | ||
| //number of cols/rows in output pixels | ||
| int nCols = 0; | ||
| int nRows = 0; | ||
| //number of raster cols/rows with oversampling | ||
| int nRasterCols = 0; | ||
| int nRasterRows = 0; | ||
| //shift to top left point for the raster part | ||
| int topLeftCol = 0; | ||
| int topLeftRow = 0; | ||
|
|
||
| bool readSuccess = true; | ||
| while ( true ) | ||
| { | ||
| QSet<int>::const_iterator bandIt = bands.constBegin(); | ||
| for ( ; bandIt != bands.constEnd(); ++bandIt ) | ||
| { | ||
| readSuccess = readSuccess && readNextRasterPart( *bandIt, oversamplingX, oversamplingY, viewPort, nCols, nRows, | ||
| nRasterCols, nRasterRows, &bandData[*bandIt], topLeftCol, topLeftRow ); | ||
| } | ||
|
|
||
| if ( !readSuccess ) | ||
| { | ||
| break; | ||
| } | ||
|
|
||
| if ( mRedBand > 0 ) | ||
| { | ||
| redData = bandData[mRedBand]; | ||
| } | ||
| if ( mGreenBand > 0 ) | ||
| { | ||
| greenData = bandData[mGreenBand]; | ||
| } | ||
| if ( mBlueBand > 0 ) | ||
| { | ||
| blueData = bandData[mBlueBand]; | ||
| } | ||
| if ( mAlphaBand > 0 ) | ||
| { | ||
| alphaData = bandData[mAlphaBand]; | ||
| } | ||
|
|
||
| QImage img( nRasterCols, nRasterRows, QImage::Format_ARGB32_Premultiplied ); | ||
| QRgb* imageScanLine = 0; | ||
| int currentRasterPos = 0; | ||
| int redVal = 0; | ||
| int greenVal = 0; | ||
| int blueVal = 0; | ||
| QRgb defaultColor = qRgba( 255, 255, 255, 0 ); | ||
| double currentOpacity = mOpacity; //opacity (between 0 and 1) | ||
|
|
||
| for ( int i = 0; i < nRasterRows; ++i ) | ||
| { | ||
| imageScanLine = ( QRgb* )( img.scanLine( i ) ); | ||
| for ( int j = 0; j < nRasterCols; ++j ) | ||
| { | ||
|
|
||
| if ( fastDraw ) //fast rendering if no transparency, stretching, color inversion, etc. | ||
| { | ||
| redVal = readValue( redData, redType, currentRasterPos ); | ||
| greenVal = readValue( greenData, greenType, currentRasterPos ); | ||
| blueVal = readValue( blueData, blueType, currentRasterPos ); | ||
| imageScanLine[j] = qRgba( redVal, greenVal, blueVal, 255 ); | ||
| ++currentRasterPos; | ||
| continue; | ||
| } | ||
|
|
||
| if ( mRedBand > 0 ) | ||
| { | ||
| redVal = readValue( redData, redType, currentRasterPos ); | ||
| } | ||
| if ( mGreenBand > 0 ) | ||
| { | ||
| greenVal = readValue( greenData, greenType, currentRasterPos ); | ||
| } | ||
| if ( mBlueBand > 0 ) | ||
| { | ||
| blueVal = readValue( blueData, blueType, currentRasterPos ); | ||
| } | ||
|
|
||
| //apply default color if red, green or blue not in displayable range | ||
| if (( mRedContrastEnhancement && !mRedContrastEnhancement->isValueInDisplayableRange( redVal ) ) | ||
| || ( mGreenContrastEnhancement && !mGreenContrastEnhancement->isValueInDisplayableRange( redVal ) ) | ||
| || ( mBlueContrastEnhancement && !mBlueContrastEnhancement->isValueInDisplayableRange( redVal ) ) ) | ||
| { | ||
| imageScanLine[j] = defaultColor; | ||
| ++currentRasterPos; | ||
| continue; | ||
| } | ||
|
|
||
| //stretch color values | ||
| if ( mRedContrastEnhancement ) | ||
| { | ||
| redVal = mRedContrastEnhancement->enhanceContrast( redVal ); | ||
| } | ||
| if ( mGreenContrastEnhancement ) | ||
| { | ||
| greenVal = mGreenContrastEnhancement->enhanceContrast( greenVal ); | ||
| } | ||
| if ( mBlueContrastEnhancement ) | ||
| { | ||
| blueVal = mBlueContrastEnhancement->enhanceContrast( blueVal ); | ||
| } | ||
|
|
||
| if ( mInvertColor ) | ||
| { | ||
| redVal = 255 - redVal; | ||
| greenVal = 255 - greenVal; | ||
| blueVal = 255 - blueVal; | ||
| } | ||
|
|
||
| //opacity | ||
| currentOpacity = mOpacity; | ||
| if ( mRasterTransparency ) | ||
| { | ||
| currentOpacity = mRasterTransparency->alphaValue( redVal, greenVal, blueVal, mOpacity * 255 ) / 255.0; | ||
| } | ||
| if ( mAlphaBand > 0 ) | ||
| { | ||
| currentOpacity *= ( readValue( alphaData, transparencyType, currentRasterPos ) / 255.0 ); | ||
| } | ||
|
|
||
| if ( doubleNear( currentOpacity, 255 ) ) | ||
| { | ||
| imageScanLine[j] = qRgba( redVal, greenVal, blueVal, 255 ); | ||
| } | ||
| else | ||
| { | ||
| imageScanLine[j] = qRgba( currentOpacity * redVal, currentOpacity * greenVal, currentOpacity * blueVal, currentOpacity * 255 ); | ||
| } | ||
| ++currentRasterPos; | ||
| } | ||
| } | ||
|
|
||
| drawImage( p, viewPort, img, topLeftCol, topLeftRow, nCols, nRows, oversamplingX, oversamplingY ); | ||
| } | ||
|
|
||
| bandIt = bands.constBegin(); | ||
| for ( ; bandIt != bands.constEnd(); ++bandIt ) | ||
| { | ||
| stopRasterRead( *bandIt ); | ||
| } | ||
| } | ||
|
|
||
| void QgsMultiBandColorRenderer::writeXML( QDomDocument& doc, QDomElement& parentElem ) const | ||
| { | ||
| if ( parentElem.isNull() ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| QDomElement rasterRendererElem = doc.createElement( "rasterrenderer" ); | ||
| _writeXML( doc, rasterRendererElem ); | ||
| rasterRendererElem.setAttribute( "redBand", mRedBand ); | ||
| rasterRendererElem.setAttribute( "greenBand", mGreenBand ); | ||
| rasterRendererElem.setAttribute( "blueBand", mBlueBand ); | ||
|
|
||
| //contrast enhancement | ||
| if ( mRedContrastEnhancement ) | ||
| { | ||
| QDomElement redContrastElem = doc.createElement( "redContrastEnhancement" ); | ||
| mRedContrastEnhancement->writeXML( doc, redContrastElem ); | ||
| rasterRendererElem.appendChild( redContrastElem ); | ||
| } | ||
| if ( mGreenContrastEnhancement ) | ||
| { | ||
| QDomElement greenContrastElem = doc.createElement( "greenContrastEnhancement" ); | ||
| mGreenContrastEnhancement->writeXML( doc, greenContrastElem ); | ||
| rasterRendererElem.appendChild( greenContrastElem ); | ||
| } | ||
| if ( mBlueContrastEnhancement ) | ||
| { | ||
| QDomElement blueContrastElem = doc.createElement( "blueContrastEnhancement" ); | ||
| mBlueContrastEnhancement->writeXML( doc, blueContrastElem ); | ||
| rasterRendererElem.appendChild( blueContrastElem ); | ||
| } | ||
| parentElem.appendChild( rasterRendererElem ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| /*************************************************************************** | ||
| qgsmultibandcolorrenderer.h | ||
| --------------------------- | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSMULTIBANDCOLORRENDERER_H | ||
| #define QGSMULTIBANDCOLORRENDERER_H | ||
|
|
||
| #include "qgsrasterrenderer.h" | ||
|
|
||
| class QgsContrastEnhancement; | ||
| class QDomElement; | ||
|
|
||
| /**Renderer for multiband images with the color components*/ | ||
| class QgsMultiBandColorRenderer: public QgsRasterRenderer | ||
| { | ||
| public: | ||
| QgsMultiBandColorRenderer( QgsRasterDataProvider* provider, int redBand, int greenBand, int blueBand, | ||
| QgsContrastEnhancement* redEnhancement = 0, QgsContrastEnhancement* greenEnhancement = 0, | ||
| QgsContrastEnhancement* blueEnhancement = 0 ); | ||
| ~QgsMultiBandColorRenderer(); | ||
|
|
||
| static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider ); | ||
|
|
||
| void draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel ); | ||
|
|
||
| int redBand() const { return mRedBand; } | ||
| void setRedBand( int band ) { mRedBand = band; } | ||
| int greenBand() const { return mGreenBand; } | ||
| void setGreenBand( int band ) { mGreenBand = band; } | ||
| int blueBand() const { return mBlueBand; } | ||
| void setBlueBand( int band ) { mBlueBand = band; } | ||
|
|
||
| const QgsContrastEnhancement* redContrastEnhancement() const { return mRedContrastEnhancement; } | ||
| /**Takes ownership*/ | ||
| void setRedContrastEnhancement( QgsContrastEnhancement* ce ); | ||
|
|
||
| const QgsContrastEnhancement* greenContrastEnhancement() const { return mGreenContrastEnhancement; } | ||
| /**Takes ownership*/ | ||
| void setGreenContrastEnhancement( QgsContrastEnhancement* ce ); | ||
|
|
||
| const QgsContrastEnhancement* blueContrastEnhancement() const { return mBlueContrastEnhancement; } | ||
| /**Takes ownership*/ | ||
| void setBlueContrastEnhancement( QgsContrastEnhancement* ce ); | ||
|
|
||
| void writeXML( QDomDocument& doc, QDomElement& parentElem ) const; | ||
|
|
||
| private: | ||
| int mRedBand; | ||
| int mGreenBand; | ||
| int mBlueBand; | ||
|
|
||
| QgsContrastEnhancement* mRedContrastEnhancement; | ||
| QgsContrastEnhancement* mGreenContrastEnhancement; | ||
| QgsContrastEnhancement* mBlueContrastEnhancement; | ||
| }; | ||
|
|
||
| #endif // QGSMULTIBANDCOLORRENDERER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,219 @@ | ||
| /*************************************************************************** | ||
| qgspalettedrasterrenderer.cpp | ||
| ----------------------------- | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #include "qgspalettedrasterrenderer.h" | ||
| #include "qgsrastertransparency.h" | ||
| #include "qgsrasterviewport.h" | ||
| #include <QColor> | ||
| #include <QDomDocument> | ||
| #include <QDomElement> | ||
| #include <QImage> | ||
|
|
||
| QgsPalettedRasterRenderer::QgsPalettedRasterRenderer( QgsRasterDataProvider* provider, int bandNumber, | ||
| QColor* colorArray, int nColors ): | ||
| QgsRasterRenderer( provider, "paletted" ), mBandNumber( bandNumber ), mColors( colorArray ), mNColors( nColors ) | ||
| { | ||
| } | ||
|
|
||
| QgsPalettedRasterRenderer::~QgsPalettedRasterRenderer() | ||
| { | ||
| delete[] mColors; | ||
| } | ||
|
|
||
| QgsRasterRenderer* QgsPalettedRasterRenderer::create( const QDomElement& elem, QgsRasterDataProvider* provider ) | ||
| { | ||
| if ( elem.isNull() ) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| int bandNumber = elem.attribute( "band", "-1" ).toInt(); | ||
| int nColors; | ||
| QColor* colors; | ||
|
|
||
| QDomElement paletteElem = elem.firstChildElement( "colorPalette" ); | ||
| if ( !paletteElem.isNull() ) | ||
| { | ||
| QDomNodeList paletteEntries = paletteElem.elementsByTagName( "paletteEntry" ); | ||
| nColors = paletteEntries.size(); | ||
| colors = new QColor[ nColors ]; | ||
|
|
||
| int value = 0; | ||
| QDomElement entryElem; | ||
| for ( int i = 0; i < nColors; ++i ) | ||
| { | ||
| entryElem = paletteEntries.at( i ).toElement(); | ||
| value = entryElem.attribute( "value", "0" ).toInt(); | ||
| QgsDebugMsg( entryElem.attribute( "color", "#000000" ) ); | ||
| colors[value] = QColor( entryElem.attribute( "color", "#000000" ) ); | ||
| } | ||
| } | ||
| QgsRasterRenderer* r = new QgsPalettedRasterRenderer( provider, bandNumber, colors, nColors ); | ||
| r->readXML( elem ); | ||
| return r; | ||
| } | ||
|
|
||
| QColor* QgsPalettedRasterRenderer::colors() const | ||
| { | ||
| if ( mNColors < 1 ) | ||
| { | ||
| return 0; | ||
| } | ||
| QColor* colorArray = new QColor[ mNColors ]; | ||
| for ( int i = 0; i < mNColors; ++i ) | ||
| { | ||
| colorArray[i] = mColors[i]; | ||
| } | ||
| return colorArray; | ||
| } | ||
|
|
||
| void QgsPalettedRasterRenderer::draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel ) | ||
| { | ||
| if ( !p || !mProvider || !viewPort || !theQgsMapToPixel ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| double oversamplingX, oversamplingY; | ||
| QgsRasterDataProvider::DataType transparencyType = QgsRasterDataProvider::UnknownDataType; | ||
| if ( mAlphaBand > 0 ) | ||
| { | ||
| transparencyType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mAlphaBand ); | ||
| } | ||
| startRasterRead( mBandNumber, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY ); | ||
|
|
||
| //Read alpha band if necessary | ||
| if ( mAlphaBand > 0 && mAlphaBand != mBandNumber ) | ||
| { | ||
| startRasterRead( mAlphaBand, viewPort, theQgsMapToPixel, oversamplingX, oversamplingY ); | ||
| } | ||
|
|
||
| //number of cols/rows in output pixels | ||
| int nCols = 0; | ||
| int nRows = 0; | ||
| //number of raster cols/rows with oversampling | ||
| int nRasterCols = 0; | ||
| int nRasterRows = 0; | ||
| //shift to top left point for the raster part | ||
| int topLeftCol = 0; | ||
| int topLeftRow = 0; | ||
| int currentRasterPos = 0; | ||
| QgsRasterDataProvider::DataType rasterType = ( QgsRasterDataProvider::DataType )mProvider->dataType( mBandNumber ); | ||
| void* rasterData; | ||
| double currentOpacity = mOpacity; | ||
|
|
||
| //rendering is faster without considering user-defined transparency | ||
| bool hasTransparency = usesTransparency( viewPort->mSrcCRS, viewPort->mDestCRS ); | ||
| void* transparencyData; | ||
|
|
||
| while ( readNextRasterPart( mBandNumber, oversamplingX, oversamplingY, viewPort, nCols, nRows, nRasterCols, nRasterRows, | ||
| &rasterData, topLeftCol, topLeftRow ) ) | ||
| { | ||
| if ( mAlphaBand > 0 && mAlphaBand != mBandNumber ) | ||
| { | ||
| readNextRasterPart( mAlphaBand, oversamplingX, oversamplingY, viewPort, nCols, nRows, nRasterCols, nRasterRows, | ||
| &transparencyData, topLeftCol, topLeftRow ); | ||
| } | ||
| else if ( mAlphaBand == mBandNumber ) | ||
| { | ||
| transparencyData = rasterData; | ||
| } | ||
|
|
||
| //create image | ||
| QImage img( nRasterCols, nRasterRows, QImage::Format_ARGB32_Premultiplied ); | ||
| QRgb* imageScanLine = 0; | ||
| int val = 0; | ||
| currentRasterPos = 0; | ||
|
|
||
| for ( int i = 0; i < nRasterRows; ++i ) | ||
| { | ||
| imageScanLine = ( QRgb* )( img.scanLine( i ) ); | ||
| for ( int j = 0; j < nRasterCols; ++j ) | ||
| { | ||
| val = readValue( rasterData, rasterType, currentRasterPos ); | ||
| if ( !hasTransparency ) | ||
| { | ||
| imageScanLine[j] = mColors[ val ].rgba(); | ||
| } | ||
| else | ||
| { | ||
| currentOpacity = mOpacity; | ||
| if ( mRasterTransparency ) | ||
| { | ||
| currentOpacity = mRasterTransparency->alphaValue( val, mOpacity * 255 ) / 255.0; | ||
| } | ||
| if ( mAlphaBand > 0 ) | ||
| { | ||
| currentOpacity *= ( readValue( transparencyData, transparencyType, currentRasterPos ) / 255.0 ); | ||
| } | ||
| QColor& currentColor = mColors[val]; | ||
|
|
||
| if ( mInvertColor ) | ||
| { | ||
| imageScanLine[j] = qRgba( currentOpacity * currentColor.blue(), currentOpacity * currentColor.green(), currentOpacity * currentColor.red(), currentOpacity * 255 ); | ||
| } | ||
| else | ||
| { | ||
| imageScanLine[j] = qRgba( currentOpacity * currentColor.red(), currentOpacity * currentColor.green(), currentOpacity * currentColor.blue(), currentOpacity * 255 ); | ||
| } | ||
| } | ||
| ++currentRasterPos; | ||
| } | ||
| } | ||
|
|
||
| drawImage( p, viewPort, img, topLeftCol, topLeftRow, nCols, nRows, oversamplingX, oversamplingY ); | ||
| } | ||
|
|
||
| //stop raster reading | ||
| stopRasterRead( mBandNumber ); | ||
| if ( mAlphaBand > 0 && mAlphaBand != mBandNumber ) | ||
| { | ||
| stopRasterRead( mAlphaBand ); | ||
| } | ||
| } | ||
|
|
||
| void QgsPalettedRasterRenderer::writeXML( QDomDocument& doc, QDomElement& parentElem ) const | ||
| { | ||
| if ( parentElem.isNull() ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| QDomElement rasterRendererElem = doc.createElement( "rasterrenderer" ); | ||
| _writeXML( doc, rasterRendererElem ); | ||
|
|
||
| rasterRendererElem.setAttribute( "band", mBandNumber ); | ||
| QDomElement colorPaletteElem = doc.createElement( "colorPalette" ); | ||
| for ( int i = 0; i < mNColors; ++i ) | ||
| { | ||
| QDomElement colorElem = doc.createElement( "paletteEntry" ); | ||
| colorElem.setAttribute( "value", i ); | ||
| colorElem.setAttribute( "color", mColors[i].name() ); | ||
| colorPaletteElem.appendChild( colorElem ); | ||
| } | ||
| rasterRendererElem.appendChild( colorPaletteElem ); | ||
|
|
||
| parentElem.appendChild( rasterRendererElem ); | ||
| } | ||
|
|
||
| void QgsPalettedRasterRenderer::legendSymbologyItems( QList< QPair< QString, QColor > >& symbolItems ) const | ||
| { | ||
| for ( int i = 0; i < mNColors; ++i ) | ||
| { | ||
| symbolItems.push_back( qMakePair( QString::number( i ), mColors[i] ) ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| /*************************************************************************** | ||
| qgspalettedrasterrenderer.h | ||
| --------------------------- | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSPALETTEDRASTERRENDERER_H | ||
| #define QGSPALETTEDRASTERRENDERER_H | ||
|
|
||
| #include "qgsrasterrenderer.h" | ||
|
|
||
| class QColor; | ||
| class QDomElement; | ||
|
|
||
| class QgsPalettedRasterRenderer: public QgsRasterRenderer | ||
| { | ||
| public: | ||
| /**Renderer owns color array*/ | ||
| QgsPalettedRasterRenderer( QgsRasterDataProvider* provider, int bandNumber, QColor* colorArray, int nColors ); | ||
| ~QgsPalettedRasterRenderer(); | ||
| static QgsRasterRenderer* create( const QDomElement& elem, QgsRasterDataProvider* provider ); | ||
|
|
||
| void draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel ); | ||
|
|
||
| /**Returns number of colors*/ | ||
| int nColors() const { return mNColors; } | ||
| /**Returns copy of color array (caller takes ownership)*/ | ||
| QColor* colors() const; | ||
|
|
||
| void writeXML( QDomDocument& doc, QDomElement& parentElem ) const; | ||
|
|
||
| void legendSymbologyItems( QList< QPair< QString, QColor > >& symbolItems ) const; | ||
|
|
||
| private: | ||
| int mBandNumber; | ||
| /**Color array*/ | ||
| QColor* mColors; | ||
| /**Number of colors*/ | ||
| int mNColors; | ||
| }; | ||
|
|
||
| #endif // QGSPALETTEDRASTERRENDERER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,385 @@ | ||
| /*************************************************************************** | ||
| qgsrasterrenderer.cpp | ||
| --------------------- | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #include "qgsrasterrenderer.h" | ||
| #include "qgsrasterresampler.h" | ||
| #include "qgsrasterprojector.h" | ||
| #include "qgsrastertransparency.h" | ||
| #include "qgsrasterviewport.h" | ||
| #include "qgsmaptopixel.h" | ||
|
|
||
| //resamplers | ||
| #include "qgsbilinearrasterresampler.h" | ||
| #include "qgscubicrasterresampler.h" | ||
|
|
||
| #include <QDomDocument> | ||
| #include <QDomElement> | ||
| #include <QImage> | ||
| #include <QPainter> | ||
|
|
||
| QgsRasterRenderer::QgsRasterRenderer( QgsRasterDataProvider* provider, const QString& type ): mProvider( provider ), | ||
| mType( type ), mZoomedInResampler( 0 ), mZoomedOutResampler( 0 ), mOpacity( 1.0 ), mRasterTransparency( 0 ), | ||
| mAlphaBand( -1 ), mInvertColor( false ), mMaxOversampling( 2.0 ) | ||
| { | ||
| } | ||
|
|
||
| QgsRasterRenderer::~QgsRasterRenderer() | ||
| { | ||
| //remove remaining memory in partinfos | ||
| QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.begin(); | ||
| for ( ; partIt != mRasterPartInfos.end(); ++partIt ) | ||
| { | ||
| CPLFree( partIt.value().data ); | ||
| } | ||
|
|
||
| delete mZoomedInResampler; | ||
| delete mZoomedOutResampler; | ||
| delete mRasterTransparency; | ||
| } | ||
|
|
||
| void QgsRasterRenderer::setZoomedInResampler( QgsRasterResampler* r ) | ||
| { | ||
| delete mZoomedInResampler; | ||
| mZoomedInResampler = r; | ||
| } | ||
|
|
||
| void QgsRasterRenderer::setZoomedOutResampler( QgsRasterResampler* r ) | ||
| { | ||
| delete mZoomedOutResampler; | ||
| mZoomedOutResampler = r; | ||
| } | ||
|
|
||
| void QgsRasterRenderer::startRasterRead( int bandNumber, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double& oversamplingX, double& oversamplingY ) | ||
| { | ||
| if ( !viewPort || !mapToPixel || !mProvider ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| //remove any previous part on that band | ||
| removePartInfo( bandNumber ); | ||
|
|
||
| //calculate oversampling factor | ||
| double oversampling = 1.0; //approximate global oversampling factor | ||
|
|
||
| if ( mZoomedInResampler || mZoomedOutResampler ) | ||
| { | ||
| QgsRectangle providerExtent = mProvider->extent(); | ||
| if ( viewPort->mSrcCRS.isValid() && viewPort->mDestCRS.isValid() && viewPort->mSrcCRS != viewPort->mDestCRS ) | ||
| { | ||
| QgsCoordinateTransform t( viewPort->mSrcCRS, viewPort->mDestCRS ); | ||
| providerExtent = t.transformBoundingBox( providerExtent ); | ||
| } | ||
| double pixelRatio = mapToPixel->mapUnitsPerPixel() / ( providerExtent.width() / mProvider->xSize() ); | ||
| oversampling = ( pixelRatio > mMaxOversampling ) ? mMaxOversampling : pixelRatio; | ||
| } | ||
|
|
||
| //set oversampling back to 1.0 if no resampler for zoomed in / zoomed out (nearest neighbour) | ||
| if (( oversampling < 1.0 && !mZoomedInResampler ) || ( oversampling > 1.0 && !mZoomedOutResampler ) ) | ||
| { | ||
| oversampling = 1.0; | ||
| } | ||
|
|
||
| //split raster into small portions if necessary | ||
| RasterPartInfo pInfo; | ||
| pInfo.nCols = viewPort->drawableAreaXDim; | ||
| pInfo.nRows = viewPort->drawableAreaYDim; | ||
|
|
||
| //effective oversampling factors are different to global one because of rounding | ||
| oversamplingX = (( double )pInfo.nCols * oversampling ) / viewPort->drawableAreaXDim; | ||
| oversamplingY = (( double )pInfo.nRows * oversampling ) / viewPort->drawableAreaYDim; | ||
|
|
||
| int totalMemoryUsage = pInfo.nCols * oversamplingX * pInfo.nRows * oversamplingY * mProvider->dataTypeSize( bandNumber ); | ||
| int parts = totalMemoryUsage / 100000000 + 1; | ||
| int nPartsPerDimension = sqrt( parts ); | ||
| pInfo.nColsPerPart = pInfo.nCols / nPartsPerDimension; | ||
| pInfo.nRowsPerPart = pInfo.nRows / nPartsPerDimension; | ||
| pInfo.currentCol = 0; | ||
| pInfo.currentRow = 0; | ||
| pInfo.data = 0; | ||
| pInfo.prj = 0; | ||
| mRasterPartInfos.insert( bandNumber, pInfo ); | ||
| } | ||
|
|
||
| bool QgsRasterRenderer::readNextRasterPart( int bandNumber, double oversamplingX, double oversamplingY, QgsRasterViewPort* viewPort, | ||
| int& nCols, int& nRows, int& nColsRaster, int& nRowsRaster, void** rasterData, int& topLeftCol, int& topLeftRow ) | ||
| { | ||
| if ( !viewPort ) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| //get partinfo | ||
| QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber ); | ||
| if ( partIt == mRasterPartInfos.end() ) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| RasterPartInfo& pInfo = partIt.value(); | ||
|
|
||
| //remove last data block | ||
| CPLFree( pInfo.data ); | ||
| pInfo.data = 0; | ||
| delete pInfo.prj; | ||
| pInfo.prj = 0; | ||
|
|
||
| //already at end | ||
| if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow == pInfo.nRows ) | ||
| { | ||
| return false; | ||
| } | ||
|
|
||
| //read data block | ||
| nCols = qMin( pInfo.nColsPerPart, pInfo.nCols - pInfo.currentCol ); | ||
| nRows = qMin( pInfo.nRowsPerPart, pInfo.nRows - pInfo.currentRow ); | ||
| int typeSize = mProvider->dataTypeSize( bandNumber ) / 8; | ||
|
|
||
| //get subrectangle | ||
| QgsRectangle viewPortExtent = viewPort->mDrawnExtent; | ||
| double xmin = viewPortExtent.xMinimum() + pInfo.currentCol / ( double )pInfo.nCols * viewPortExtent.width(); | ||
| double xmax = viewPortExtent.xMinimum() + ( pInfo.currentCol + nCols ) / ( double )pInfo.nCols * viewPortExtent.width(); | ||
| double ymin = viewPortExtent.yMaximum() - ( pInfo.currentRow + nRows ) / ( double )pInfo.nRows * viewPortExtent.height(); | ||
| double ymax = viewPortExtent.yMaximum() - pInfo.currentRow / ( double )pInfo.nRows * viewPortExtent.height(); | ||
| QgsRectangle blockRect( xmin, ymin, xmax, ymax ); | ||
|
|
||
| if ( viewPort->mSrcCRS.isValid() && viewPort->mDestCRS.isValid() && viewPort->mSrcCRS != viewPort->mDestCRS ) | ||
| { | ||
| pInfo.prj = new QgsRasterProjector( viewPort->mSrcCRS, | ||
| viewPort->mDestCRS, blockRect, nRows, nCols, 0, 0, mProvider->extent() ); | ||
|
|
||
| // If we zoom out too much, projector srcRows / srcCols maybe 0, which can cause problems in providers | ||
| if ( pInfo.prj->srcRows() <= 0 || pInfo.prj->srcCols() <= 0 ) | ||
| { | ||
| delete pInfo.prj; | ||
| pInfo.prj = 0; | ||
| return false; | ||
| } | ||
|
|
||
| blockRect = pInfo.prj->srcExtent(); | ||
| } | ||
|
|
||
| if ( pInfo.prj ) | ||
| { | ||
| nColsRaster = pInfo.prj->srcCols() * oversamplingX; | ||
| nRowsRaster = pInfo.prj->srcRows() * oversamplingY; | ||
| } | ||
| else | ||
| { | ||
| nColsRaster = nCols * oversamplingX; | ||
| nRowsRaster = nRows * oversamplingY; | ||
| } | ||
| pInfo.data = VSIMalloc( typeSize * nColsRaster * nRowsRaster ); | ||
| mProvider->readBlock( bandNumber, blockRect, nColsRaster, nRowsRaster, pInfo.data ); | ||
| *rasterData = pInfo.data; | ||
| topLeftCol = pInfo.currentCol; | ||
| topLeftRow = pInfo.currentRow; | ||
|
|
||
| pInfo.currentCol += nCols; | ||
| if ( pInfo.currentCol == pInfo.nCols && pInfo.currentRow + nRows == pInfo.nRows ) //end of raster | ||
| { | ||
| pInfo.currentRow = pInfo.nRows; | ||
| } | ||
| else if ( pInfo.currentCol == pInfo.nCols ) //start new row | ||
| { | ||
| pInfo.currentCol = 0; | ||
| pInfo.currentRow += pInfo.nRowsPerPart; | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
| void QgsRasterRenderer::stopRasterRead( int bandNumber ) | ||
| { | ||
| removePartInfo( bandNumber ); | ||
| } | ||
|
|
||
| void QgsRasterRenderer::removePartInfo( int bandNumber ) | ||
| { | ||
| QMap<int, RasterPartInfo>::iterator partIt = mRasterPartInfos.find( bandNumber ); | ||
| if ( partIt != mRasterPartInfos.end() ) | ||
| { | ||
| RasterPartInfo& pInfo = partIt.value(); | ||
| CPLFree( pInfo.data ); | ||
| delete pInfo.prj; | ||
| mRasterPartInfos.remove( bandNumber ); | ||
| } | ||
| } | ||
|
|
||
| bool QgsRasterRenderer::usesTransparency( QgsCoordinateReferenceSystem& srcSRS, QgsCoordinateReferenceSystem& dstSRS ) const | ||
| { | ||
| //transparency is always used if on-the-fly reprojection is enabled | ||
| bool reprojectionEnabled = ( srcSRS.isValid() && dstSRS.isValid() && srcSRS != dstSRS ); | ||
| if ( !mProvider || reprojectionEnabled ) | ||
| { | ||
| return true; | ||
| } | ||
| return ( mAlphaBand > 0 || ( mRasterTransparency && !mRasterTransparency->isEmpty( mProvider->noDataValue() ) ) || !doubleNear( mOpacity, 1.0 ) ); | ||
| } | ||
|
|
||
| void QgsRasterRenderer::setRasterTransparency( QgsRasterTransparency* t ) | ||
| { | ||
| delete mRasterTransparency; | ||
| mRasterTransparency = t; | ||
| } | ||
|
|
||
| void QgsRasterRenderer::drawImage( QPainter* p, QgsRasterViewPort* viewPort, const QImage& img, int topLeftCol, int topLeftRow, | ||
| int nCols, int nRows, double oversamplingX, double oversamplingY ) const | ||
| { | ||
| if ( !p || !viewPort ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| //get QgsRasterProjector | ||
| QgsRasterProjector* prj; | ||
| QMap<int, RasterPartInfo>::const_iterator partInfoIt = mRasterPartInfos.constBegin(); | ||
| if ( partInfoIt != mRasterPartInfos.constEnd() ) | ||
| { | ||
| prj = partInfoIt->prj; | ||
| } | ||
|
|
||
| //top left position in device coords | ||
| QPoint tlPoint = QPoint( viewPort->topLeftPoint.x() + topLeftCol, viewPort->topLeftPoint.y() + topLeftRow ); | ||
|
|
||
| //resample and draw image | ||
| if (( mZoomedInResampler || mZoomedOutResampler ) && !doubleNear( oversamplingX, 1.0 ) && !doubleNear( oversamplingY, 1.0 ) ) | ||
| { | ||
| QImage dstImg; | ||
| if ( prj ) | ||
| { | ||
| dstImg = QImage( prj->srcCols(), prj->srcRows(), QImage::Format_ARGB32_Premultiplied ); | ||
| } | ||
| else | ||
| { | ||
| dstImg = QImage( nCols, nRows, QImage::Format_ARGB32_Premultiplied ); | ||
| } | ||
| if ( mZoomedInResampler && oversamplingX < 1.0 ) | ||
| { | ||
| mZoomedInResampler->resample( img, dstImg ); | ||
| } | ||
| else if ( mZoomedOutResampler && oversamplingX > 1.0 ) | ||
| { | ||
| mZoomedOutResampler->resample( img, dstImg ); | ||
| } | ||
|
|
||
| if ( prj ) | ||
| { | ||
| QImage projectedImg( nCols, nRows, QImage::Format_ARGB32_Premultiplied ); | ||
| projectImage( dstImg, projectedImg, prj ); | ||
| p->drawImage( tlPoint, projectedImg ); | ||
| } | ||
| else | ||
| { | ||
| p->drawImage( tlPoint, dstImg ); | ||
| } | ||
| } | ||
| else //use original image | ||
| { | ||
| if ( prj ) | ||
| { | ||
| QImage projectedImg( nCols, nRows, QImage::Format_ARGB32_Premultiplied ); | ||
| projectImage( img, projectedImg, prj ); | ||
| p->drawImage( tlPoint, projectedImg ); | ||
| } | ||
| else | ||
| { | ||
| p->drawImage( tlPoint, img ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void QgsRasterRenderer::projectImage( const QImage& srcImg, QImage& dstImage, QgsRasterProjector* prj ) const | ||
| { | ||
| int nRows = dstImage.height(); | ||
| int nCols = dstImage.width(); | ||
| int srcRow, srcCol; | ||
| for ( int i = 0; i < nRows; ++i ) | ||
| { | ||
| for ( int j = 0; j < nCols; ++j ) | ||
| { | ||
| prj->srcRowCol( i, j, &srcRow, &srcCol ); | ||
| dstImage.setPixel( j, i, srcImg.pixel( srcCol, srcRow ) ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| void QgsRasterRenderer::_writeXML( QDomDocument& doc, QDomElement& rasterRendererElem ) const | ||
| { | ||
| if ( rasterRendererElem.isNull() ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| rasterRendererElem.setAttribute( "type", mType ); | ||
| rasterRendererElem.setAttribute( "opacity", mOpacity ); | ||
| rasterRendererElem.setAttribute( "alphaBand", mAlphaBand ); | ||
| rasterRendererElem.setAttribute( "maxOversampling", mMaxOversampling ); | ||
| rasterRendererElem.setAttribute( "invertColor", mInvertColor ); | ||
| if ( mZoomedInResampler ) | ||
| { | ||
| rasterRendererElem.setAttribute( "zoomedInResampler", mZoomedInResampler->type() ); | ||
| } | ||
| if ( mZoomedOutResampler ) | ||
| { | ||
| rasterRendererElem.setAttribute( "zoomedOutResampler", mZoomedOutResampler->type() ); | ||
| } | ||
|
|
||
| if ( mRasterTransparency ) | ||
| { | ||
| mRasterTransparency->writeXML( doc, rasterRendererElem ); | ||
| } | ||
| } | ||
|
|
||
| void QgsRasterRenderer::readXML( const QDomElement& rendererElem ) | ||
| { | ||
| if ( rendererElem.isNull() ) | ||
| { | ||
| return; | ||
| } | ||
|
|
||
| mType = rendererElem.attribute( "type" ); | ||
| mOpacity = rendererElem.attribute( "opacity", "1.0" ).toDouble(); | ||
| mAlphaBand = rendererElem.attribute( "alphaBand", "-1" ).toInt(); | ||
| mMaxOversampling = rendererElem.attribute( "maxOversampling", "2.0" ).toDouble(); | ||
| mInvertColor = rendererElem.attribute( "invertColor", "0" ).toInt(); | ||
|
|
||
| QString zoomedInResamplerType = rendererElem.attribute( "zoomedInResampler" ); | ||
| if ( zoomedInResamplerType == "bilinear" ) | ||
| { | ||
| mZoomedInResampler = new QgsBilinearRasterResampler(); | ||
| } | ||
| else if ( zoomedInResamplerType == "cubic" ) | ||
| { | ||
| mZoomedInResampler = new QgsCubicRasterResampler(); | ||
| } | ||
|
|
||
| QString zoomedOutResamplerType = rendererElem.attribute( "zoomedOutResampler" ); | ||
| if ( zoomedOutResamplerType == "bilinear" ) | ||
| { | ||
| mZoomedOutResampler = new QgsBilinearRasterResampler(); | ||
| } | ||
|
|
||
| //todo: read mRasterTransparency | ||
| QDomElement rasterTransparencyElem = rendererElem.firstChildElement( "rasterTransparency" ); | ||
| if ( !rasterTransparencyElem.isNull() ) | ||
| { | ||
| delete mRasterTransparency; | ||
| mRasterTransparency = new QgsRasterTransparency(); | ||
| mRasterTransparency->readXML( rasterTransparencyElem ); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,185 @@ | ||
| /*************************************************************************** | ||
| qgsrasterrenderer.h | ||
| ------------------- | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSRASTERRENDERER_H | ||
| #define QGSRASTERRENDERER_H | ||
|
|
||
| #include "qgsrasterdataprovider.h" | ||
| #include <QPair> | ||
|
|
||
| class QPainter; | ||
| class QgsMapToPixel; | ||
| class QgsRasterResampler; | ||
| class QgsRasterProjector; | ||
| class QgsRasterTransparency; | ||
| class QgsRasterViewPort; | ||
|
|
||
| class QDomElement; | ||
|
|
||
| class QgsRasterRenderer | ||
| { | ||
| public: | ||
| //Stores information about reading of a raster band. Columns and rows are in unsampled coordinates | ||
| struct RasterPartInfo | ||
| { | ||
| int currentCol; | ||
| int currentRow; | ||
| int nCols; | ||
| int nRows; | ||
| int nColsPerPart; | ||
| int nRowsPerPart; | ||
| void* data; //data (can be in oversampled/undersampled resolution) | ||
| QgsRasterProjector* prj; //raster projector (or 0 if no reprojection is done) | ||
| }; | ||
|
|
||
| QgsRasterRenderer( QgsRasterDataProvider* provider, const QString& type ); | ||
| virtual ~QgsRasterRenderer(); | ||
|
|
||
| virtual QString type() const { return mType; } | ||
| virtual void draw( QPainter* p, QgsRasterViewPort* viewPort, const QgsMapToPixel* theQgsMapToPixel ) = 0; | ||
|
|
||
| bool usesTransparency( QgsCoordinateReferenceSystem& srcSRS, QgsCoordinateReferenceSystem& dstSRS ) const; | ||
|
|
||
| void setOpacity( double opacity ) { mOpacity = opacity; } | ||
| double opacity() const { return mOpacity; } | ||
|
|
||
| void setRasterTransparency( QgsRasterTransparency* t ); | ||
| const QgsRasterTransparency* rasterTransparency() const { return mRasterTransparency; } | ||
|
|
||
| void setAlphaBand( int band ) { mAlphaBand = band; } | ||
| int alphaBand() const { return mAlphaBand; } | ||
|
|
||
| void setInvertColor( bool invert ) { mInvertColor = invert; } | ||
| bool invertColor() const { return mInvertColor; } | ||
|
|
||
| /**Set resampler for zoomed in scales. Takes ownership of the object*/ | ||
| void setZoomedInResampler( QgsRasterResampler* r ); | ||
| const QgsRasterResampler* zoomedInResampler() const { return mZoomedInResampler; } | ||
|
|
||
| /**Set resampler for zoomed out scales. Takes ownership of the object*/ | ||
| void setZoomedOutResampler( QgsRasterResampler* r ); | ||
| const QgsRasterResampler* zoomedOutResampler() const { return mZoomedOutResampler; } | ||
|
|
||
| void setMaxOversampling( double os ) { mMaxOversampling = os; } | ||
| double maxOversampling() const { return mMaxOversampling; } | ||
|
|
||
| /**Get symbology items if provided by renderer*/ | ||
| virtual void legendSymbologyItems( QList< QPair< QString, QColor > >& symbolItems ) const { Q_UNUSED( symbolItems ); } | ||
|
|
||
| virtual void writeXML( QDomDocument& doc, QDomElement& parentElem ) const = 0; | ||
|
|
||
| /**Sets base class members from xml. Usually called from create() methods of subclasses*/ | ||
| void readXML( const QDomElement& rendererElem ); | ||
|
|
||
| protected: | ||
| inline double readValue( void *data, QgsRasterDataProvider::DataType type, int index ); | ||
|
|
||
| /**Start reading of raster band. Raster data can then be retrieved by calling readNextRasterPart until it returns false. | ||
| @param bandNumer number of raster band to read | ||
| @param viewPort describes raster position on screen | ||
| @param oversamplingX out: oversampling rate in x-direction | ||
| @param oversamplingY out: oversampling rate in y-direction*/ | ||
| void startRasterRead( int bandNumber, QgsRasterViewPort* viewPort, const QgsMapToPixel* mapToPixel, double& oversamplingX, double& oversamplingY ); | ||
| /**Fetches next part of raster data | ||
| @param nCols number of columns on output device | ||
| @param nRows number of rows on output device | ||
| @param nColsRaster number of raster columns (different to nCols if oversamplingX != 1.0) | ||
| @param nRowsRaster number of raster rows (different to nRows if oversamplingY != 0)*/ | ||
| bool readNextRasterPart( int bandNumber, double oversamplingX, double oversamplingY, QgsRasterViewPort* viewPort, int& nCols, int& nRows, | ||
| int& nColsRaster, int& nRowsRaster, void** rasterData, int& topLeftCol, int& topLeftRow ); | ||
| /**Draws raster part | ||
| @param topLeftCol Left position relative to left border of viewport | ||
| @param topLeftRow Top position relative to top border of viewport*/ | ||
| void drawImage( QPainter* p, QgsRasterViewPort* viewPort, const QImage& img, int topLeftCol, int topLeftRow, | ||
| int nCols, int nRows, double oversamplingX, double oversamplingY ) const; | ||
| void stopRasterRead( int bandNumber ); | ||
|
|
||
| /**Write upper class info into <rasterrenderer> element (called by writeXML method of subclasses)*/ | ||
| void _writeXML( QDomDocument& doc, QDomElement& rasterRendererElem ) const; | ||
|
|
||
|
|
||
| QgsRasterDataProvider* mProvider; | ||
| QString mType; | ||
| /**Resampler used if screen resolution is higher than raster resolution (zoomed in). 0 means no resampling (nearest neighbour)*/ | ||
| QgsRasterResampler* mZoomedInResampler; | ||
| /**Resampler used if raster resolution is higher than raster resolution (zoomed out). 0 mean no resampling (nearest neighbour)*/ | ||
| QgsRasterResampler* mZoomedOutResampler; | ||
| QMap<int, RasterPartInfo> mRasterPartInfos; | ||
|
|
||
| /**Global alpha value (0-1)*/ | ||
| double mOpacity; | ||
| /**Raster transparency per color or value. Overwrites global alpha value*/ | ||
| QgsRasterTransparency* mRasterTransparency; | ||
| /**Read alpha value from band. Is combined with value from raster transparency / global alpha value. | ||
| Default: -1 (not set)*/ | ||
| int mAlphaBand; | ||
|
|
||
| bool mInvertColor; | ||
|
|
||
| /**Maximum boundary for oversampling (to avoid too much data traffic). Default: 2.0*/ | ||
| double mMaxOversampling; | ||
|
|
||
| private: | ||
| /**Remove part into and release memory*/ | ||
| void removePartInfo( int bandNumer ); | ||
| void projectImage( const QImage& srcImg, QImage& dstImage, QgsRasterProjector* prj ) const; | ||
| }; | ||
|
|
||
| inline double QgsRasterRenderer::readValue( void *data, QgsRasterDataProvider::DataType type, int index ) | ||
| { | ||
| if ( !mProvider ) | ||
| { | ||
| return 0; | ||
| } | ||
|
|
||
| if ( !data ) | ||
| { | ||
| return mProvider->noDataValue(); | ||
| } | ||
|
|
||
| switch ( type ) | ||
| { | ||
| case QgsRasterDataProvider::Byte: | ||
| return ( double )(( GByte * )data )[index]; | ||
| break; | ||
| case QgsRasterDataProvider::UInt16: | ||
| return ( double )(( GUInt16 * )data )[index]; | ||
| break; | ||
| case QgsRasterDataProvider::Int16: | ||
| return ( double )(( GInt16 * )data )[index]; | ||
| break; | ||
| case QgsRasterDataProvider::UInt32: | ||
| return ( double )(( GUInt32 * )data )[index]; | ||
| break; | ||
| case QgsRasterDataProvider::Int32: | ||
| return ( double )(( GInt32 * )data )[index]; | ||
| break; | ||
| case QgsRasterDataProvider::Float32: | ||
| return ( double )(( float * )data )[index]; | ||
| break; | ||
| case QgsRasterDataProvider::Float64: | ||
| return ( double )(( double * )data )[index]; | ||
| break; | ||
| default: | ||
| //QgsMessageLog::logMessage( tr( "GDAL data type %1 is not supported" ).arg( type ), tr( "Raster" ) ); | ||
| break; | ||
| } | ||
|
|
||
| return mProvider->noDataValue(); | ||
| } | ||
|
|
||
| #endif // QGSRASTERRENDERER_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| /*************************************************************************** | ||
| qgsrasterrendererregistry.cpp | ||
| ----------------------------- | ||
| begin : January 2012 | ||
| copyright : (C) 2012 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #include "qgsrasterrendererregistry.h" | ||
| #include "qgsmultibandcolorrenderer.h" | ||
| #include "qgspalettedrasterrenderer.h" | ||
| #include "qgssinglebandcolordatarenderer.h" | ||
| #include "qgssinglebandgrayrenderer.h" | ||
| #include "qgssinglebandpseudocolorrenderer.h" | ||
|
|
||
| QgsRasterRendererRegistryEntry::QgsRasterRendererRegistryEntry( const QString& theName, const QString& theVisibleName, | ||
| QgsRasterRendererCreateFunc rendererFunction, | ||
| QgsRasterRendererWidgetCreateFunc widgetFunction ): | ||
| name( theName ), visibleName( theVisibleName ), rendererCreateFunction( rendererFunction ), | ||
| widgetCreateFunction( widgetFunction ) | ||
| { | ||
| } | ||
|
|
||
| QgsRasterRendererRegistryEntry::QgsRasterRendererRegistryEntry(): rendererCreateFunction( 0 ), widgetCreateFunction( 0 ) | ||
| { | ||
| } | ||
|
|
||
| QgsRasterRendererRegistry* QgsRasterRendererRegistry::mInstance = 0; | ||
|
|
||
| QgsRasterRendererRegistry* QgsRasterRendererRegistry::instance() | ||
| { | ||
| if ( !mInstance ) | ||
| { | ||
| mInstance = new QgsRasterRendererRegistry(); | ||
| } | ||
| return mInstance; | ||
| } | ||
|
|
||
| QgsRasterRendererRegistry::QgsRasterRendererRegistry() | ||
| { | ||
| insert( QgsRasterRendererRegistryEntry( "paletted", QObject::tr( "Paletted" ), QgsPalettedRasterRenderer::create, 0 ) ); | ||
| insert( QgsRasterRendererRegistryEntry( "multibandcolor", QObject::tr( "Multiband color" ), | ||
| QgsMultiBandColorRenderer::create, 0 ) ); | ||
| insert( QgsRasterRendererRegistryEntry( "singlebandpseudocolor", QObject::tr( "Singleband pseudocolor" ), | ||
| QgsSingleBandPseudoColorRenderer::create, 0 ) ); | ||
| insert( QgsRasterRendererRegistryEntry( "singlebandgray", QObject::tr( "Singleband gray" ), | ||
| QgsSingleBandGrayRenderer::create, 0 ) ); | ||
| insert( QgsRasterRendererRegistryEntry( "singlebandcolordata", QObject::tr( "Singleband color data" ), | ||
| QgsSingleBandColorDataRenderer::create, 0 ) ); | ||
| } | ||
|
|
||
| QgsRasterRendererRegistry::~QgsRasterRendererRegistry() | ||
| { | ||
| } | ||
|
|
||
| void QgsRasterRendererRegistry::insert( QgsRasterRendererRegistryEntry entry ) | ||
| { | ||
| mEntries.insert( entry.name, entry ); | ||
| } | ||
|
|
||
| void QgsRasterRendererRegistry::insertWidgetFunction( const QString& rendererName, QgsRasterRendererWidgetCreateFunc func ) | ||
| { | ||
| if ( !mEntries.contains( rendererName ) ) | ||
| { | ||
| return; | ||
| } | ||
| mEntries[rendererName].widgetCreateFunction = func; | ||
| } | ||
|
|
||
| bool QgsRasterRendererRegistry::rendererData( const QString& rendererName, QgsRasterRendererRegistryEntry& data ) const | ||
| { | ||
| QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.find( rendererName ); | ||
| if ( it == mEntries.constEnd() ) | ||
| { | ||
| return false; | ||
| } | ||
| data = it.value(); | ||
| return true; | ||
| } | ||
|
|
||
| QStringList QgsRasterRendererRegistry::renderersList() const | ||
| { | ||
| return QStringList( mEntries.keys() ); | ||
| } | ||
|
|
||
| QList< QgsRasterRendererRegistryEntry > QgsRasterRendererRegistry::entries() const | ||
| { | ||
| QList< QgsRasterRendererRegistryEntry > result; | ||
|
|
||
| QHash< QString, QgsRasterRendererRegistryEntry >::const_iterator it = mEntries.constBegin(); | ||
| for ( ; it != mEntries.constEnd(); ++it ) | ||
| { | ||
| result.push_back( it.value() ); | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| /*************************************************************************** | ||
| qgsrasterrendererregistry.h | ||
| --------------------------- | ||
| begin : January 2012 | ||
| copyright : (C) 2012 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSRASTERRENDERERREGISTRY_H | ||
| #define QGSRASTERRENDERERREGISTRY_H | ||
|
|
||
| #include <QHash> | ||
| #include <QString> | ||
|
|
||
| class QDomElement; | ||
| class QgsRasterDataProvider; | ||
| class QgsRasterLayer; | ||
| class QgsRasterRenderer; | ||
| class QgsRasterRendererWidget; | ||
|
|
||
| typedef QgsRasterRenderer*( *QgsRasterRendererCreateFunc )( const QDomElement&, QgsRasterDataProvider* provider ); | ||
| typedef QgsRasterRendererWidget*( *QgsRasterRendererWidgetCreateFunc )( QgsRasterLayer* ); | ||
|
|
||
| struct QgsRasterRendererRegistryEntry | ||
| { | ||
| QgsRasterRendererRegistryEntry( const QString& theName, const QString& theVisibleName, QgsRasterRendererCreateFunc rendererFunction, | ||
| QgsRasterRendererWidgetCreateFunc widgetFunction ); | ||
| QgsRasterRendererRegistryEntry(); | ||
| QString name; | ||
| QString visibleName; //visible (and translatable) name | ||
| QgsRasterRendererCreateFunc rendererCreateFunction; //pointer to create function | ||
| QgsRasterRendererWidgetCreateFunc widgetCreateFunction; //pointer to create function for renderer widget | ||
| }; | ||
|
|
||
| class QgsRasterRendererRegistry | ||
| { | ||
| public: | ||
| static QgsRasterRendererRegistry* instance(); | ||
| ~QgsRasterRendererRegistry(); | ||
|
|
||
| void insert( QgsRasterRendererRegistryEntry entry ); | ||
| void insertWidgetFunction( const QString& rendererName, QgsRasterRendererWidgetCreateFunc func ); | ||
| bool rendererData( const QString& rendererName, QgsRasterRendererRegistryEntry& data ) const; | ||
| QStringList renderersList() const; | ||
| QList< QgsRasterRendererRegistryEntry > entries() const; | ||
|
|
||
| protected: | ||
| QgsRasterRendererRegistry(); | ||
|
|
||
| private: | ||
| static QgsRasterRendererRegistry* mInstance; | ||
| QHash< QString, QgsRasterRendererRegistryEntry > mEntries; | ||
| }; | ||
|
|
||
| #endif // QGSRASTERRENDERERREGISTRY_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| /*************************************************************************** | ||
| qgsrasterresampler.h | ||
| -------------------- | ||
| begin : December 2011 | ||
| copyright : (C) 2011 by Marco Hugentobler | ||
| email : marco at sourcepole dot ch | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSRASTERRESAMPLER_H | ||
| #define QGSRASTERRESAMPLER_H | ||
|
|
||
| #include <QString> | ||
|
|
||
| class QImage; | ||
|
|
||
| /**Interface for resampling rasters (e.g. to have a smoother appearance)*/ | ||
| class QgsRasterResampler | ||
| { | ||
| public: | ||
| virtual void resample( const QImage& srcImage, QImage& dstImage ) = 0; | ||
| virtual QString type() const = 0; | ||
| }; | ||
|
|
||
| #endif // QGSRASTERRESAMPLER_H |