Skip to content

Commit

Permalink
Merge pull request #1843 from radosuav/processing_sublayers
Browse files Browse the repository at this point in the history
[Processing] Add support for input rasters with sublayers.
  • Loading branch information
volaya committed Jan 21, 2015
2 parents 8f6b014 + 82f043c commit c1f60e3
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 11 deletions.
7 changes: 5 additions & 2 deletions python/plugins/processing/algs/grass/GrassAlgorithm.py
Expand Up @@ -472,11 +472,14 @@ def setSessionProjectionFromLayer(self, layer, commands):
def exportRasterLayer(self, layer):
destFilename = self.getTempFilename()
self.exportedLayers[layer] = destFilename
command = 'r.external'
if bool(re.match('netcdf', layer, re.I)) or bool(re.match('hdf', layer, re.I)):
command = 'r.in.gdal'
else:
command = 'r.external -r'
command += ' input="' + layer + '"'
command += ' band=1'
command += ' output=' + destFilename
command += ' --overwrite -o -r'
command += ' --overwrite -o'
return command

def getTempFilename(self):
Expand Down
11 changes: 8 additions & 3 deletions python/plugins/processing/core/parameters.py
Expand Up @@ -32,7 +32,6 @@
from processing.tools.system import *
from processing.tools import dataobjects


def getParameterFromString(s):
tokens = s.split("|")
params = [t if unicode(t) != "None" else None for t in tokens[1:]]
Expand Down Expand Up @@ -463,8 +462,9 @@ def getValueAsCommandLineParameter(self):

class ParameterRaster(ParameterDataObject):

def __init__(self, name='', description='', optional=False):
def __init__(self, name='', description='', optional=False, showSublayersDialog = True):
ParameterDataObject.__init__(self, name, description)
self.showSublayersDialog = parseBool(showSublayersDialog)
self.optional = parseBool(optional)
self.value = None
self.exported = None
Expand Down Expand Up @@ -515,7 +515,12 @@ def setValue(self, obj):
if layer.name() == self.value:
self.value = unicode(layer.dataProvider().dataSourceUri())
return True
return os.path.exists(self.value)
if os.path.exists(self.value) or QgsRasterLayer(self.value).isValid():
return True
else:
# Layer could not be found
return False


def getFileFilter(self):
exts = dataobjects.getSupportedOutputRasterLayerExtensions()
Expand Down
8 changes: 4 additions & 4 deletions python/plugins/processing/gui/BatchInputSelectionPanel.py
Expand Up @@ -127,13 +127,13 @@ def showFileSelectionDialog(self):
self.tr('All files(*.*);;') + self.param.getFileFilter())
if ret:
files = list(ret)
if len(files) == 1:
settings.setValue('/Processing/LastInputPath',
settings.setValue('/Processing/LastInputPath',
os.path.dirname(unicode(files[0])))
for i, filename in enumerate(files):
files[i] = dataobjects.getRasterSublayer(filename, self.param)
if len(files) == 1:
self.text.setText(files[0])
else:
settings.setValue('/Processing/LastInputPath',
os.path.dirname(unicode(files[0])))
if isinstance(self.param, ParameterMultipleInput):
self.text.setText(';'.join(unicode(f) for f in files))
else:
Expand Down
7 changes: 5 additions & 2 deletions python/plugins/processing/gui/InputLayerSelectorPanel.py
Expand Up @@ -29,6 +29,7 @@

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from processing.tools import dataobjects

from processing.ui.ui_widgetLayerSelector import Ui_Form

Expand Down Expand Up @@ -65,10 +66,12 @@ def showSelectionDialog(self):
filename = QFileDialog.getOpenFileName(self, self.tr('Select file'),
path, self.tr('All files (*.*);;') + self.param.getFileFilter())
if filename:
self.cmbText.addItem(filename, filename)
self.cmbText.setCurrentIndex(self.cmbText.count() - 1)
settings.setValue('/Processing/LastInputPath',
os.path.dirname(unicode(filename)))
filename = dataobjects.getRasterSublayer(filename, self.param)
self.cmbText.addItem(filename, filename)
self.cmbText.setCurrentIndex(self.cmbText.count() - 1)


def getValue(self):
return self.cmbText.itemData(self.cmbText.currentIndex())
52 changes: 52 additions & 0 deletions python/plugins/processing/tools/dataobjects.py
Expand Up @@ -26,7 +26,9 @@
__revision__ = '$Format:%H$'

from os import path
import re
from qgis.core import *
from qgis.gui import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.utils import iface
Expand Down Expand Up @@ -373,3 +375,53 @@ def exportTable(table):
return filename[:-3] + 'dbf'
else:
return filename

def getRasterSublayer(path, param):

layer = QgsRasterLayer(path)

try:
# If the layer is a raster layer and has multiple sublayers, let the user chose one.
# # Based on QgisApp::askUserForGDALSublayers
if layer and param.showSublayersDialog and layer.dataProvider().name() == "gdal" and len(layer.subLayers()) > 1:
layers = []
subLayerNum = 0
# simplify raster sublayer name
for subLayer in layer.subLayers():
# if netcdf/hdf use all text after filename
if bool(re.match('netcdf', subLayer, re.I)) or bool(re.match('hdf', subLayer, re.I)):
subLayer = subLayer.split(path)[1]
subLayer = subLayer[1:]
else:
# remove driver name and file name
subLayer.replace(subLayer.split(":")[0], "")
subLayer.replace(path, "")
# remove any : or " left over
if subLayer.startswith(":"):
subLayer = subLayer[1:]
if subLayer.startswith("\""):
subLayer = subLayer[1:]
if subLayer.endswith(":"):
subLayer = subLayer[:-1]
if subLayer.endswith("\""):
subLayer = subLayer[:-1]

layers.append(str(subLayerNum)+"|"+subLayer)
subLayerNum = subLayerNum + 1

# Use QgsSublayersDialog
# Would be good if QgsSublayersDialog had an option to allow only one sublayer to be selected
chooseSublayersDialog = QgsSublayersDialog(QgsSublayersDialog.Gdal, "gdal")
chooseSublayersDialog.populateLayerTable( layers, "|" )

if chooseSublayersDialog.exec_():
return layer.subLayers()[chooseSublayersDialog.selectionIndexes()[0]]
else:
# If user pressed cancel then just return the input path
return path
else:
# If the sublayers selection dialog is not to be shown then just return the input path
return path
except:
# If the layer is not a raster layer, then just return the input path
return path

0 comments on commit c1f60e3

Please sign in to comment.