Skip to content


improved management of tables in SEXTANTE
Browse files Browse the repository at this point in the history
  • Loading branch information
volaya committed Feb 17, 2013
1 parent d8ec492 commit 3aadcfa
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 25 deletions.
3 changes: 2 additions & 1 deletion python/plugins/sextante/
Expand Up @@ -17,7 +17,8 @@

from sextante.core.Sextante import runalg, runandload, alghelp, alglist, algoptions, load, loadFromAlg, extent, getObjectFromName, getObjectFromUri, features
from sextante.core.Sextante import runalg, runandload, alghelp, alglist, algoptions, load, loadFromAlg, \
extent, getObjectFromName, getObjectFromUri, getobject, getfeatures

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
Expand Down
37 changes: 36 additions & 1 deletion python/plugins/sextante/core/
Expand Up @@ -44,7 +44,8 @@ def exportVectorLayer(layer):
a remote one or db-based (non-file based) one, or if there is a selection and it should be
used, exporting just the selected features.
Currently, the output is restricted to shapefiles, so anything that is not in a shapefile
will get exported'''
will get exported.
It also export to a new file if the original one contains non-ascii characters'''
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = SextanteUtils.getTempFilename("shp")
Expand Down Expand Up @@ -91,4 +92,38 @@ def exportRasterLayer(layer):
#TODO:Do the conversion here
return unicode(layer.source())

def exportTable( table):
'''Takes a QgsVectorLayer and returns the filename to refer to its attributes table,
which allows external apps which support only file-based layers to use it.
It performs the necessary export in case the input layer is not in a standard format
suitable for most applications, it isa remote one or db-based (non-file based) one
Currently, the output is restricted to dbf.
It also export to a new file if the original one contains non-ascii characters'''
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = SextanteUtils.getTempFilename("dbf")
provider = table.dataProvider()
except UnicodeEncodeError:
isDbf = unicode(table.source()).endswith("dbf") or unicode(table.source()).endswith("shp")
if (not isDbf or not isASCII):
writer = QgsVectorFileWriter( output, systemEncoding, provider.fields(), QGis.WKBNoGeometry, )
for feat in table.getFeatures():
del writer
return output
filename = unicode(table.source())
if unicode(table.source()).endswith("shp"):
return filename[:-3] + "dbf"
return filename

4 changes: 1 addition & 3 deletions python/plugins/sextante/core/
Expand Up @@ -99,9 +99,7 @@ def getTables():
tables = list()
for layer in layers:
if layer.type() == layer.VectorLayer :
uri = unicode(layer.source())
if uri.lower().endswith("csv") or uri.lower().endswith("dbf") or uri.lower().endswith("shp"):
return tables

Expand Down
8 changes: 7 additions & 1 deletion python/plugins/sextante/core/
Expand Up @@ -416,11 +416,17 @@ def getObjectFromName(name):
def getObjectFromUri(uri):
return QGisLayers.getObjectFromUri(uri, False)

def getobject(uriorname):
ret = getObjectFromName(uriorname)
if ret is None:
ret = getObjectFromUri(uriorname)
return ret

def load(path):
'''Loads a layer into QGIS'''
return QGisLayers.load(path)

def features(layer):
def getfeatures(layer):
return QGisLayers.features(layer)

def loadFromAlg(layersdict):
Expand Down
8 changes: 6 additions & 2 deletions python/plugins/sextante/core/
Expand Up @@ -40,12 +40,16 @@ def __init__(self, fileName, encoding, fields):
if not fileName.endswith("csv"):
fileName += ".csv"
file = open(fileName, "w")
file.write(";".join( for field in fields))
file.write(";".join(unicode( for field in fields))

def addRecord(self, values):
for i in range(len(values)):
if isinstance(values[i], QVariant):
values[i] = values[i].toString()

file = open(self.fileName, "a")
file.write(";".join([value.toString() for value in values]))
file.write(";".join([unicode(value) for value in values]))
12 changes: 1 addition & 11 deletions python/plugins/sextante/gui/
Expand Up @@ -74,17 +74,7 @@ def updateTree(self):

def configureProviders(self):"")
# #QDesktopServices.openUrl(QUrl(os.path.join(os.path.dirname(__file__), os.path.pardir) + "/help/3rdParty.html"))
# filename = os.path.join(os.path.dirname(__file__), "..", "help", "3rdParty.html")
# if == "nt":
# os.startfile(filename)
# elif sys.platform == "darwin":
# subprocess.Popen(('open', filename))
# else:
#'xdg-open', filename))

def showPopupMenu(self,point):
item = self.algorithmTree.itemAt(point)
Expand Down
5 changes: 3 additions & 2 deletions python/plugins/sextante/outputs/
Expand Up @@ -31,6 +31,7 @@

class OutputTable(Output):

encoding = None
compatible = None

def getFileFilter(self,alg):
Expand All @@ -47,7 +48,7 @@ def getCompatibleFileName(self, alg):
If the algorithm supports the file format of the current output value, it returns that value. If not,
it returns a temporary file with a supported file format, to be used to generate the output result.'''
ext = self.value[self.value.rfind(".") + 1:]
if ext in alg.provider.getSupportedOutputTableExtensions:
if ext in alg.provider.getSupportedOutputTableExtensions():
return self.value
if self.compatible is None:
Expand All @@ -59,7 +60,7 @@ def getTableWriter(self, fields):
result of the algorithm. Use this to transparently handle output
values instead of creating your own method.
@param fields a dict of int-QgsField
@param fields a list of QgsField
@return writer instance of the table writer class
Expand Down
22 changes: 22 additions & 0 deletions python/plugins/sextante/parameters/
Expand Up @@ -17,6 +17,7 @@
import os
from sextante.core.LayerExporter import LayerExporter

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
Expand All @@ -34,8 +35,10 @@ def __init__(self, name="", description="", optional=False):
ParameterDataObject.__init__(self, name, description)
self.optional = optional
self.value = None
self.exported = None

def setValue(self, obj):
self.exported = None
if obj == None:
if self.optional:
self.value = None
Expand All @@ -56,6 +59,25 @@ def setValue(self, obj):
val = unicode(obj)
self.value = val
return os.path.exists(self.value)

def getSafeExportedTable(self):
'''Returns not the value entered by the user, but a string with a filename which
contains the data of this table, but saved in a standard format (currently always
a dbf file) so that it can be opened by most external applications.
Works only if the table represented by the parameter value is currently loaded in QGIS.
Otherwise, it will not perform any export and return the current value string.
If the current value represents a table in a suitable format, it does not export at all
and returns that value.
The table is exported just the first time the method is called. The method can be called
several times and it will always return the same file, performing the export only the first time.'''
if self.exported:
return self.exported
table = QGisLayers.getObjectFromUri(self.value, False)
if table:
self.exported = LayerExporter.exportTable(table)
self.exported = self.value
return self.exported

def serialize(self):
return self.__module__.split(".")[-1] + "|" + + "|" + self.description +\
Expand Down
11 changes: 7 additions & 4 deletions python/plugins/sextante/saga/
Expand Up @@ -204,9 +204,12 @@ def processAlgorithm(self, progress):
if isinstance(param, ParameterTable):
if param.value == None:
value = param.value
if not value.endswith("dbf"):
raise GeoAlgorithmExecutionException("Unsupported file format")
table = QGisLayers.getObjectFromUri(param.value, False)
if table:
filename = LayerExporter.exportTable(table)
elif not param.value.endswith("shp"):
raise GeoAlgorithmExecutionException("Unsupported file format")
if isinstance(param, ParameterMultipleInput):
if param.value == None:
Expand Down Expand Up @@ -237,7 +240,7 @@ def processAlgorithm(self, progress):
for param in self.parameters:
if param.value is None:
if isinstance(param, (ParameterRaster, ParameterVector)):
if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)):
value = param.value
if value in self.exportedLayers.keys():
command+=(" -" + + " \"" + self.exportedLayers[value] + "\"")
Expand Down

0 comments on commit 3aadcfa

Please sign in to comment.