Skip to content
Permalink
Browse files
Merge pull request #394 from etiennesky/gdaltools1
GdalTools - use raster format save option and pyramids dialogs
  • Loading branch information
brushtyler committed Jan 28, 2013
2 parents 8c89c2a + c279ec2 commit 9dffa42eea0bfedf829b802a9a4d10fbea03bfcd
Showing with 1,028 additions and 627 deletions.
  1. +19 −9 python/core/raster/qgsrasterdataprovider.sip
  2. +3 −1 python/core/raster/qgsrasterfilewriter.sip
  3. +2 −0 python/gui/qgsrasterformatsaveoptionswidget.sip
  4. +3 −2 python/gui/qgsrasterlayersaveasdialog.sip
  5. +10 −1 python/gui/qgsrasterpyramidsoptionswidget.sip
  6. +11 −11 python/plugins/GdalTools/GdalTools.py
  7. +5 −0 python/plugins/GdalTools/tools/GdalTools_utils.py
  8. +15 −5 python/plugins/GdalTools/tools/doDEM.py
  9. +38 −16 python/plugins/GdalTools/tools/doOverview.py
  10. +12 −6 python/plugins/GdalTools/tools/doTranslate.py
  11. +285 −252 python/plugins/GdalTools/tools/widgetDEM.ui
  12. +181 −144 python/plugins/GdalTools/tools/widgetOverview.ui
  13. +12 −1 python/plugins/GdalTools/tools/widgetPluginBase.py
  14. +14 −5 python/plugins/GdalTools/tools/widgetTranslate.ui
  15. +3 −2 src/app/qgisapp.cpp
  16. +2 −0 src/core/qgis.h
  17. +57 −0 src/core/raster/qgsrasterdataprovider.cpp
  18. +23 −12 src/core/raster/qgsrasterdataprovider.h
  19. +3 −2 src/core/raster/qgsrasterfilewriter.cpp
  20. +4 −1 src/core/raster/qgsrasterfilewriter.h
  21. +0 −1 src/core/symbology-ng/qgssymbolv2.h
  22. +95 −31 src/gui/qgsrasterformatsaveoptionswidget.cpp
  23. +15 −1 src/gui/qgsrasterformatsaveoptionswidget.h
  24. +14 −4 src/gui/qgsrasterlayersaveasdialog.cpp
  25. +4 −2 src/gui/qgsrasterlayersaveasdialog.h
  26. +22 −10 src/gui/qgsrasterpyramidsoptionswidget.cpp
  27. +7 −6 src/gui/qgsrasterpyramidsoptionswidget.h
  28. +108 −45 src/providers/gdal/qgsgdalprovider.cpp
  29. +7 −3 src/providers/gdal/qgsgdalprovider.h
  30. +54 −54 src/ui/qgsrasterpyramidsoptionswidgetbase.ui
@@ -169,10 +169,11 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
virtual QStringList subLayers() const;

/** \brief Create pyramid overviews */
virtual QString buildPyramids( const QList<QgsRasterPyramid> & thePyramidList,
const QString & theResamplingMethod = "NEAREST",
RasterPyramidsFormat theFormat = PyramidsGTiff );

virtual QString buildPyramids( const QList<QgsRasterPyramid> & thePyramidList,
const QString & theResamplingMethod = "NEAREST",
RasterPyramidsFormat theFormat = PyramidsGTiff,
const QStringList & theConfigOptions = QStringList() );

/** \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
@@ -269,13 +270,22 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
/** Remove dataset*/
virtual bool remove();

static QStringList pyramidResamplingMethods( QString providerKey );
/** Returns a list of pyramid resampling method names for given provider */
static QStringList pyramidResamplingMethods( QString providerKey = "gdal" );
/** Returns the pyramid resampling argument that corresponds to a given method */
static QString pyramidResamplingArg( QString method, QString providerKey = "gdal" );

/** Validates creation options for a specific dataset and destination format.
* @note used by GDAL provider only
* @note see also validateCreationOptionsFormat() in gdal provider for validating options based on format only */
virtual QString validateCreationOptions( const QStringList& createOptions, QString format );

/** Validates creation options for a specific dataset and destination format - used by GDAL provider only.
* See also validateCreationOptionsFormat() in gdal provider for validating options based on format only. */
virtual QString validateCreationOptions( const QStringList& createOptions, QString format );
/** Validates pyramid creation options for a specific dataset and destination format
* @note used by GDAL provider only */
virtual QString validatePyramidsConfigOptions( RasterPyramidsFormat pyramidsFormat,
const QStringList & theConfigOptions, const QString & fileFormat );

signals:
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 );
@@ -59,8 +59,10 @@ class QgsRasterFileWriter
void setMaxTileHeight( int h );
int maxTileHeight() const;

// for now not putting createOptions in all methods, use createOptions()
void setCreateOptions( const QStringList& list );
QStringList createOptions() const;

QStringList pyramidsConfigOptions() const;
void setPyramidsConfigOptions( const QStringList& list );
};

@@ -24,8 +24,10 @@ class QgsRasterFormatSaveOptionsWidget : QWidget
void setFormat( QString format );
void setProvider( QString provider );
void setRasterLayer( QgsRasterLayer* rasterLayer );
void setRasterFileName( const QString& file );
QStringList options() const;
void setType( QgsRasterFormatSaveOptionsWidget::Type type = Default );
void setPyramidsFormat( QgsRasterDataProvider::RasterPyramidsFormat format );

public slots:

@@ -48,10 +48,11 @@ class QgsRasterLayerSaveAsDialog : QDialog
QgsRectangle outputRectangle() const;
QList<QgsRasterNuller::NoData> noData() const;

QList< int > overviewList() const;
QList< int > pyramidsList() const;
QgsRasterDataProvider::RasterBuildPyramids buildPyramidsFlag() const;
QString pyramidsResampling() const;
QString pyramidsResamplingMethod() const;
QgsRasterDataProvider::RasterPyramidsFormat pyramidsFormat() const;
QStringList pyramidsConfigOptions() const;

void hideFormat();
void hideOutput();
@@ -12,17 +12,26 @@ class QgsRasterPyramidsOptionsWidget: QWidget
QgsRasterPyramidsOptionsWidget( QWidget* parent = 0, QString provider = "gdal" );
~QgsRasterPyramidsOptionsWidget();

QStringList createOptions() const;
QStringList configOptions() const;
QgsRasterFormatSaveOptionsWidget* createOptionsWidget() /Factory/;
const QList<int> overviewList() const;
QgsRasterDataProvider::RasterPyramidsFormat pyramidsFormat() const;
QString resamplingMethod() const;
void setRasterLayer( QgsRasterLayer* rasterLayer );
void setRasterFileName( const QString& file );

public slots:

void apply();
void checkAllLevels( bool checked );

private slots:

void on_cbxPyramidsLevelsCustom_toggled( bool toggled );
void on_cbxPyramidsFormat_currentIndexChanged( int index );
void setOverviewList();
void updateUi();

signals:
void overviewListChanged();
};
@@ -97,7 +97,7 @@ def initGui( self ):
return None

from tools.GdalTools_utils import Version, GdalConfig, LayerRegistry
self.GdalVersion = Version( GdalConfig.version() )
self.GdalVersionNum = GdalConfig.versionNum()
LayerRegistry.setIface( self.iface )

# find the Raster menu
@@ -141,13 +141,13 @@ def initGui( self ):
# conversion menu (Rasterize (Vector to raster), Polygonize (Raster to vector), Translate, RGB to PCT, PCT to RGB)
self.conversionMenu = QMenu( QCoreApplication.translate( "GdalTools", "Conversion" ), self.iface.mainWindow() )

if self.GdalVersion >= "1.3":
if self.GdalVersionNum >= 1300:
self.rasterize = QAction( QIcon(":/icons/rasterize.png"), QCoreApplication.translate( "GdalTools", "Rasterize (Vector to raster)" ), self.iface.mainWindow() )
self.rasterize.setStatusTip( QCoreApplication.translate( "GdalTools", "Burns vector geometries into a raster") )
QObject.connect( self.rasterize, SIGNAL( "triggered()" ), self.doRasterize )
self.conversionMenu.addAction( self.rasterize )

if self.GdalVersion >= "1.6":
if self.GdalVersionNum >= 1600:
self.polygonize = QAction( QIcon(":/icons/polygonize.png"), QCoreApplication.translate( "GdalTools", "Polygonize (Raster to vector)" ), self.iface.mainWindow() )
self.polygonize.setStatusTip( QCoreApplication.translate( "GdalTools", "Produces a polygon feature layer from a raster") )
QObject.connect( self.polygonize, SIGNAL( "triggered()" ), self.doPolygonize )
@@ -170,7 +170,7 @@ def initGui( self ):
# extraction menu (Clipper, Contour)
self.extractionMenu = QMenu( QCoreApplication.translate( "GdalTools", "Extraction" ), self.iface.mainWindow() )

if self.GdalVersion >= "1.6":
if self.GdalVersionNum >= 1600:
self.contour = QAction( QIcon(":/icons/contour.png"), QCoreApplication.translate( "GdalTools", "Contour" ), self.iface.mainWindow() )
self.contour.setStatusTip( QCoreApplication.translate( "GdalTools", "Builds vector contour lines from a DEM") )
QObject.connect( self.contour, SIGNAL( "triggered()" ), self.doContour )
@@ -185,37 +185,37 @@ def initGui( self ):
# analysis menu (DEM (Terrain model), Grid (Interpolation), Near black, Proximity (Raster distance), Sieve)
self.analysisMenu = QMenu( QCoreApplication.translate( "GdalTools", "Analysis" ), self.iface.mainWindow() )

if self.GdalVersion >= "1.6":
if self.GdalVersionNum >= 1600:
self.sieve = QAction( QIcon(":/icons/sieve.png"), QCoreApplication.translate( "GdalTools", "Sieve" ), self.iface.mainWindow() )
self.sieve.setStatusTip( QCoreApplication.translate( "GdalTools", "Removes small raster polygons") )
QObject.connect( self.sieve, SIGNAL( "triggered()" ), self.doSieve )
self.analysisMenu.addAction( self.sieve )

if self.GdalVersion >= "1.5":
if self.GdalVersionNum >= 1500:
self.nearBlack = QAction( QIcon(":/icons/nearblack.png"), QCoreApplication.translate( "GdalTools", "Near black" ), self.iface.mainWindow() )
self.nearBlack.setStatusTip( QCoreApplication.translate( "GdalTools", "Convert nearly black/white borders to exact value") )
QObject.connect( self.nearBlack, SIGNAL( "triggered()" ), self.doNearBlack )
self.analysisMenu.addAction( self.nearBlack )

if self.GdalVersion >= "1.7":
if self.GdalVersionNum >= 1700:
self.fillNodata = QAction( QIcon(":/icons/fillnodata.png"), QCoreApplication.translate( "GdalTools", "Fill nodata" ), self.iface.mainWindow() )
self.fillNodata.setStatusTip( QCoreApplication.translate( "GdalTools", "Fill raster regions by interpolation from edges") )
QObject.connect( self.fillNodata, SIGNAL( "triggered()" ), self.doFillNodata )
self.analysisMenu.addAction( self.fillNodata )

if self.GdalVersion >= "1.6":
if self.GdalVersionNum >= 1600:
self.proximity = QAction( QIcon(":/icons/proximity.png"), QCoreApplication.translate( "GdalTools", "Proximity (Raster distance)" ), self.iface.mainWindow() )
self.proximity.setStatusTip( QCoreApplication.translate( "GdalTools", "Produces a raster proximity map") )
QObject.connect( self.proximity, SIGNAL( "triggered()" ), self.doProximity )
self.analysisMenu.addAction( self.proximity )

if self.GdalVersion >= "1.5":
if self.GdalVersionNum >= 1500:
self.grid = QAction( QIcon(":/icons/grid.png"), QCoreApplication.translate( "GdalTools", "Grid (Interpolation)" ), self.iface.mainWindow() )
self.grid.setStatusTip( QCoreApplication.translate( "GdalTools", "Create raster from the scattered data") )
QObject.connect( self.grid, SIGNAL( "triggered()" ), self.doGrid )
self.analysisMenu.addAction( self.grid )

if self.GdalVersion >= "1.7":
if self.GdalVersionNum >= 1700:
self.dem = QAction( QIcon( ":icons/dem.png" ), QCoreApplication.translate( "GdalTools", "DEM (Terrain models)" ), self.iface.mainWindow() )
self.dem.setStatusTip( QCoreApplication.translate( "GdalTools", "Tool to analyze and visualize DEMs" ) )
QObject.connect( self.dem, SIGNAL( "triggered()" ), self.doDEM )
@@ -226,7 +226,7 @@ def initGui( self ):
# miscellaneous menu (Build overviews (Pyramids), Tile index, Information, Merge, Build Virtual Raster (Catalog))
self.miscellaneousMenu = QMenu( QCoreApplication.translate( "GdalTools", "Miscellaneous" ), self.iface.mainWindow() )

if self.GdalVersion >= "1.6":
if self.GdalVersionNum >= 1600:
self.buildVRT = QAction( QIcon(":/icons/vrt.png"), QCoreApplication.translate( "GdalTools", "Build Virtual Raster (Catalog)" ), self.iface.mainWindow() )
self.buildVRT.setStatusTip( QCoreApplication.translate( "GdalTools", "Builds a VRT from a list of datasets") )
QObject.connect( self.buildVRT, SIGNAL( "triggered()" ), self.doBuildVRT )
@@ -499,6 +499,10 @@ class GdalConfig:
def version(self):
return Version(gdal.VersionInfo("RELEASE_NAME"))

@classmethod
def versionNum(self):
return int(gdal.VersionInfo("VERSION_NUM"))

# store the supported rasters info
supportedRasters = None

@@ -844,6 +848,7 @@ def setMacOSXDefaultEnvironment():
qgis_standalone_gdal_path = u"%s/Frameworks/GDAL.framework" % qgis_app

# path to the GDAL framework when installed as external framework
# TODO adjust this for gdal 1.10
gdal_bin_path = u"/Library/Frameworks/GDAL.framework/Versions/%s/Programs" % str(GdalConfig.version())[:3]

if os.path.exists( qgis_standalone_gdal_path ): # qgis standalone
@@ -60,15 +60,17 @@ def __init__(self, iface):
self.configSelector.setFilename(colorConfigFile)

self.outputFormat = Utils.fillRasterOutputFormat()
self.creationOptionsWidget.setFormat(self.outputFormat)

self.setParamsStatus(
[
(self.inSelector, SIGNAL("filenameChanged()")),
(self.outSelector, SIGNAL("filenameChanged()")),
(self.computeEdgesCheck, SIGNAL("stateChanged(int)"), None, "1.8.0"),
(self.computeEdgesCheck, SIGNAL("stateChanged(int)"), None, 1800),
(self.bandSpin, SIGNAL("valueChanged(int)"), self.bandCheck),
(self.algorithmCheck, SIGNAL("stateChanged(int)"), None, "1.8.0"),
(self.creationOptionsTable, [SIGNAL("cellValueChanged(int, int)"), SIGNAL("rowRemoved()")], self.creationGroupBox),
(self.algorithmCheck, SIGNAL("stateChanged(int)"), None, 1800),
(self.creationOptionsWidget, SIGNAL("optionsChanged()")),
(self.creationOptionsGroupBox, SIGNAL("toggled(bool)")),
(self.modeCombo, SIGNAL("currentIndexChanged(int)")),
([self.hillshadeZFactorSpin, self.hillshadeScaleSpin, self.hillshadeAltitudeSpin, self.hillshadeAzimuthSpin], SIGNAL("valueChanged(double)")),
(self.slopeScaleSpin, SIGNAL("valueChanged(double)")),
@@ -102,6 +104,7 @@ def fillInputFileEdit(self):
Utils.FileFilter.setLastUsedRasterFilter(lastUsedFilter)

self.inSelector.setFilename(inputFile)
self.getArguments()

def fillOutputFileEdit(self):
lastUsedFilter = Utils.FileFilter.lastUsedRasterFilter()
@@ -112,6 +115,7 @@ def fillOutputFileEdit(self):

self.outputFormat = Utils.fillRasterOutputFormat( lastUsedFilter, outputFile )
self.outSelector.setFilename(outputFile)
self.creationOptionsWidget.setFormat(self.outputFormat)

def fillColorConfigFileEdit(self):
configFile = Utils.FileDialog.getOpenFileName(self, self.tr( "Select the color configuration file" ))
@@ -158,9 +162,15 @@ def getArguments(self):
arguments << "-b" << str(self.bandSpin.value())
if not outputFn.isEmpty():
arguments << "-of" << self.outputFormat
if self.creationGroupBox.isChecked():
for opt in self.creationOptionsTable.options():
if self.creationOptionsGroupBox.isChecked():
for opt in self.creationOptionsWidget.options():
arguments << "-co" << opt
# set creation options filename/layer for validation
if self.inSelector.layer():
self.creationOptionsWidget.setRasterLayer(self.inSelector.layer())
else:
self.creationOptionsWidget.setRasterFileName(self.getInputFileName())

return arguments

def getInputFileName(self):
@@ -54,21 +54,24 @@ def __init__( self, iface ):

self.setParamsStatus(
[
(self.inSelector, SIGNAL("filenameChanged()")),
( self.inSelector, SIGNAL("filenameChanged()")),
( self.algorithmCombo, SIGNAL( "currentIndexChanged( int )" ), self.algorithmCheck ),
( self.levelsEdit, SIGNAL( "textChanged( const QString & )" ) ),
( self.roModeCheck, SIGNAL( "stateChanged( int )" ), None, "1.6.0" ),
( self.roModeCheck, SIGNAL( "stateChanged( int )" ), None, 1600 ),
( self.rrdCheck, SIGNAL( "stateChanged(int)" ) ),
( self.jpegQualitySpin, SIGNAL( "valueChanged (int)" ) ),
( self.jpegQualityContainer, None, self.tiffjpegCheck),
( self.jpegQualityContainer, None, None, "1.7.0"),
( self.cleanCheck, SIGNAL( "stateChanged(int)" ), None, "1.7.0" )
( self.jpegQualityContainer, None, None, 1700),
( self.cleanCheck, SIGNAL( "stateChanged(int)" ), None, 1700 ),
( self.mPyramidOptionsWidget, SIGNAL( "overviewListChanged()" )),
( self.mPyramidOptionsWidget, SIGNAL( "someValueChanged()" ))
]
)

self.connect( self.inSelector, SIGNAL( "selectClicked()" ), self.fillInputFile )
self.connect( self.batchCheck, SIGNAL( "stateChanged( int )" ), self.switchToolMode )

self.init = False #workaround bug that pyramid options widgets are not initialized at first

# switch to batch or normal mode
def switchToolMode( self ):
@@ -101,6 +104,8 @@ def fillInputFile( self ):

self.inSelector.setFilename( inputFile )

self.mPyramidOptionsWidget.setRasterLayer(None)

def fillInputDir( self ):
inputDir = Utils.FileDialog.getExistingDirectory( self, self.tr( "Select the input directory with files" ))
if inputDir.isEmpty():
@@ -110,27 +115,44 @@ def fillInputDir( self ):

def getArguments( self ):
arguments = QStringList()
if self.algorithmCheck.isChecked() and self.algorithmCombo.currentIndex() >= 0:
arguments << "-r"
arguments << self.resampling_method[self.algorithmCombo.currentIndex()]
if self.roModeCheck.isChecked():

arguments << "-r"
arguments << self.mPyramidOptionsWidget.resamplingMethod();

format = self.mPyramidOptionsWidget.pyramidsFormat()
if format == QgsRasterDataProvider.PyramidsGTiff:
arguments << "-ro"
if self.rrdCheck.isChecked():
elif format == QgsRasterDataProvider.PyramidsErdas:
arguments << "--config" << "USE_RRD" << "YES"
if self.tiffjpegCheck.isChecked():
arguments << "--config" << "COMPRESS_OVERVIEW" << "JPEG" << "--config" << "PHOTOMETRIC_OVERVIEW" << "YCBCR" << "--config" << "INTERLEAVE_OVERVIEW" << "PIXEL"
if self.jpegQualityContainer.isVisible():
arguments << "--config" << "JPEG_QUALITY_OVERVIEW" << self.jpegQualitySpin.cleanText()

for option in self.mPyramidOptionsWidget.configOptions():
(k,v) = option.split("=")
arguments << "--config" << str(k) << str(v)

if self.cleanCheck.isChecked():
arguments << "-clean"

if self.isBatchEnabled():
return arguments

arguments << self.getInputFileName()
if not self.levelsEdit.text().isEmpty():
arguments << self.levelsEdit.text().split( " " )

if len(self.mPyramidOptionsWidget.overviewList()) == 0:
arguments << "[levels]"
for level in self.mPyramidOptionsWidget.overviewList():
arguments << str(level)

# set creation options filename/layer for validation
if self.init:
if self.isBatchEnabled():
self.mPyramidOptionsWidget.setRasterLayer(None)
elif self.inSelector.layer():
self.mPyramidOptionsWidget.setRasterLayer(self.inSelector.layer())
else:
self.mPyramidOptionsWidget.setRasterFileName(self.getInputFileName())
else:
arguments << "2" << "4" << "8" << "16" << "32"
self.init = True

return arguments

def getInputFileName( self ):
Loading

0 comments on commit 9dffa42

Please sign in to comment.