Skip to content
Permalink
Browse files
added support for all gdal/ogr formats in all providers
added support for pre and post execution hooks
  • Loading branch information
volaya committed Jan 21, 2013
1 parent c58c9da commit 995ede35262422223645b6262d58f3f5213e0c89
@@ -17,6 +17,9 @@
from sextante.outputs.OutputTable import OutputTable
from sextante.outputs.OutputHTML import OutputHTML
import copy
from sextante.core.SextanteVectorWriter import SextanteVectorWriter
from sextante.core.SextanteConfig import SextanteConfig
from sextante.gdal.GdalUtils import GdalUtils

class GeoAlgorithm:

@@ -103,18 +106,23 @@ def checkParameterValuesBeforeExecuting(self):
This check is called from the parameters dialog, and also when calling from the console'''
return None
#=========================================================



def execute(self, progress):
'''The method to use to call a SEXTANTE algorithm.
Although the body of the algorithm is in processAlgorithm(),
it should be called using this method, since it performs
some additional operations.
Raises a GeoAlgorithmExecutionException in case anything goes wrong.'''
self.setOutputCRSFromInputLayers()
self.resolveTemporaryOutputs()
self.checkOutputFileExtensions()

try:
self.processAlgorithm(progress)
self.setOutputCRSFromInputLayers()
self.resolveTemporaryOutputs()
self.checkOutputFileExtensions()
self.runPreExecutionScript(progress)
self.processAlgorithm(progress)
self.convertUnsupportedFormats(progress)
self.runPostExecutionScript(progress)
except GeoAlgorithmExecutionException, gaee:
SextanteLog.addToLog(SextanteLog.LOG_ERROR, gaee.msg)
raise gaee
@@ -132,6 +140,62 @@ def execute(self, progress):
SextanteLog.addToLog(SextanteLog.LOG_ERROR, lines)
raise GeoAlgorithmExecutionException(errstring)


def runPostExecutionScript(self, progress):
scriptFile = SextanteConfig.getSetting(SextanteConfig.POST_EXECUTION_SCRIPT)
self.runHookScript(scriptFile, progress);

def runPreExecutionScript(self, progress):
scriptFile = SextanteConfig.getSetting(SextanteConfig.PRE_EXECUTION_SCRIPT)
self.runHookScript(scriptFile, progress);

def runHookScript(self, filename, progress):
if not os.path.exists(filename):
return
try:
script = "import sextante\n"
ns = {}
ns['progress'] = progress
ns['alg'] = self
f = open(filename)
lines = f.readlines()
for line in lines:
script+=line
exec(script) in ns
except: # a wrong script should not cause problems, so we swallow all exceptions
pass

def convertUnsupportedFormats(self, progress):
i = 0
progress.setText("Converting outputs")
for out in self.outputs:
if isinstance(out, OutputVector):
if out.compatible is not None:
layer = QGisLayers.getObjectFromUri(out.compatible)
provider = layer.dataProvider()
writer = out.getVectorWriter( provider.fields(), provider.geometryType(), provider.crs())
features = QGisLayers.features(layer)
for feature in features:
writer.addFeature(feature)
elif isinstance(out, OutputRaster):
if out.compatible is not None:
layer = QGisLayers.getObjectFromUri(out.compatible)
provider = layer.dataProvider()
writer = QgsRasterFileWriter(out.value)
format = self.getFormatShortNameFromFilename(out.value)
writer.setOutputFormat(format);
writer.writeRaster(layer.pipe(), layer.width(), layer.height(), layer.extent(), layer.crs())
progress.setPercentage(100 * i / float(len(self.outputs)))

def getFormatShortNameFromFilename(self, filename):
ext = filename[filename.rfind(".")+1:]
supported = GdalUtils.getSupportedRasters()
for name in supported.keys():
exts = supported[name]
if ext in exts:
return name
return "GTiff"

def checkOutputFileExtensions(self):
'''Checks if the values of outputs are correct and have one of the supported output extensions.
If not, it adds the first one of the supported extensions, which is assumed to be the default one'''
@@ -140,11 +204,11 @@ def checkOutputFileExtensions(self):
if not os.path.isabs(out.value):
continue
if isinstance(out, OutputRaster):
exts = self.provider.getSupportedOutputRasterLayerExtensions()
exts = QGisLayers.getSupportedOutputRasterLayerExtensions()
elif isinstance(out, OutputVector):
exts = self.provider.getSupportedOutputVectorLayerExtensions()
exts = QGisLayers.getSupportedOutputVectorLayerExtensions()
elif isinstance(out, OutputTable):
exts = self.provider.getSupportedOutputTableExtensions()
exts = QGisLayers.getSupportedOutputTableExtensions()
elif isinstance(out, OutputHTML):
exts =["html", "htm"]
else:
@@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from sextante.gdal.GdalUtils import GdalUtils

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
@@ -37,6 +38,32 @@ class QGisLayers:
ALL_TYPES = -1
iface = None;

@staticmethod
def getSupportedOutputVectorLayerExtensions():
formats = QgsVectorFileWriter.supportedFiltersAndFormats()
exts = ["shp"]#shp is the default, should be the first
for extension in formats.keys():
extension = unicode(extension)
extension = extension[extension.find('*.') + 2:]
extension = extension[:extension.find(" ")]
if extension.lower() != "shp":
exts.append(extension)
return exts

@staticmethod
def getSupportedOutputRasterLayerExtensions():
allexts = ["tif"]
for exts in GdalUtils.getSupportedRasters().values():
for ext in exts:
if ext not in allexts:
allexts.append(ext)
return allexts

@staticmethod
def getSupportedOutputTableExtensions():
exts = ["dbf, csv"]
return exts

@staticmethod
def getRasterLayers():
layers = QGisLayers.iface.legendInterface().layers()
@@ -257,7 +257,7 @@ def runAlgorithm(algOrName, onFinish, *args):
alghelp(algOrName)
return

alg = alg.getCopy()#copy.deepcopy(alg)
alg = alg.getCopy()
if isinstance(args, dict):
# set params by name
for name, value in args.items():
@@ -306,7 +306,7 @@ def runAlgorithm(algOrName, onFinish, *args):
def finish():
QApplication.restoreOverrideCursor()
if onFinish is not None:
onFinish(alg)
onFinish(alg, SilentProgress())
progress.close()
def error(msg):
QApplication.restoreOverrideCursor()
@@ -325,9 +325,10 @@ def cancel():
algEx.start()
algEx.wait()
else:
ret = UnthreadedAlgorithmExecutor.runalg(alg, SilentProgress())
progress = SilentProgress()
ret = UnthreadedAlgorithmExecutor.runalg(alg, progress)
if onFinish is not None and ret:
onFinish(alg)
onFinish(alg, progress)
QApplication.restoreOverrideCursor()
return alg

@@ -43,6 +43,8 @@ class SextanteConfig():
USE_THREADS = "USE_THREADS"
SHOW_DEBUG_IN_DIALOG = "SHOW_DEBUG_IN_DIALOG"
RECENT_ALGORITHMS = "RECENT_ALGORITHMS"
PRE_EXECUTION_SCRIPT = "PRE_EXECUTION_SCRIPT"
POST_EXECUTION_SCRIPT = "POST_EXECUTION_SCRIPT"

settings = {}
settingIcons= {}
@@ -65,7 +67,11 @@ def initialize():
SextanteConfig.addSetting(Setting("General", SextanteConfig.VECTOR_POINT_STYLE,"Style for point layers",""))
SextanteConfig.addSetting(Setting("General", SextanteConfig.VECTOR_LINE_STYLE,"Style for line layers",""))
SextanteConfig.addSetting(Setting("General", SextanteConfig.VECTOR_POLYGON_STYLE,"Style for polygon layers",""))
SextanteConfig.addSetting(Setting("General", SextanteConfig.VECTOR_POLYGON_STYLE,"Style for polygon layers",""))
SextanteConfig.addSetting(Setting("General", SextanteConfig.PRE_EXECUTION_SCRIPT,"Pre-execution script",""))
SextanteConfig.addSetting(Setting("General", SextanteConfig.POST_EXECUTION_SCRIPT,"Post-execution script",""))
SextanteConfig.addSetting(Setting("General", SextanteConfig.RECENT_ALGORITHMS,"Recent algs","", hidden=True))


@staticmethod
def setGroupIcon(group, icon):
@@ -100,5 +100,7 @@ def createAlgsList(self):
def getSupportedOutputRasterLayerExtensions(self):
return GdalUtils.getSupportedRasterExtensions()

def getSupportedOutputVectorLayerExtensions(self):
return ["shp", "sqlite"]
#===========================================================================
# def getSupportedOutputVectorLayerExtensions(self):
# return ["shp", "sqlite"]
#===========================================================================
@@ -73,8 +73,10 @@ def getSupportedRasters():

shortName = str(QString(driver.ShortName).remove( QRegExp( '\(.*$' ) ).trimmed())
metadata = driver.GetMetadata()
if not metadata.has_key(gdal.DCAP_CREATE) or metadata[gdal.DCAP_CREATE] != 'YES':
continue
if metadata.has_key(gdal.DMD_EXTENSION):
extensions = metadata[gdal.DMD_EXTENSION].split("/")
extensions = metadata[gdal.DMD_EXTENSION].split("/")
if extensions:
GdalUtils.supportedRasters[shortName] = extensions

@@ -85,7 +87,7 @@ def getSupportedRasterExtensions():
allexts = ["tif"]
for exts in GdalUtils.getSupportedRasters().values():
for ext in exts:
if ext not in allexts:
if ext not in allexts and ext != "":
allexts.append(ext)
return allexts

@@ -286,8 +286,8 @@ def accept(self):

@pyqtSlot()
def finish(self):
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
SextantePostprocessing.handleAlgorithmResults(self.alg, not keepOpen)
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
SextantePostprocessing.handleAlgorithmResults(self.alg, self, not keepOpen)
self.executed = True
self.setInfo("Algorithm %s finished" % self.alg.name)
QApplication.restoreOverrideCursor()
@@ -38,9 +38,12 @@
class SextantePostprocessing:

@staticmethod
def handleAlgorithmResults(alg, showResults = True):
def handleAlgorithmResults(alg, progress, showResults = True):
htmlResults = False;
progress.setText("Loading resulting layers")
i = 0
for out in alg.outputs:
progress.setPercentage(100 * i / float(len(alg.outputs)))
if out.hidden or not out.open:
continue
if isinstance(out, (OutputRaster, OutputVector, OutputTable)):
@@ -59,6 +62,7 @@ def handleAlgorithmResults(alg, showResults = True):
elif isinstance(out, OutputHTML):
SextanteResults.addResult(out.description, out.value)
htmlResults = True
i += 1
if showResults and htmlResults:
QApplication.restoreOverrideCursor()
dlg = ResultsDialog()
@@ -84,7 +84,7 @@ def runalgIterating(alg,paramToIter,progress):
progress.setText("Executing iteration " + str(i) + "/" + str(len(filelist)) + "...")
progress.setPercentage((i * 100) / len(filelist))
if UnthreadedAlgorithmExecutor.runalg(alg, SilentProgress()):
SextantePostprocessing.handleAlgorithmResults(alg, False)
SextantePostprocessing.handleAlgorithmResults(alg, progress, False)
i+=1
else:
return False;
@@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from sextante.core.QGisLayers import QGisLayers

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
@@ -24,14 +25,28 @@
__revision__ = '$Format:%H$'

from sextante.outputs.Output import Output
from sextante.core.SextanteUtils import SextanteUtils

class OutputRaster(Output):


compatible = None

def getFileFilter(self, alg):
exts = alg.provider.getSupportedOutputRasterLayerExtensions()
exts = QGisLayers.getSupportedOutputRasterLayerExtensions()
for i in range(len(exts)):
exts[i] = exts[i].upper() + " files(*." + exts[i].lower() + ")"
return ";;".join(exts)

def getDefaultFileExtension(self, alg):
return alg.provider.getSupportedOutputRasterLayerExtensions()[0]

def getCompatibleFileName(self, alg):
'''Returns a filename that is compatible with the algorithm that is going to generate this output.
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.'''
if self.value.endswith(self.getDefaultFileExtension(alg)):
return self.value
else:
if self.compatible is None:
self.compatible = SextanteUtils.getTempFilename(self.getDefaultFileExtension(alg))
return self.compatible;
@@ -31,14 +31,18 @@
class OutputTable(Output):

def getFileFilter(self,alg):
exts = alg.provider.getSupportedOutputTableExtensions()
exts = ['csv']
for i in range(len(exts)):
exts[i] = exts[i].upper() + " files(*." + exts[i].lower() + ")"
return ";;".join(exts)

def getDefaultFileExtension(self, alg):
return alg.provider.getSupportedOutputTableExtensions()[0]

def getCompatibleFileName(self, alg):
#TODO!!!
return self.value

def getTableWriter(self, fields):
'''Returns a suitable writer to which records can be added as a
result of the algorithm. Use this to transparently handle output
@@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from sextante.core.QGisLayers import QGisLayers

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
@@ -24,23 +25,39 @@
__revision__ = '$Format:%H$'

from PyQt4.QtCore import *

from qgis.core import *
from sextante.outputs.Output import Output
from sextante.core.SextanteVectorWriter import SextanteVectorWriter
from sextante.core.SextanteUtils import SextanteUtils


class OutputVector(Output):

encoding = None
compatible = None

def getFileFilter(self,alg):
exts = alg.provider.getSupportedOutputVectorLayerExtensions()
def getFileFilter(self,alg):
exts = QGisLayers.getSupportedOutputRasterLayerExtensions()
for i in range(len(exts)):
exts[i] = exts[i].upper() + " files(*." + exts[i].lower() + ")"
return ";;".join(exts)


def getDefaultFileExtension(self, alg):
return alg.provider.getSupportedOutputVectorLayerExtensions()[0]


def getCompatibleFileName(self, alg):
'''Returns a filename that is compatible with the algorithm that is going to generate this output.
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.'''
if self.value.endswith(self.getDefaultFileExtension(alg)):
return self.value
else:
if self.compatible is None:
self.compatible = SextanteUtils.getTempFilename(self.getDefaultFileExtension(alg))
return self.compatible;


def getVectorWriter(self, fields, geomType, crs, options=None):
'''Returns a suitable writer to which features can be added as a
result of the algorithm. Use this to transparently handle output

0 comments on commit 995ede3

Please sign in to comment.