Skip to content
Permalink
Browse files
made SEXTANTE command line usage more pythonic
Fixed problem with temporary grass mapset created by SEXTANTE (wrong path)
  • Loading branch information
volaya committed Nov 19, 2012
1 parent 3398341 commit 6173fa3
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 73 deletions.
@@ -17,6 +17,8 @@
***************************************************************************
"""

from sextante.core.Sextante import runalg, alghelp, alglist, algoptions, load, loadFromAlg, extent, getObjectFromName, getObjectFromUri

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
__copyright__ = '(C) 2012, Victor Olaya'
@@ -264,7 +264,7 @@ def getOutputValue(self, name):
def getAsCommand(self):
'''Returns the command that would run this same algorithm from the console.
Should return null if the algorithm cannot be run from the console.'''
s="Sextante.runalg(\"" + self.commandLineName() + "\","
s="sextante.runalg(\"" + self.commandLineName() + "\","
for param in self.parameters:
s+=param.getValueAsCommandLineParameter() + ","
for out in self.outputs:
@@ -24,7 +24,7 @@

from PyQt4.QtCore import *
from PyQt4.QtGui import *

from qgis.core import *
from sextante.core.QGisLayers import QGisLayers
from sextante.core.SextanteConfig import SextanteConfig
from sextante.core.GeoAlgorithm import GeoAlgorithm
@@ -238,45 +238,14 @@ def getAlgorithm(name):
return provider[name]
return None


##This methods are here to be used from the python console,
##making it easy to use SEXTANTE from there
##==========================================================

@staticmethod
def alglist(text=None):
s=""
for provider in Sextante.algs.values():
sortedlist = sorted(provider.values(), key= lambda alg: alg.name)
for alg in sortedlist:
if text == None or text.lower() in alg.name.lower():
s+=(alg.name.ljust(50, "-") + "--->" + alg.commandLineName() + "\n")
print s


@staticmethod
def algoptions(name):
alg = Sextante.getAlgorithm(name)
if alg != None:
s =""
for param in alg.parameters:
if isinstance(param, ParameterSelection):
s+=param.name + "(" + param.description + ")\n"
i=0
for option in param.options:
s+= "\t" + str(i) + " - " + str(option) + "\n"
i+=1
print(s)
else:
print "Algorithm not found"
def getObject(uri):
'''Returns the QGIS object identified by the given URI'''
return QGisLayers.getObjectFromUri(uri)

@staticmethod
def alghelp(name):
alg = Sextante.getAlgorithm(name)
if alg != None:
print(str(alg))
else:
print "Algorithm not found"
def runandload(name, *args):
Sextante.runAlgorithm(name, SextantePostprocessing.handleAlgorithmResults, *args)

@staticmethod
def runAlgorithm(algOrName, onFinish, *args):
@@ -359,28 +328,80 @@ def cancel():
QApplication.restoreOverrideCursor()
return alg

@staticmethod
def runalg(algOrName, *args):
alg = Sextante.runAlgorithm(algOrName, None, *args)
return alg.getOutputValuesAsDictionary()


@staticmethod
def load(layer):
'''Loads a layer into QGIS'''
QGisLayers.load(layer)
##==========================================================
##This methods are here to be used from the python console,
##making it easy to use SEXTANTE from there
##==========================================================

@staticmethod
def loadFromAlg(layersdict):
'''Load all layer resulting from a given algorithm.
Layers are passed as a dictionary, obtained from alg.getOutputValuesAsDictionary()'''
QGisLayers.loadFromDict(layersdict)

@staticmethod
def getObject(uri):
'''Returns the QGIS object identified by the given URI'''
return QGisLayers.getObjectFromUri(uri)

@staticmethod
def runandload(name, *args):
Sextante.runAlgorithm(name, SextantePostprocessing.handleAlgorithmResults, *args)
def alglist(text=None):
s=""
for provider in Sextante.algs.values():
sortedlist = sorted(provider.values(), key= lambda alg: alg.name)
for alg in sortedlist:
if text == None or text.lower() in alg.name.lower():
s+=(alg.name.ljust(50, "-") + "--->" + alg.commandLineName() + "\n")
print s

def algoptions(name):
alg = Sextante.getAlgorithm(name)
if alg != None:
s =""
for param in alg.parameters:
if isinstance(param, ParameterSelection):
s+=param.name + "(" + param.description + ")\n"
i=0
for option in param.options:
s+= "\t" + str(i) + " - " + str(option) + "\n"
i+=1
print(s)
else:
print "Algorithm not found"

def alghelp(name):
alg = Sextante.getAlgorithm(name)
if alg != None:
print(str(alg))
else:
print "Algorithm not found"

def runalg(algOrName, *args):
alg = Sextante.runAlgorithm(algOrName, None, *args)
return alg.getOutputValuesAsDictionary()

def extent(layers):
first = True
for layer in layers:
if not isinstance(layer, (QgsRasterLayer, QgsVectorLayer)):
layer = QGisLayers.getObjectFromUri(layer)
if first:
xmin = layer.extent().xMinimum()
xmax = layer.extent().xMaximum()
ymin = layer.extent().yMinimum()
ymax = layer.extent().yMaximum()
else:
xmin = min(xmin, layer.extent().xMinimum())
xmax = max(xmax, layer.extent().xMaximum())
ymin = min(ymin, layer.extent().yMinimum())
ymax = max(ymax, layer.extent().yMaximum())
first = False
return str(xmin) + "," + str(xmax) + "," + str(ymin) + "," + str(ymax)

def getObjectFromName(name):
layers = QGisLayers.getAllLayers()
for layer in layers:
if layer.name() == name:
return layer

def getObjectFromUri(uri):
return QGisLayers.getObjectFromUri(uri, False)

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

def loadFromAlg(layersdict):
'''Load all layer resulting from a given algorithm.
Layers are passed as a dictionary, obtained from alg.getOutputValuesAsDictionary()'''
QGisLayers.loadFromDict(layersdict)
@@ -16,6 +16,7 @@
* *
***************************************************************************
"""
from PyQt4 import QtGui

__author__ = 'Victor Olaya'
__date__ = 'August 2012'
@@ -129,7 +130,8 @@ def createGrassScript(commands):
output = open(gisrc, "w")
location = "temp_location"
mapset = "user"
gisdbase = os.path.join(os.path.expanduser("~"), "sextante", "tempdata", "grassdata")
gisdbase = GrassUtils.grassDataFolder()
#gisdbase = os.path.join(os.path.expanduser("~"), "sextante", "tempdata", "grassdata")
output.write("GISDBASE: " + gisdbase + "\n");
output.write("LOCATION_NAME: " + location + "\n");
output.write("MAPSET: " + mapset + "\n");
@@ -178,7 +180,13 @@ def createGrassBatchJobFileFromGrassCommands(commands):

@staticmethod
def grassMapsetFolder():
tempfolder = os.path.join(SextanteUtils.tempFolder(), "grassdata", "temp_location")
folder = os.path.join(GrassUtils.grassDataFolder(), "temp_location")
mkdir(folder)
return folder

@staticmethod
def grassDataFolder():
tempfolder = os.path.join(SextanteUtils.tempFolder(), "grassdata")
mkdir(tempfolder)
return tempfolder

@@ -190,7 +198,7 @@ def createTempMapset():
structure and content will vary slightly depending on whether the user wants to process lat/lon or x/y data.'''

latlon = SextanteConfig.getSetting(GrassUtils.GRASS_LATLON)
folder = GrassUtils.grassMapsetFolder()
folder = GrassUtils.grassMapsetFolder()
mkdir(os.path.join(folder, "PERMANENT"))
mkdir(os.path.join(folder, "user"))
mkdir(os.path.join(folder, "PERMANENT", ".tmp"))
@@ -309,15 +317,15 @@ def getGrassVersion():
# of the previous ones.
# Starting a session just involves creating the temp mapset structure
@staticmethod
def startGrassSession():
def startGrassSession():
if not GrassUtils.sessionRunning:
GrassUtils.createTempMapset()
GrassUtils.sessionRunning = True

# End session by removing the temporary GRASS mapset and all the layers.
@staticmethod
def endGrassSession():
shutil.rmtree(GrassUtils.grassMapsetFolder(), True)
#shutil.rmtree(GrassUtils.grassMapsetFolder(), True)
GrassUtils.sessionRunning = False
GrassUtils.sessionLayers = {}

@@ -93,7 +93,6 @@ def raiseInternalError(self, error):
def runalg(self):
try:
self.algorithm.execute(self.progress)
self.finished.emit()
except GeoAlgorithmExecutionException, e :
self.error.emit(e.msg)
except BaseException, e:
@@ -58,7 +58,7 @@ def serialize(self):

def setValue(self, value):
try:
if value != None:
if value != None and isinstance(value, basestring):
value = value.strip()
self.value = value
return True
@@ -95,7 +95,10 @@ def executeSaga(progress):
for line in iter(proc.readline, ""):
if "%" in line:
s = "".join([x for x in line if x.isdigit()])
progress.setPercentage(int(s))
try:
progress.setPercentage(int(s))
except:
pass
else:
line = line.strip()
if line!="/" and line!="-" and line !="\\" and line!="|":
@@ -161,6 +161,10 @@ def processParameterLine(self,line):
out = OutputHTML()
elif tokens[1].lower().strip().startswith("output file"):
out = OutputFile()
elif tokens[1].lower().strip().startswith("output number"):
out = OutputNumber()
elif tokens[1].lower().strip().startswith("output string"):
out = OutputString()

if param != None:
self.addParameter(param)
@@ -173,18 +177,25 @@ def processParameterLine(self,line):

def processAlgorithm(self, progress):

script = "from sextante.core.Sextante import Sextante\n"
script = "import sextante\n"

ns = {}

for param in self.parameters:
script += param.name + "=" + param.getValueAsCommandLineParameter() + "\n"
#script += param.name + "=" + param.getValueAsCommandLineParameter() + "\n"
ns[param.name] = param.value

for out in self.outputs:
script += out.name + "=" + out.getValueAsCommandLineParameter() + "\n"
ns[out.name] = out.value
#script += out.name + "=" + out.getValueAsCommandLineParameter() + "\n"

script+=self.script
redirection = Redirection(progress)
sys.stdout = redirection
exec(script)
exec(script) in ns
sys.stdout = sys.__stdout__
for out in self.outputs:
out.setValue(ns[out.name])

def helpFile(self):
helpfile = self.descriptionFile + ".help"
@@ -9,4 +9,4 @@
centery = (input.extent().yMinimum() + input.extent().yMaximum()) / 2
width = (input.extent().xMaximum() - input.extent().xMinimum())
height = (input.extent().yMaximum() - input.extent().yMinimum())
Sextante.runalg("mmqgisx:creategrid", cellsize, cellsize, width, height, centerx, centery, 3, grid)
sextante.runalg("mmqgisx:creategrid", cellsize, cellsize, width, height, centerx, centery, 3, grid)

0 comments on commit 6173fa3

Please sign in to comment.