Skip to content

Commit

Permalink
implement pyramids in raster save dialog ; improve pyramids creation …
Browse files Browse the repository at this point in the history
…; remove pyramid-related stuff from qgsrasterlayer
  • Loading branch information
etiennesky committed Aug 26, 2012
1 parent 4cfc365 commit eda71f5
Show file tree
Hide file tree
Showing 19 changed files with 805 additions and 270 deletions.
14 changes: 7 additions & 7 deletions python/core/qgsrasterlayer.sip
Expand Up @@ -6,7 +6,7 @@
class QgsRasterLayer : QgsMapLayer
{
%TypeHeaderCode
#include <qgsrasterpyramid.h>
// #include <qgsrasterpyramid.h>
#include <qgsrasterlayer.h>
#include <qgscontrastenhancement.h>
#include <qgsrastertransparency.h>
Expand Down Expand Up @@ -91,7 +91,7 @@ public:
* to be added to the list. Each time a RasterPyramid is created
* we will check to see if a pyramid matching these dimensions already exists
* in the raster layer, and if so mark the exists flag as true */
typedef QList<QgsRasterPyramid> RasterPyramidList;
// typedef QList<QgsRasterPyramid> RasterPyramidList;

/** \brief A list containing one RasterBandStats struct per raster band in this raster layer.
* Note that while every RasterBandStats element will have the name and number of its associated
Expand Down Expand Up @@ -151,7 +151,7 @@ public:
//QString greenBandName() const; //removed with raster redesign

/** \brief Accessor for mHasPyramids (READ ONLY) */
bool hasPyramids();
// bool hasPyramids();

/** \brief Accessor for mUserDefinedGrayMinimumMaximum */
bool hasUserDefinedGrayMinimumMaximum() const;
Expand Down Expand Up @@ -248,7 +248,7 @@ public:
* ACTUALLY exists you need to look at the existsFlag member in each struct stored in the
* list.
*/
RasterPyramidList buildPyramidList();
// RasterPyramidList buildPyramidList();

/** \brief Accessor for color shader algorithm */
QString colorShadingAlgorithmAsString() const;
Expand Down Expand Up @@ -470,9 +470,9 @@ public:

public slots:
/** \brief Create GDAL pyramid overviews */
QString buildPyramids( const RasterPyramidList &,
const QString & theResamplingMethod = "NEAREST",
bool theTryInternalFlag = false );
// QString buildPyramids( const RasterPyramidList &,
// const QString & theResamplingMethod = "NEAREST",
// bool theTryInternalFlag = false );

void showStatusMessage( const QString & theMessage );

Expand Down
5 changes: 5 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -3997,6 +3997,11 @@ void QgisApp::saveAsRasterFile()
}
fileWriter.setCreateOptions( d.createOptions() );

fileWriter.setBuildPyramidsFlag( d.buildPyramidsFlag() );
fileWriter.setPyramidsList( d.overviewList() );
fileWriter.setPyramidsResampling( d.pyramidsResampling() );
fileWriter.setPyramidsFormat( d.pyramidsFormat() );

fileWriter.writeRaster( pipe, d.nColumns(), d.nRows(), d.outputRectangle(), d.outputCrs(), &pd );
delete pipe;
}
Expand Down
28 changes: 17 additions & 11 deletions src/app/qgsrasterlayerproperties.cpp
Expand Up @@ -117,13 +117,20 @@ QgsRasterLayerProperties::QgsRasterLayerProperties( QgsMapLayer* lyr, QgsMapCanv
{
return;
}

QgsRasterDataProvider* provider = mRasterLayer->dataProvider();

// Only do pyramids if dealing directly with GDAL.
if ( provider->capabilities() & QgsRasterDataProvider::BuildPyramids )
{
QgsRasterLayer::RasterPyramidList myPyramidList = mRasterLayer->buildPyramidList();
QgsRasterLayer::RasterPyramidList::iterator myRasterPyramidIterator;
// initialize resampling methods
cboResamplingMethod->clear();
foreach ( QString method, QgsRasterDataProvider::pyramidResamplingMethods( mRasterLayer->providerType() ) )
cboResamplingMethod->addItem( method );

// build pyramid list
QList< QgsRasterPyramid > myPyramidList = provider->buildPyramidList();
QList< QgsRasterPyramid >::iterator myRasterPyramidIterator;

for ( myRasterPyramidIterator = myPyramidList.begin();
myRasterPyramidIterator != myPyramidList.end();
Expand Down Expand Up @@ -762,13 +769,14 @@ void QgsRasterLayerProperties::apply()

void QgsRasterLayerProperties::on_buttonBuildPyramids_clicked()
{
QgsRasterDataProvider* provider = mRasterLayer->dataProvider();

connect( mRasterLayer, SIGNAL( progressUpdate( int ) ), mPyramidProgress, SLOT( setValue( int ) ) );
connect( provider, SIGNAL( progressUpdate( int ) ), mPyramidProgress, SLOT( setValue( int ) ) );
//
// Go through the list marking any files that are selected in the listview
// as true so that we can generate pyramids for them.
//
QgsRasterLayer::RasterPyramidList myPyramidList = mRasterLayer->buildPyramidList();
QList< QgsRasterPyramid> myPyramidList = provider->buildPyramidList();
for ( int myCounterInt = 0; myCounterInt < lbxPyramidResolutions->count(); myCounterInt++ )
{
QListWidgetItem *myItem = lbxPyramidResolutions->item( myCounterInt );
Expand All @@ -781,15 +789,14 @@ void QgsRasterLayerProperties::on_buttonBuildPyramids_clicked()

// let the user know we're going to possibly be taking a while
QApplication::setOverrideCursor( Qt::WaitCursor );
bool myBuildInternalFlag = cbxInternalPyramids->isChecked();
QString res = mRasterLayer->buildPyramids(
QString res = provider->buildPyramids(
myPyramidList,
cboResamplingMethod->currentText(),
myBuildInternalFlag );
( QgsRasterDataProvider::RasterPyramidsFormat ) cbxPyramidsFormat->currentIndex() );
QApplication::restoreOverrideCursor();
mPyramidProgress->setValue( 0 );
buttonBuildPyramids->setEnabled( false );
disconnect( mRasterLayer, SIGNAL( progressUpdate( int ) ), mPyramidProgress, SLOT( setValue( int ) ) );
disconnect( provider, SIGNAL( progressUpdate( int ) ), mPyramidProgress, SLOT( setValue( int ) ) );
if ( !res.isNull() )
{
if ( res == "ERROR_WRITE_ACCESS" )
Expand Down Expand Up @@ -821,17 +828,16 @@ void QgsRasterLayerProperties::on_buttonBuildPyramids_clicked()

}


//
// repopulate the pyramids list
//
lbxPyramidResolutions->clear();
// Need to rebuild list as some or all pyramids may have failed to build
myPyramidList = mRasterLayer->buildPyramidList();
myPyramidList = provider->buildPyramidList();
QIcon myPyramidPixmap( QgsApplication::getThemeIcon( "/mIconPyramid.png" ) );
QIcon myNoPyramidPixmap( QgsApplication::getThemeIcon( "/mIconNoPyramid.png" ) );

QgsRasterLayer::RasterPyramidList::iterator myRasterPyramidIterator;
QList< QgsRasterPyramid >::iterator myRasterPyramidIterator;
for ( myRasterPyramidIterator = myPyramidList.begin();
myRasterPyramidIterator != myPyramidList.end();
++myRasterPyramidIterator )
Expand Down
20 changes: 20 additions & 0 deletions src/core/qgsrasterdataprovider.cpp
Expand Up @@ -272,6 +272,26 @@ QByteArray QgsRasterDataProvider::noValueBytes( int theBandNo )
return ba;
}

bool QgsRasterDataProvider::hasPyramids()
{
QList<QgsRasterPyramid> myPyramidList = buildPyramidList();

if ( myPyramidList.isEmpty() )
return false;

QList<QgsRasterPyramid>::iterator myRasterPyramidIterator;
for ( myRasterPyramidIterator = myPyramidList.begin();
myRasterPyramidIterator != myPyramidList.end();
++myRasterPyramidIterator )
{
if ( myRasterPyramidIterator->exists )
{
return true;
}
}
return false;
}

#if 0
QgsRasterBandStats QgsRasterDataProvider::bandStatistics( int theBandNo )
{
Expand Down
41 changes: 36 additions & 5 deletions src/core/qgsrasterdataprovider.h
Expand Up @@ -102,6 +102,20 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
ProgressStatistics = 2
};

enum RasterBuildPyramids
{
PyramidsFlagNo = 0,
PyramidsFlagYes = 1,
CopyExisting = 2
};

enum RasterPyramidsFormat
{
PyramidsGTiff = 0,
PyramidsInternal = 1,
PyramidsErdas = 2
};

QgsRasterDataProvider();

QgsRasterDataProvider( QString const & uri );
Expand Down Expand Up @@ -345,15 +359,24 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
/** \brief Create pyramid overviews */
virtual QString buildPyramids( const QList<QgsRasterPyramid> & thePyramidList,
const QString & theResamplingMethod = "NEAREST",
bool theTryInternalFlag = false )
{ Q_UNUSED( thePyramidList ); Q_UNUSED( theResamplingMethod ); Q_UNUSED( theTryInternalFlag ); return "FAILED_NOT_SUPPORTED"; };
RasterPyramidsFormat theFormat = PyramidsGTiff )
{
Q_UNUSED( thePyramidList ); Q_UNUSED( theResamplingMethod ); Q_UNUSED( theFormat );
return "FAILED_NOT_SUPPORTED";
};

/** \brief Accessor for ths raster layers pyramid list. A pyramid list defines the
/** \brief Accessor for ths raster layers pyramid list.
* @param overviewList used to construct the pyramid list (optional), when empty the list is defined by the provider.
* A pyramid list defines the
* POTENTIAL pyramids that can be in a raster. To know which of the pyramid layers
* ACTUALLY exists you need to look at the existsFlag member in each struct stored in the
* list.
*/
virtual QList<QgsRasterPyramid> buildPyramidList() { return QList<QgsRasterPyramid>(); };
virtual QList<QgsRasterPyramid> buildPyramidList( QList<int> overviewList = QList<int>() )
{ Q_UNUSED( overviewList ); return QList<QgsRasterPyramid>(); };

/** \brief Returns true if raster has at least one populated histogram. */
bool hasPyramids();

/** If the provider supports it, return band stats for the
given band. Default behaviour is to blockwise read the data
Expand Down Expand Up @@ -537,13 +560,21 @@ class CORE_EXPORT QgsRasterDataProvider : public QgsDataProvider, public QgsRast
/** Remove dataset*/
virtual bool remove() { return false; }

static QStringList pyramidResamplingMethods( QString providerKey )
{
return providerKey == "gdal" ?
QStringList() << tr( "Average" ) << tr( "Nearest Neighbour" ) << tr( "Gauss" ) <<
tr( "Cubic" ) << tr( "Mode" ) << tr( "None" ) : QStringList();
}

signals:
/** Emit a signal to notify of the progress event.
* Emited theProgress is in percents (0.0-100.0) */
void progress( int theType, double theProgress, QString theMessage );
void progressUpdate( int theProgress );

protected:
/**Dots per intch. Extended WMS (e.g. QGIS mapserver) support DPI dependent output and therefore
/**Dots per inch. Extended WMS (e.g. QGIS mapserver) support DPI dependent output and therefore
are suited for printing. A value of -1 means it has not been set
@note: this member has been added in version 1.2*/
int mDpi;
Expand Down

0 comments on commit eda71f5

Please sign in to comment.