Skip to content

Commit 9dffa42

Browse files
committedJan 28, 2013
Merge pull request #394 from etiennesky/gdaltools1
GdalTools - use raster format save option and pyramids dialogs
2 parents 8c89c2a + c279ec2 commit 9dffa42

30 files changed

+1028
-627
lines changed
 

‎python/core/raster/qgsrasterdataprovider.sip

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -169,10 +169,11 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
169169
virtual QStringList subLayers() const;
170170

171171
/** \brief Create pyramid overviews */
172-
virtual QString buildPyramids( const QList<QgsRasterPyramid> & thePyramidList,
173-
const QString & theResamplingMethod = "NEAREST",
174-
RasterPyramidsFormat theFormat = PyramidsGTiff );
175-
172+
virtual QString buildPyramids( const QList<QgsRasterPyramid> & thePyramidList,
173+
const QString & theResamplingMethod = "NEAREST",
174+
RasterPyramidsFormat theFormat = PyramidsGTiff,
175+
const QStringList & theConfigOptions = QStringList() );
176+
176177
/** \brief Accessor for ths raster layers pyramid list.
177178
* @param overviewList used to construct the pyramid list (optional), when empty the list is defined by the provider.
178179
* A pyramid list defines the
@@ -269,13 +270,22 @@ class QgsRasterDataProvider : QgsDataProvider, QgsRasterInterface
269270
/** Remove dataset*/
270271
virtual bool remove();
271272

272-
static QStringList pyramidResamplingMethods( QString providerKey );
273+
/** Returns a list of pyramid resampling method names for given provider */
274+
static QStringList pyramidResamplingMethods( QString providerKey = "gdal" );
275+
/** Returns the pyramid resampling argument that corresponds to a given method */
276+
static QString pyramidResamplingArg( QString method, QString providerKey = "gdal" );
277+
278+
/** Validates creation options for a specific dataset and destination format.
279+
* @note used by GDAL provider only
280+
* @note see also validateCreationOptionsFormat() in gdal provider for validating options based on format only */
281+
virtual QString validateCreationOptions( const QStringList& createOptions, QString format );
273282

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

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

‎python/core/raster/qgsrasterfilewriter.sip

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ class QgsRasterFileWriter
5959
void setMaxTileHeight( int h );
6060
int maxTileHeight() const;
6161

62-
// for now not putting createOptions in all methods, use createOptions()
6362
void setCreateOptions( const QStringList& list );
6463
QStringList createOptions() const;
64+
65+
QStringList pyramidsConfigOptions() const;
66+
void setPyramidsConfigOptions( const QStringList& list );
6567
};
6668

‎python/gui/qgsrasterformatsaveoptionswidget.sip

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ class QgsRasterFormatSaveOptionsWidget : QWidget
2424
void setFormat( QString format );
2525
void setProvider( QString provider );
2626
void setRasterLayer( QgsRasterLayer* rasterLayer );
27+
void setRasterFileName( const QString& file );
2728
QStringList options() const;
2829
void setType( QgsRasterFormatSaveOptionsWidget::Type type = Default );
30+
void setPyramidsFormat( QgsRasterDataProvider::RasterPyramidsFormat format );
2931

3032
public slots:
3133

‎python/gui/qgsrasterlayersaveasdialog.sip

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ class QgsRasterLayerSaveAsDialog : QDialog
4848
QgsRectangle outputRectangle() const;
4949
QList<QgsRasterNuller::NoData> noData() const;
5050

51-
QList< int > overviewList() const;
51+
QList< int > pyramidsList() const;
5252
QgsRasterDataProvider::RasterBuildPyramids buildPyramidsFlag() const;
53-
QString pyramidsResampling() const;
53+
QString pyramidsResamplingMethod() const;
5454
QgsRasterDataProvider::RasterPyramidsFormat pyramidsFormat() const;
55+
QStringList pyramidsConfigOptions() const;
5556

5657
void hideFormat();
5758
void hideOutput();

‎python/gui/qgsrasterpyramidsoptionswidget.sip

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,26 @@ class QgsRasterPyramidsOptionsWidget: QWidget
1212
QgsRasterPyramidsOptionsWidget( QWidget* parent = 0, QString provider = "gdal" );
1313
~QgsRasterPyramidsOptionsWidget();
1414

15-
QStringList createOptions() const;
15+
QStringList configOptions() const;
1616
QgsRasterFormatSaveOptionsWidget* createOptionsWidget() /Factory/;
1717
const QList<int> overviewList() const;
1818
QgsRasterDataProvider::RasterPyramidsFormat pyramidsFormat() const;
1919
QString resamplingMethod() const;
20+
void setRasterLayer( QgsRasterLayer* rasterLayer );
21+
void setRasterFileName( const QString& file );
2022

2123
public slots:
2224

2325
void apply();
2426
void checkAllLevels( bool checked );
2527

28+
private slots:
29+
30+
void on_cbxPyramidsLevelsCustom_toggled( bool toggled );
31+
void on_cbxPyramidsFormat_currentIndexChanged( int index );
32+
void setOverviewList();
33+
void updateUi();
34+
2635
signals:
2736
void overviewListChanged();
2837
};

‎python/plugins/GdalTools/GdalTools.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def initGui( self ):
9797
return None
9898

9999
from tools.GdalTools_utils import Version, GdalConfig, LayerRegistry
100-
self.GdalVersion = Version( GdalConfig.version() )
100+
self.GdalVersionNum = GdalConfig.versionNum()
101101
LayerRegistry.setIface( self.iface )
102102

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

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

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

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

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

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

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

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

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

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

229-
if self.GdalVersion >= "1.6":
229+
if self.GdalVersionNum >= 1600:
230230
self.buildVRT = QAction( QIcon(":/icons/vrt.png"), QCoreApplication.translate( "GdalTools", "Build Virtual Raster (Catalog)" ), self.iface.mainWindow() )
231231
self.buildVRT.setStatusTip( QCoreApplication.translate( "GdalTools", "Builds a VRT from a list of datasets") )
232232
QObject.connect( self.buildVRT, SIGNAL( "triggered()" ), self.doBuildVRT )

‎python/plugins/GdalTools/tools/GdalTools_utils.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,10 @@ class GdalConfig:
499499
def version(self):
500500
return Version(gdal.VersionInfo("RELEASE_NAME"))
501501

502+
@classmethod
503+
def versionNum(self):
504+
return int(gdal.VersionInfo("VERSION_NUM"))
505+
502506
# store the supported rasters info
503507
supportedRasters = None
504508

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

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

849854
if os.path.exists( qgis_standalone_gdal_path ): # qgis standalone

‎python/plugins/GdalTools/tools/doDEM.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,17 @@ def __init__(self, iface):
6060
self.configSelector.setFilename(colorConfigFile)
6161

6262
self.outputFormat = Utils.fillRasterOutputFormat()
63+
self.creationOptionsWidget.setFormat(self.outputFormat)
6364

6465
self.setParamsStatus(
6566
[
6667
(self.inSelector, SIGNAL("filenameChanged()")),
6768
(self.outSelector, SIGNAL("filenameChanged()")),
68-
(self.computeEdgesCheck, SIGNAL("stateChanged(int)"), None, "1.8.0"),
69+
(self.computeEdgesCheck, SIGNAL("stateChanged(int)"), None, 1800),
6970
(self.bandSpin, SIGNAL("valueChanged(int)"), self.bandCheck),
70-
(self.algorithmCheck, SIGNAL("stateChanged(int)"), None, "1.8.0"),
71-
(self.creationOptionsTable, [SIGNAL("cellValueChanged(int, int)"), SIGNAL("rowRemoved()")], self.creationGroupBox),
71+
(self.algorithmCheck, SIGNAL("stateChanged(int)"), None, 1800),
72+
(self.creationOptionsWidget, SIGNAL("optionsChanged()")),
73+
(self.creationOptionsGroupBox, SIGNAL("toggled(bool)")),
7274
(self.modeCombo, SIGNAL("currentIndexChanged(int)")),
7375
([self.hillshadeZFactorSpin, self.hillshadeScaleSpin, self.hillshadeAltitudeSpin, self.hillshadeAzimuthSpin], SIGNAL("valueChanged(double)")),
7476
(self.slopeScaleSpin, SIGNAL("valueChanged(double)")),
@@ -102,6 +104,7 @@ def fillInputFileEdit(self):
102104
Utils.FileFilter.setLastUsedRasterFilter(lastUsedFilter)
103105

104106
self.inSelector.setFilename(inputFile)
107+
self.getArguments()
105108

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

113116
self.outputFormat = Utils.fillRasterOutputFormat( lastUsedFilter, outputFile )
114117
self.outSelector.setFilename(outputFile)
118+
self.creationOptionsWidget.setFormat(self.outputFormat)
115119

116120
def fillColorConfigFileEdit(self):
117121
configFile = Utils.FileDialog.getOpenFileName(self, self.tr( "Select the color configuration file" ))
@@ -158,9 +162,15 @@ def getArguments(self):
158162
arguments << "-b" << str(self.bandSpin.value())
159163
if not outputFn.isEmpty():
160164
arguments << "-of" << self.outputFormat
161-
if self.creationGroupBox.isChecked():
162-
for opt in self.creationOptionsTable.options():
165+
if self.creationOptionsGroupBox.isChecked():
166+
for opt in self.creationOptionsWidget.options():
163167
arguments << "-co" << opt
168+
# set creation options filename/layer for validation
169+
if self.inSelector.layer():
170+
self.creationOptionsWidget.setRasterLayer(self.inSelector.layer())
171+
else:
172+
self.creationOptionsWidget.setRasterFileName(self.getInputFileName())
173+
164174
return arguments
165175

166176
def getInputFileName(self):

‎python/plugins/GdalTools/tools/doOverview.py

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,24 @@ def __init__( self, iface ):
5454

5555
self.setParamsStatus(
5656
[
57-
(self.inSelector, SIGNAL("filenameChanged()")),
57+
( self.inSelector, SIGNAL("filenameChanged()")),
5858
( self.algorithmCombo, SIGNAL( "currentIndexChanged( int )" ), self.algorithmCheck ),
5959
( self.levelsEdit, SIGNAL( "textChanged( const QString & )" ) ),
60-
( self.roModeCheck, SIGNAL( "stateChanged( int )" ), None, "1.6.0" ),
60+
( self.roModeCheck, SIGNAL( "stateChanged( int )" ), None, 1600 ),
6161
( self.rrdCheck, SIGNAL( "stateChanged(int)" ) ),
6262
( self.jpegQualitySpin, SIGNAL( "valueChanged (int)" ) ),
6363
( self.jpegQualityContainer, None, self.tiffjpegCheck),
64-
( self.jpegQualityContainer, None, None, "1.7.0"),
65-
( self.cleanCheck, SIGNAL( "stateChanged(int)" ), None, "1.7.0" )
64+
( self.jpegQualityContainer, None, None, 1700),
65+
( self.cleanCheck, SIGNAL( "stateChanged(int)" ), None, 1700 ),
66+
( self.mPyramidOptionsWidget, SIGNAL( "overviewListChanged()" )),
67+
( self.mPyramidOptionsWidget, SIGNAL( "someValueChanged()" ))
6668
]
6769
)
6870

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

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

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

102105
self.inSelector.setFilename( inputFile )
103106

107+
self.mPyramidOptionsWidget.setRasterLayer(None)
108+
104109
def fillInputDir( self ):
105110
inputDir = Utils.FileDialog.getExistingDirectory( self, self.tr( "Select the input directory with files" ))
106111
if inputDir.isEmpty():
@@ -110,27 +115,44 @@ def fillInputDir( self ):
110115

111116
def getArguments( self ):
112117
arguments = QStringList()
113-
if self.algorithmCheck.isChecked() and self.algorithmCombo.currentIndex() >= 0:
114-
arguments << "-r"
115-
arguments << self.resampling_method[self.algorithmCombo.currentIndex()]
116-
if self.roModeCheck.isChecked():
118+
119+
arguments << "-r"
120+
arguments << self.mPyramidOptionsWidget.resamplingMethod();
121+
122+
format = self.mPyramidOptionsWidget.pyramidsFormat()
123+
if format == QgsRasterDataProvider.PyramidsGTiff:
117124
arguments << "-ro"
118-
if self.rrdCheck.isChecked():
125+
elif format == QgsRasterDataProvider.PyramidsErdas:
119126
arguments << "--config" << "USE_RRD" << "YES"
120-
if self.tiffjpegCheck.isChecked():
121-
arguments << "--config" << "COMPRESS_OVERVIEW" << "JPEG" << "--config" << "PHOTOMETRIC_OVERVIEW" << "YCBCR" << "--config" << "INTERLEAVE_OVERVIEW" << "PIXEL"
122-
if self.jpegQualityContainer.isVisible():
123-
arguments << "--config" << "JPEG_QUALITY_OVERVIEW" << self.jpegQualitySpin.cleanText()
127+
128+
for option in self.mPyramidOptionsWidget.configOptions():
129+
(k,v) = option.split("=")
130+
arguments << "--config" << str(k) << str(v)
131+
124132
if self.cleanCheck.isChecked():
125133
arguments << "-clean"
134+
126135
if self.isBatchEnabled():
127136
return arguments
128137

129138
arguments << self.getInputFileName()
130-
if not self.levelsEdit.text().isEmpty():
131-
arguments << self.levelsEdit.text().split( " " )
139+
140+
if len(self.mPyramidOptionsWidget.overviewList()) == 0:
141+
arguments << "[levels]"
142+
for level in self.mPyramidOptionsWidget.overviewList():
143+
arguments << str(level)
144+
145+
# set creation options filename/layer for validation
146+
if self.init:
147+
if self.isBatchEnabled():
148+
self.mPyramidOptionsWidget.setRasterLayer(None)
149+
elif self.inSelector.layer():
150+
self.mPyramidOptionsWidget.setRasterLayer(self.inSelector.layer())
151+
else:
152+
self.mPyramidOptionsWidget.setRasterFileName(self.getInputFileName())
132153
else:
133-
arguments << "2" << "4" << "8" << "16" << "32"
154+
self.init = True
155+
134156
return arguments
135157

136158
def getInputFileName( self ):

0 commit comments

Comments
 (0)
Please sign in to comment.