Skip to content

Commit c9b2d62

Browse files
author
volayaf
committedApr 1, 2012
Fixed bugs #5262, #5263, #5265 , #5266, #5267
Added numeric value selector improved grass provider git-svn-id: http://sextante.googlecode.com/svn/trunk/soft/bindings/qgis-plugin@57 881b9c09-3ef8-f3c2-ec3d-21d735c97f4d
1 parent 0bd4ab3 commit c9b2d62

31 files changed

+408
-179
lines changed
 

‎src/sextante/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ def name():
55
def description():
66
return "SEXTANTE Geoprocessing platform for QGIS"
77
def version():
8-
return "Version 0.1"
8+
return "Version 1.0"
99
def icon():
1010
return "icon.png"
1111
def qgisMinimumVersion():

‎src/sextante/core/AlgorithmProvider.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,25 @@ def __init__(self):
1212
self.actions = []
1313
self.contextMenuActions = []
1414

15+
def loadAlgorithms(self):
16+
self.algs = []
17+
name = "ACTIVATE_" + self.getName().upper().replace(" ", "_")
18+
if not SextanteConfig.getSetting(name):
19+
return
20+
else:
21+
self._loadAlgorithms()
22+
23+
#methods to be overridden.
24+
#==============================
25+
26+
27+
def _loadAlgorithms(self):
28+
'''Algorithm loading should take place here, filling self.algs, which is a list of
29+
elements of class GeoAlgorithm. Use that class to create your own algorithms
30+
Since algorithms should have a reference to the provider they come
31+
from, this is also the place to set the 'provider' variable of each algorithm'''
32+
pass
33+
1534
def initializeSettings(self):
1635
'''this is the place where you should add config parameters to sextante using the SextanteConfig class.
1736
this method is called when a provider is added to Sextante.
@@ -25,26 +44,12 @@ def unload(self):
2544
Removal of config setting should be done here'''
2645
name = "ACTIVATE_" + self.getName().upper().replace(" ", "_")
2746
SextanteConfig.removeSetting(name)
47+
2848
def getName(self):
2949
return "Generic algorithm provider"
3050

31-
def loadAlgorithms(self):
32-
self.algs = []
33-
name = "ACTIVATE_" + self.getName().upper().replace(" ", "_")
34-
if not SextanteConfig.getSetting(name):
35-
return
36-
else:
37-
self._loadAlgorithms()
3851

39-
#methods to be overridden.
40-
#==============================
4152

42-
#Algorithm loading should take place here, filling self.algs, which is a list of
43-
#elements of class GeoAlgorithm. Use that class to create your own algorithms
44-
#Since algorithms should have a reference to the provider they come
45-
#from, this is also the place to set the 'provider' variable of each algorithm
46-
def _loadAlgorithms(self):
47-
pass
4853

4954
def getIcon(self):
5055
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/alg.png")

‎src/sextante/core/GeoAlgorithm.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
import os.path
88
from sextante.core.SextanteUtils import SextanteUtils
99
from sextante.parameters.ParameterMultipleInput import ParameterMultipleInput
10-
10+
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
11+
import traceback
12+
from sextante.core.SextanteLog import SextanteLog
1113

1214
class GeoAlgorithm:
1315

@@ -23,6 +25,10 @@ def __init__(self):
2325
#change any of the following if your algorithm should not appear in the toolbox or modeler
2426
self.showInToolbox = True
2527
self.showInModeler = True
28+
#true if the algorithm has been canceled while it was being executed
29+
#default value is false, so it should be changed in processAlgorithm only if the algorithm
30+
#gets canceled
31+
self.canceled = False
2632

2733
self.defineCharacteristics()
2834

@@ -32,6 +38,8 @@ def getIcon(self):
3238
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/alg.png")
3339

3440
def helpFile(self):
41+
'''Returns the path to the help file with the description of this algorithm.
42+
It should be an HTML file'''
3543
return None
3644

3745
def processAlgorithm(self):
@@ -43,7 +51,8 @@ def defineCharacteristics(self):
4351
pass
4452

4553
def getCustomParametersDialog(self):
46-
'''if the algorithm has a custom parameters dialog, it should be returned here, ready to be executed'''
54+
'''if the algorithm has a custom parameters dialog, it should be returned
55+
here, ready to be executed'''
4756
return None
4857

4958
def getCustomModelerParametersDialog(self, modelAlg):
@@ -54,9 +63,29 @@ def getCustomModelerParametersDialog(self, modelAlg):
5463
#=========================================================
5564

5665
def execute(self, progress):
66+
'''The method to use to call a SEXTANTE algorithm.
67+
Although the body of the algorithm is in processAlgorithm(),
68+
it should be called using this method, since it performs
69+
some additional operations.
70+
The return value indicates whether the algorithm was canceled (false)
71+
or successfully run (true).
72+
Raises a GeoAlgorithmExecutionException in case anything goes wrong.'''
5773
self.setOutputCRSFromInputLayers()
5874
self.resolveTemporaryOutputs()
59-
self.processAlgorithm(progress)
75+
try:
76+
self.processAlgorithm(progress)
77+
return not self.canceled
78+
except GeoAlgorithmExecutionException, gaee:
79+
SextanteLog.addToLog(SextanteLog.LOG_ERROR, gaee.msg)
80+
raise gaee
81+
except Exception, e:
82+
#if something goes wrong and is not caught in the algorithm,
83+
#we catch it here and wrap it
84+
lines = []
85+
lines.append(str(e))
86+
lines.append(traceback.format_exc().replace("\n", "|"))
87+
SextanteLog.addToLog(SextanteLog.LOG_ERROR, lines)
88+
raise GeoAlgorithmExecutionException(str(e))
6089

6190
def resolveTemporaryOutputs(self):
6291
'''sets temporary outputs (output.value = None) with a temporary file instead'''
@@ -152,7 +181,6 @@ def getOutputValue(self, name):
152181
return out.value
153182
return None
154183

155-
156184
def getAsCommand(self):
157185
'''Returns the command that would run this same algorithm from the console'''
158186
s="Sextante.runalg(\"" + self.commandLineName() + "\","

‎src/sextante/core/QGisLayers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from qgis.core import *
22
from PyQt4.QtCore import *
33
from PyQt4.QtGui import *
4-
from PyQt4 import QtCore, QtGui
4+
from PyQt4 import QtGui
55
from os import path
66
from sextante.core.SextanteConfig import SextanteConfig
77
import os.path

‎src/sextante/core/Sextante.py

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def removeProvider(provider):
5454
Sextante.updateAlgsList()
5555
except:
5656
pass #This try catch block is here to avoid problems if the plugin with a provider is unloaded
57-
#after SEXTANTEe itself has been unloaded. It is a quick fix before I found out how to
57+
#after SEXTANTE itself has been unloaded. It is a quick fix before I found out how to
5858
#properly avoid that
5959

6060
@staticmethod
@@ -82,6 +82,7 @@ def initialize():
8282
Sextante.addProvider(ScriptAlgorithmProvider())
8383
Sextante.addProvider(RAlgorithmProvider())
8484
Sextante.addProvider(SagaAlgorithmProvider())
85+
Sextante.addProvider(GrassAlgorithmProvider())
8586
Sextante.modeler.initializeSettings();
8687
#and initialize
8788
SextanteLog.startLogging()
@@ -260,14 +261,11 @@ def runalg(name, *args):
260261

261262
SextanteLog.addToLog(SextanteLog.LOG_ALGORITHM, alg.getAsCommand())
262263

263-
try:
264-
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
265-
AlgorithmExecutor.runalg(alg, SilentProgress())
266-
QApplication.restoreOverrideCursor()
267-
return alg.getOutputValuesAsDictionary()
268-
except GeoAlgorithmExecutionException, e:
269-
print "*****Error executing algorithm*****"
270-
print e.msg
264+
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
265+
AlgorithmExecutor.runalg(alg, SilentProgress())
266+
QApplication.restoreOverrideCursor()
267+
return alg.getOutputValuesAsDictionary()
268+
271269

272270
@staticmethod
273271
def load(layer):
@@ -283,7 +281,7 @@ def loadFromAlg(layersdict):
283281
@staticmethod
284282
def getObject(uri):
285283
'''Returns the QGIS object identified the given URI'''
286-
QGisLayers.getObjectFromUri(uri)
284+
return QGisLayers.getObjectFromUri(uri)
287285

288286
@staticmethod
289287
def runandload(name, *args):
@@ -313,13 +311,12 @@ def runandload(name, *args):
313311
return
314312
i = i +1
315313

316-
try:
317-
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
318-
AlgorithmExecutor.runalg(alg, SilentProgress())
319-
QApplication.restoreOverrideCursor()
314+
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
315+
ret = AlgorithmExecutor.runalg(alg, SilentProgress())
316+
QApplication.restoreOverrideCursor()
317+
if ret:
320318
SextantePostprocessing.handleAlgorithmResults(alg)
321-
except GeoAlgorithmExecutionException, e:
322-
QMessageBox.critical(None, "Error", e.msg)
319+
323320

324321

325322

‎src/sextante/core/SextanteConfig.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def getSetting(name):
8080

8181

8282
class Setting():
83-
83+
'''A simple config parameter that will appear on the SEXTANTE config dialog'''
8484
def __init__(self, group, name, description, default):
8585
self.group=group
8686
self.name = name

‎src/sextante/ftools/Delaunay.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from qgis.core import *
77
from sextante.parameters.ParameterVector import ParameterVector
88
from sextante.core.QGisLayers import QGisLayers
9-
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
109
from sextante.outputs.OutputVector import OutputVector
1110
import voronoi
1211
from sets import Set

‎src/sextante/ftools/LinesIntersection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def processAlgorithm(self, progress):
4646
field2.setName(unicode(field2.name()) + "_2")
4747
fieldList = {0:field1, 1:field2}
4848
sRs = provider1.crs()
49-
check = QFile(self.shapefileName)
49+
check = QFile(output)
5050
if check.exists():
5151
if not QgsVectorFileWriter.deleteShapeFile(output):
5252
raise GeoAlgorithmExecutionException("Could not delete existing output file")

‎src/sextante/ftools/PointsInPolygon.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def processAlgorithm(self, progress):
3232
polyProvider = polyLayer.dataProvider()
3333
pointProvider = pointLayer.dataProvider()
3434
if polyProvider.crs() <> pointProvider.crs():
35-
SextanteLog.addToLog(SextanteLog.LOG_WARNING,
35+
SextanteLog.addToLog(SextanteLog.LOG_WARNING,
3636
"CRS warning!Warning: Input layers have non-matching CRS.\nThis may cause unexpected results.")
3737
allAttrs = polyProvider.attributeIndexes()
3838
polyProvider.select(allAttrs)
@@ -45,10 +45,10 @@ def processAlgorithm(self, progress):
4545
field = QgsField(unicode(inField), QVariant.Double, "real", 24, 15, "point count field")
4646
fieldList[index] = field
4747
sRs = polyProvider.crs()
48-
check = QFile(self.shapefileName)
48+
check = QFile(output)
4949
if check.exists():
50-
if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
51-
return
50+
if not QgsVectorFileWriter.deleteShapeFile(output):
51+
raise GeoAlgorithmExecutionException("could not delete file: " + output)
5252
writer = QgsVectorFileWriter(output, systemEncoding, fieldList, polyProvider.geometryType(), sRs)
5353
inFeat = QgsFeature()
5454
inFeatB = QgsFeature()

‎src/sextante/ftools/SumLines.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from sextante.core.SextanteLog import SextanteLog
1111
from sextante.ftools import ftools_utils
1212
from sextante.parameters.ParameterString import ParameterString
13+
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
1314

1415
class SumLines(GeoAlgorithm):
1516

@@ -53,10 +54,10 @@ def processAlgorithm(self, progress):
5354
lineProvider.rewind()
5455
start = 15.00
5556
add = 85.00 / polyProvider.featureCount()
56-
check = QFile(self.shapefileName)
57+
check = QFile(output)
5758
if check.exists():
58-
if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName):
59-
return
59+
if not QgsVectorFileWriter.deleteShapeFile(output):
60+
raise GeoAlgorithmExecutionException("Could not delete existing output file")
6061
writer = QgsVectorFileWriter(output, systemEncoding, fieldList, polyProvider.geometryType(), sRs)
6162
#writer = QgsVectorFileWriter(outPath, "UTF-8", fieldList, polyProvider.geometryType(), sRs)
6263
spatialIndex = ftools_utils.createIndex( lineProvider )

‎src/sextante/grass/GrassAlgorithm.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from sextante.parameters.ParameterVector import ParameterVector
1111
from sextante.parameters.ParameterBoolean import ParameterBoolean
1212
from sextante.outputs.OutputVector import OutputVector
13-
from sextante.saga.SagaUtils import SagaUtils
1413
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
1514
from sextante.core.SextanteLog import SextanteLog
1615
from sextante.parameters.ParameterFactory import ParameterFactory
@@ -200,13 +199,12 @@ def processAlgorithm(self, progress):
200199
commands.append(command)
201200

202201
#4 Run GRASS
203-
GrassUtils.createGrassScript(commands)
204202
loglines = []
205203
loglines.append("GRASS execution commands")
206204
for line in commands:
207205
loglines.append(line)
208206
SextanteLog.addToLog(SextanteLog.LOG_INFO, loglines)
209-
GrassUtils.executeGrass(progress);
207+
GrassUtils.executeGrass(commands, progress);
210208

211209

212210
def exportVectorLayer(self, filename):

‎src/sextante/grass/GrassAlgorithmProvider.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from sextante.core.SextanteLog import SextanteLog
77
from sextante.grass.GrassUtils import GrassUtils
88
from sextante.grass.GrassAlgorithm import GrassAlgorithm
9+
from sextante.core.SextanteUtils import SextanteUtils
910

1011
class GrassAlgorithmProvider(AlgorithmProvider):
1112

@@ -15,29 +16,32 @@ def __init__(self):
1516

1617
def initializeSettings(self):
1718
AlgorithmProvider.initializeSettings(self)
18-
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_FOLDER, "GRASS folder", GrassUtils.grassPath()))
19+
if SextanteUtils.isWindows():
20+
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_FOLDER, "GRASS folder", GrassUtils.grassPath()))
21+
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_WIN_SHELL, "Shell executable", GrassUtils.grassWinShell()))
1922
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_AUTO_REGION, "Use min covering region", True))
2023
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_LATLON, "Coordinates are lat/lon", False))
2124
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_REGION_XMIN, "GRASS Region min x", 0))
2225
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_REGION_YMIN, "GRASS Region min y", 0))
2326
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_REGION_XMAX, "GRASS Region max x", 1000))
2427
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_REGION_YMAX, "GRASS Region max y", 1000))
2528
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_REGION_CELLSIZE, "GRASS Region cellsize", 1))
26-
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_WIN_SHELL, "Shell executable (Windows only)", GrassUtils.grassWinShell()))
29+
2730
SextanteConfig.addSetting(Setting("GRASS", GrassUtils.GRASS_HELP_FOLDER, "GRASS help folder", GrassUtils.grassHelpPath()))
2831
#SextanteConfig.addSetting(Setting("SAGA", SagaUtils.SAGA_USE_SELECTED, "Use only selected features in vector layers", False))
2932

3033
def unload(self):
3134
AlgorithmProvider.unload(self)
32-
SextanteConfig.removeSetting(GrassUtils.GRASS_FOLDER)
35+
if SextanteUtils.isWindows():
36+
SextanteConfig.removeSetting(GrassUtils.GRASS_FOLDER)
37+
SextanteConfig.removeSetting(GrassUtils.GRASS_WIN_SHELL)
3338
SextanteConfig.removeSetting(GrassUtils.GRASS_AUTO_REGION)
3439
SextanteConfig.removeSetting(GrassUtils.GRASS_LATLON)
3540
SextanteConfig.removeSetting(GrassUtils.GRASS_REGION_XMIN)
3641
SextanteConfig.removeSetting(GrassUtils.GRASS_REGION_YMIN)
3742
SextanteConfig.removeSetting(GrassUtils.GRASS_REGION_XMAX)
3843
SextanteConfig.removeSetting(GrassUtils.GRASS_REGION_YMAX)
3944
SextanteConfig.removeSetting(GrassUtils.GRASS_REGION_CELLSIZE)
40-
SextanteConfig.removeSetting(GrassUtils.GRASS_WIN_SHELL)
4145
SextanteConfig.removeSetting(GrassUtils.GRASS_HELP_FOLDER)
4246

4347
def createAlgsList(self):
@@ -53,7 +57,7 @@ def createAlgsList(self):
5357
else:
5458
SextanteLog.addToLog(SextanteLog.LOG_ERROR, "Could not open GRASS algorithm: " + descriptionFile)
5559
except Exception,e:
56-
pass
60+
SextanteLog.addToLog(SextanteLog.LOG_ERROR, "Could not open GRASS algorithm: " + descriptionFile)
5761

5862
def _loadAlgorithms(self):
5963
self.algs = self.preloadedAlgs

‎src/sextante/grass/GrassUtils.py

Lines changed: 44 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import subprocess
44
from sextante.core.SextanteConfig import SextanteConfig
55
from sextante.core.SextanteLog import SextanteLog
6+
import stat
67

78
class GrassUtils:
89

@@ -19,21 +20,17 @@ class GrassUtils:
1920

2021
@staticmethod
2122
def grassBatchJobFilename():
22-
if SextanteUtils.isWindows():
23-
filename = "grass_batch_job.bat";
24-
else:
25-
filename = "grass_batch_job.sh";
26-
23+
'''This is used in linux. This is the batch job that we assign to
24+
GRASS_BATCH_JOB and then call GRASS and let it do the work'''
25+
filename = "grass_batch_job.sh";
2726
batchfile = SextanteUtils.userFolder() + os.sep + filename
2827
return batchfile
2928

3029
@staticmethod
3130
def grassScriptFilename():
32-
if SextanteUtils.isWindows():
33-
filename = "grass_script.bat";
34-
else:
35-
filename = "grass_script.sh";
36-
31+
'''this is used in windows. We create a script that initializes
32+
GRASS and then uses grass commands'''
33+
filename = "grass_script.bat";
3734
filename = SextanteUtils.userFolder() + os.sep + filename
3835
return filename
3936

@@ -84,44 +81,38 @@ def createGrassScript(commands):
8481
output.write("GRASS_GUI: text\n");
8582
output.close();
8683

87-
#Write the startup script
88-
if not SextanteUtils.isWindows():
89-
##TODO************
90-
pass
91-
else:
92-
output=open(script, "w")
93-
shToolsPath = os.path.basename(shell)
94-
output.write("set HOME=" + os.path.expanduser("~") + "\n");
95-
output.write("set GISRC=" + gisrc + "\n")
96-
output.write("set GRASS_SH=" + shell + "\n")
97-
output.write("set PATH=" + shToolsPath + os.sep + "bin;" + shToolsPath + os.sep + "lib;" + "%PATH%\n")
98-
output.write("set WINGISBASE=" + folder + "\n")
99-
output.write("set GISBASE=" + folder + "\n");
100-
output.write("set GRASS_PROJSHARE=" + folder + os.sep + "share" + os.sep + "proj" + "\n")
101-
output.write("set GRASS_MESSAGE_FORMAT=gui\n")
102-
#Replacement code for etc/Init.bat
103-
output.write("if \"%GRASS_ADDON_PATH%\"==\"\" set PATH=%WINGISBASE%\\bin;%WINGISBASE%\\lib;%PATH%\n")
104-
output.write("if not \"%GRASS_ADDON_PATH%\"==\"\" set PATH=%WINGISBASE%\\bin;%WINGISBASE%\\lib;%GRASS_ADDON_PATH%;%PATH%\n")
105-
output.write("\n")
106-
output.write("set GRASS_VERSION=" + GrassUtils.getGrassVersion() + "\n");
107-
output.write("if not \"%LANG%\"==\"\" goto langset\n");
108-
output.write("FOR /F \"usebackq delims==\" %%i IN (`\"%WINGISBASE%\\etc\\winlocale\"`) DO @set LANG=%%i\n");
109-
output.write(":langset\n")
110-
output.write("\n")
111-
output.write("set PATHEXT=%PATHEXT%;.PY\n")
112-
output.write("set PYTHONPATH=%PYTHONPATH%;%WINGISBASE%\\etc\\python;%WINGISBASE%\\etc\\wxpython\\n");
113-
output.write("\n")
114-
output.write("g.gisenv.exe set=\"MAPSET=" + mapset + "\"\n")
115-
output.write("g.gisenv.exe set=\"LOCATION=" + location + "\"\n")
116-
output.write("g.gisenv.exe set=\"LOCATION_NAME=" + location + "\"\n")
117-
output.write("g.gisenv.exe set=\"GISDBASE=" + gisdbase + "\"\n")
118-
output.write("g.gisenv.exe set=\"GRASS_GUI=text\"\n")
119-
for command in commands:
120-
output.write(command + "\n")
121-
output.write("\n");
122-
output.write("exit\n");
123-
output.close();
124-
84+
output=open(script, "w")
85+
shToolsPath = os.path.basename(shell)
86+
output.write("set HOME=" + os.path.expanduser("~") + "\n");
87+
output.write("set GISRC=" + gisrc + "\n")
88+
output.write("set GRASS_SH=" + shell + "\n")
89+
output.write("set PATH=" + shToolsPath + os.sep + "bin;" + shToolsPath + os.sep + "lib;" + "%PATH%\n")
90+
output.write("set WINGISBASE=" + folder + "\n")
91+
output.write("set GISBASE=" + folder + "\n");
92+
output.write("set GRASS_PROJSHARE=" + folder + os.sep + "share" + os.sep + "proj" + "\n")
93+
output.write("set GRASS_MESSAGE_FORMAT=gui\n")
94+
#Replacement code for etc/Init.bat
95+
output.write("if \"%GRASS_ADDON_PATH%\"==\"\" set PATH=%WINGISBASE%\\bin;%WINGISBASE%\\lib;%PATH%\n")
96+
output.write("if not \"%GRASS_ADDON_PATH%\"==\"\" set PATH=%WINGISBASE%\\bin;%WINGISBASE%\\lib;%GRASS_ADDON_PATH%;%PATH%\n")
97+
output.write("\n")
98+
output.write("set GRASS_VERSION=" + GrassUtils.getGrassVersion() + "\n");
99+
output.write("if not \"%LANG%\"==\"\" goto langset\n");
100+
output.write("FOR /F \"usebackq delims==\" %%i IN (`\"%WINGISBASE%\\etc\\winlocale\"`) DO @set LANG=%%i\n");
101+
output.write(":langset\n")
102+
output.write("\n")
103+
output.write("set PATHEXT=%PATHEXT%;.PY\n")
104+
output.write("set PYTHONPATH=%PYTHONPATH%;%WINGISBASE%\\etc\\python;%WINGISBASE%\\etc\\wxpython\\n");
105+
output.write("\n")
106+
output.write("g.gisenv.exe set=\"MAPSET=" + mapset + "\"\n")
107+
output.write("g.gisenv.exe set=\"LOCATION=" + location + "\"\n")
108+
output.write("g.gisenv.exe set=\"LOCATION_NAME=" + location + "\"\n")
109+
output.write("g.gisenv.exe set=\"GISDBASE=" + gisdbase + "\"\n")
110+
output.write("g.gisenv.exe set=\"GRASS_GUI=text\"\n")
111+
for command in commands:
112+
output.write(command + "\n")
113+
output.write("\n");
114+
output.write("exit\n");
115+
output.close();
125116

126117
@staticmethod
127118
def createGrassBatchJobFileFromGrassCommands(commands):
@@ -176,8 +167,6 @@ def createTempMapset():
176167
outfile.close()
177168
GrassUtils.writeGrassWindow(os.path.join(folder, "user", "WIND"));
178169

179-
180-
181170
@staticmethod
182171
def writeGRASSWindow(filename):
183172
out = open(filename, "w")
@@ -224,15 +213,14 @@ def writeGRASSWindow(filename):
224213

225214

226215
@staticmethod
227-
def executeGrass(progress):
216+
def executeGrass(commands, progress):
228217
if SextanteUtils.isWindows():
218+
GrassUtils.createGrassScript(commands)
229219
command = ["cmd.exe", "/C ", GrassUtils.grassScriptFilename()]
230220
else:
231-
pass
232-
#===================================================================
233-
# os.chmod(GrassUtils.grassScriptFilename(), stat.S_IEXEC)
234-
# command = [GrassUtils.grassScriptFilename()]
235-
#===================================================================
221+
GrassUtils.createGrassBatchJobFileFromGrassCommands(commands)
222+
os.chmod(GrassUtils.grassBatchJobFilename(), stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE)
223+
#command = [SagaUtils.sagaBatchJobFilename()]
236224
loglines = []
237225
loglines.append("GRASS execution console output")
238226
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.STDOUT, universal_newlines=True).stdout

‎src/sextante/gui/AlgorithmExecutor.py

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,18 @@ class AlgorithmExecutor:
55

66
@staticmethod
77
def runalg(alg, progress):
8+
'''executes a given algorithm, showing its progress in the progress object passed along.
9+
Return true if everything went OK, false if the algorithm was canceled or there was
10+
any problem and could not be completed'''
811
try:
912
alg.execute(progress)
13+
return not alg.canceled
1014
except GeoAlgorithmExecutionException, e :
1115
QMessageBox.critical(None, "Error", e.msg)
16+
return False
1217
finally:
1318
progress.setFinished()
1419

15-
16-
@staticmethod
17-
def runbatch(algs, progress):
18-
try:
19-
for alg in algs:
20-
progress.addText(alg.getAsCommand())
21-
AlgorithmExecutor.runalg(alg, SilentProgress())
22-
progress.addText("Execution OK!")
23-
except GeoAlgorithmExecutionException, e :
24-
QMessageBox.critical(self, "Error",e.msg)
25-
progress.addText("Execution Failed")
26-
finally:
27-
progress.setFinished()
28-
29-
3020
class SilentProgress():
3121

3222
def setText(self, text):

‎src/sextante/gui/BatchProcessingDialog.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,19 @@ def okPressed(self):
102102
row+=1
103103
self.algs.append(alg)
104104

105-
try:
106-
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
107-
i=1
108-
self.progress.setMaximum(len(self.algs))
109-
for alg in self.algs:
110-
AlgorithmExecutor.runalg(alg, SilentProgress())
105+
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
106+
i=1
107+
self.progress.setMaximum(len(self.algs))
108+
for alg in self.algs:
109+
if AlgorithmExecutor.runalg(alg, SilentProgress()):
111110
self.progress.setValue(i)
112111
i+=1
113-
QApplication.restoreOverrideCursor()
114-
QMessageBox.information(self, "Batch processing", "Batch processing successfully completed!")
115-
except GeoAlgorithmExecutionException, e :
116-
QApplication.restoreOverrideCursor()
117-
QMessageBox.critical(self, "Error",e.msg)
118-
finally:
119-
self.close()
112+
else:
113+
QApplication.restoreOverrideCursor()
114+
return
115+
QApplication.restoreOverrideCursor()
116+
QMessageBox.information(self, "Batch processing", "Batch processing successfully completed!")
117+
self.close()
120118

121119

122120
def cancelPressed(self):

‎src/sextante/gui/NumberInputDialog.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
from qgis.core import *
2+
from PyQt4.QtCore import *
3+
from PyQt4.QtGui import *
4+
from PyQt4 import QtCore, QtGui
5+
from sextante.core.QGisLayers import QGisLayers
6+
7+
class NumberInputDialog(QtGui.QDialog):
8+
9+
def __init__(self):
10+
QtGui.QDialog.__init__(self)
11+
self.setModal(True)
12+
self.setupUi()
13+
self.value = None
14+
15+
def setupUi(self):
16+
self.setObjectName("Parameters")
17+
self.resize(500, 350)
18+
self.buttonBox = QtGui.QDialogButtonBox()
19+
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
20+
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
21+
self.buttonBox.setObjectName("buttonBox")
22+
self.label = QtGui.QLabel()
23+
self.label.setText("Enter expression in the text field.\nDouble click on elements in the tree to add their values to the expression.")
24+
self.tree = QtGui.QTreeWidget()
25+
self.tree.setHeaderHidden(True)
26+
self.fillTree()
27+
self.formulaText = QtGui.QLineEdit()
28+
self.formulaText.setPlaceholderText("[Enter your formula here]")
29+
self.setWindowTitle("Enter number or expression")
30+
self.verticalLayout = QtGui.QVBoxLayout()
31+
self.verticalLayout.setSpacing(2)
32+
self.verticalLayout.setMargin(0)
33+
self.verticalLayout.setObjectName("hLayout")
34+
self.verticalLayout.addWidget(self.label)
35+
self.verticalLayout.addWidget(self.tree)
36+
self.verticalLayout.addWidget(self.formulaText)
37+
self.verticalLayout.addWidget(self.buttonBox)
38+
self.setLayout(self.verticalLayout)
39+
self.tree.doubleClicked.connect(self.addValue)
40+
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), self.okPressed)
41+
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), self.cancelPressed)
42+
QtCore.QMetaObject.connectSlotsByName(self)
43+
44+
def fillTree(self):
45+
layersItem = QtGui.QTreeWidgetItem()
46+
layersItem.setText(0, "Values from data layers")
47+
self.tree.addTopLevelItem(layersItem)
48+
layers = QGisLayers.getAllLayers()
49+
for layer in layers:
50+
layerItem = QtGui.QTreeWidgetItem()
51+
layerItem.setText(0, str(layer.name()))
52+
layerItem.addChild(TreeValueItem("Min X", layer.extent().xMinimum()))
53+
layerItem.addChild(TreeValueItem("Max X", layer.extent().xMaximum()))
54+
layerItem.addChild(TreeValueItem("Min Y", layer.extent().yMinimum()))
55+
layerItem.addChild(TreeValueItem("Max y", layer.extent().yMaximum()))
56+
if isinstance(layer, QgsRasterLayer):
57+
cellsize = (layer.extent().xMaximum() - layer.extent().xMinimum())/layer.width()
58+
layerItem.addChild(TreeValueItem("Cellsize", cellsize))
59+
layersItem.addChild(layerItem)
60+
61+
def addValue(self):
62+
item = self.tree.currentItem()
63+
if isinstance(item, TreeValueItem):
64+
self.formulaText.setText(str(self.formulaText.text()) + " " + str(item.value))
65+
66+
67+
def okPressed(self):
68+
try:
69+
self.value = float(eval(str(self.formulaText.text())))
70+
self.close()
71+
except:
72+
QMessageBox.critical(self, "Wrong expression", "The expression entered is not correct")
73+
74+
75+
def cancelPressed(self):
76+
self.value = None
77+
self.close()
78+
79+
class TreeValueItem(QtGui.QTreeWidgetItem):
80+
def __init__(self, name, value):
81+
QTreeWidgetItem.__init__(self)
82+
self.value = value
83+
self.setText(0, name + ":" + str(value))

‎src/sextante/gui/NumberInputPanel.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from PyQt4 import QtGui
2+
from sextante.gui.NumberInputDialog import NumberInputDialog
3+
4+
class NumberInputPanel(QtGui.QWidget):
5+
6+
def __init__(self, number, parent = None):
7+
super(NumberInputPanel, self).__init__(parent)
8+
self.setObjectName("NIPanel")
9+
self.horizontalLayout = QtGui.QHBoxLayout(self)
10+
self.horizontalLayout.setSpacing(2)
11+
self.horizontalLayout.setMargin(0)
12+
self.horizontalLayout.setObjectName("hLayout")
13+
self.text = QtGui.QLineEdit()
14+
self.text.setObjectName("linedit")
15+
self.text.setText(str(number))
16+
self.text.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
17+
self.horizontalLayout.addWidget(self.text)
18+
self.pushButton = QtGui.QPushButton()
19+
self.pushButton.setObjectName("pushButton")
20+
self.pushButton.setText("...")
21+
self.pushButton.clicked.connect(self.showNumberInputDialog)
22+
self.horizontalLayout.addWidget(self.pushButton)
23+
self.setLayout(self.horizontalLayout)
24+
25+
def showNumberInputDialog(self):
26+
pass
27+
dlg = NumberInputDialog()
28+
dlg.exec_()
29+
if dlg.value != None:
30+
self.text.setText(str(dlg.value))
31+
32+
def getValue(self):
33+
return self.text.text()

‎src/sextante/gui/OutputSelectionPanel.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
class OutputSelectionPanel(QtGui.QWidget):
77

8+
lastOutputFolder = None
89
SAVE_TO_TEMP_FILE = "[Save to temporary file]"
910

1011
def __init__(self, output, alg):
@@ -30,7 +31,9 @@ def __init__(self, output, alg):
3031

3132
def showSelectionDialog(self):
3233
filefilter = self.output.getFileFilter(self.alg)
33-
filename = QtGui.QFileDialog.getSaveFileName(self, "Save file", QtCore.QString(), filefilter)
34+
if OutputSelectionPanel.lastOutputFolder == None:
35+
OutputSelectionPanel.lastOutputFolder = SextanteConfig.getSetting(SextanteConfig.OUTPUT_FOLDER)
36+
filename = QtGui.QFileDialog.getSaveFileName(self, "Save file", QtCore.QString(OutputSelectionPanel.lastOutputFolder), filefilter)
3437
if filename:
3538
self.text.setText(str(filename))
3639

@@ -40,5 +43,5 @@ def getValue(self):
4043
return None
4144
else:
4245
if not os.path.isabs(filename):
43-
filename = SextanteConfig.getSetting(SextanteConfig.OUTPUT_FOLDER)
46+
filename = SextanteConfig.getSetting(SextanteConfig.OUTPUT_FOLDER) + os.sep + filename
4447
return filename

‎src/sextante/gui/ParametersDialog.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
from sextante.gui.RangePanel import RangePanel
2727
from sextante.parameters.ParameterRange import ParameterRange
2828
from sextante.gui.HTMLViewerDialog import HTMLViewerDialog
29+
from sextante.gui.NumberInputPanel import NumberInputPanel
30+
from sextante.parameters.ParameterNumber import ParameterNumber
2931

3032
try:
3133
_fromUtf8 = QtCore.QString.fromUtf8
@@ -155,6 +157,8 @@ def getWidgetFromParameter(self, param):
155157
for opt in options:
156158
opts.append(opt.name())
157159
item = MultipleInputPanel(opts)
160+
elif isinstance(param, ParameterNumber):
161+
item = NumberInputPanel(param.default)
158162
else:
159163
item = QtGui.QLineEdit()
160164
item.setText(str(param.default))
@@ -262,6 +266,8 @@ def setParamValue(self, param, widget):
262266
for index in widget.selectedoptions:
263267
value.append(options[index])
264268
return param.setValue(value)
269+
elif isinstance(param, ParameterNumber):
270+
return param.setValue(widget.getValue())
265271
else:
266272
return param.setValue(str(widget.text()))
267273

@@ -271,9 +277,10 @@ def accept(self):
271277
if self.setParamValues():
272278
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
273279
SextanteLog.addToLog(SextanteLog.LOG_ALGORITHM, self.alg.getAsCommand())
274-
AlgorithmExecutor.runalg(self.alg, self)
280+
ret = AlgorithmExecutor.runalg(self.alg, self)
275281
QApplication.restoreOverrideCursor()
276-
SextantePostprocessing.handleAlgorithmResults(self.alg)
282+
if ret:
283+
SextantePostprocessing.handleAlgorithmResults(self.alg)
277284
self.dialog.executed = True
278285
self.dialog.close()
279286

‎src/sextante/mmqgis/DummyInterface.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from sextante.core.Sextante import Sextante
22
class DummyInterface:
33

4-
def addVector(self,p1,p2,p3):
4+
def addVectorLayer(self,p1,p2,p3):
55
pass
66

77
def mainWindow(self):

‎src/sextante/modeler/CalculatorModelerParametersDialog.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
class CalculatorModelerParametersDialog(QtGui.QDialog):
99

10-
1110
def __init__(self, alg, model):
1211
QtGui.QDialog.__init__(self)
1312
self.setModal(True)

‎src/sextante/r/RAlgorithm.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from sextante.r.RUtils import RUtils
1919
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
2020
from sextante.core.SextanteLog import SextanteLog
21+
from sextante.core.SextanteUtils import SextanteUtils
2122

2223
class RAlgorithm(GeoAlgorithm):
2324

@@ -144,9 +145,10 @@ def processParameterLine(self,line):
144145
raise WrongScriptException("Could not load R script:" + self.descriptionFile + ".\n Problem with line \"" + line + "\"")
145146

146147
def processAlgorithm(self, progress):
147-
path = RUtils.RFolder()
148-
if path == "":
149-
raise GeoAlgorithmExecutionException("R folder is not configured.\nPlease configure it before running R script.")
148+
if SextanteUtils.isWindows():
149+
path = RUtils.RFolder()
150+
if path == "":
151+
raise GeoAlgorithmExecutionException("R folder is not configured.\nPlease configure it before running R script.")
150152
loglines = []
151153
loglines.append("R execution commands")
152154
loglines += self.getFullSetOfRCommands()

‎src/sextante/r/RAlgorithmProvider.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from sextante.r.RAlgorithm import RAlgorithm
1111
from sextante.r.CreateNewRScriptAction import CreateNewRScriptAction
1212
from sextante.r.EditRScriptAction import EditRScriptAction
13+
from sextante.core.SextanteUtils import SextanteUtils
1314

1415
class RAlgorithmProvider(AlgorithmProvider):
1516

@@ -21,12 +22,14 @@ def __init__(self):
2122
def initializeSettings(self):
2223
AlgorithmProvider.initializeSettings(self)
2324
SextanteConfig.addSetting(Setting("R", RUtils.RSCRIPTS_FOLDER, "R Scripts folder", RUtils.RScriptsFolder()))
24-
SextanteConfig.addSetting(Setting("R", RUtils.R_FOLDER, "R folder", RUtils.RFolder()))
25+
if SextanteUtils.isWindows():
26+
SextanteConfig.addSetting(Setting("R", RUtils.R_FOLDER, "R folder", RUtils.RFolder()))
2527

2628
def unload(self):
2729
AlgorithmProvider.unload(self)
2830
SextanteConfig.removeSetting(RUtils.RSCRIPTS_FOLDER)
29-
SextanteConfig.removeSetting(RUtils.R_FOLDER)
31+
if SextanteUtils.isWindows():
32+
SextanteConfig.removeSetting(RUtils.R_FOLDER)
3033

3134
def getIcon(self):
3235
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/r.png")

‎src/sextante/r/RUtils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def executeRAlgorithm(alg):
5353
if SextanteUtils.isWindows():
5454
command = [RUtils.RFolder() + os.sep + "bin" + os.sep + "R.exe", "CMD", "BATCH", "--vanilla", RUtils.getRScriptFilename()]
5555
else:
56-
os.chmod(RUtils.getRScriptFilename(), stat.S_IEXEC)
56+
os.chmod(RUtils.getRScriptFilename(), stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE)
5757
command = ["R", "CMD", "BATCH", "--vanilla", RUtils.getRScriptFilename()]
5858

5959
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.STDOUT, universal_newlines=True)

‎src/sextante/saga/SagaAlgorithm.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,10 @@ def addToResamplingExtent(self, layer, first):
118118

119119

120120
def processAlgorithm(self, progress):
121-
path = SagaUtils.sagaPath()
122-
if path == "":
123-
raise GeoAlgorithmExecutionException("SAGA folder is not configured.\nPlease configure it before running SAGA algorithms.")
121+
if SextanteUtils.isWindows():
122+
path = SagaUtils.sagaPath()
123+
if path == "":
124+
raise GeoAlgorithmExecutionException("SAGA folder is not configured.\nPlease configure it before running SAGA algorithms.")
124125
useSelection = SextanteConfig.getSetting(SagaUtils.SAGA_USE_SELECTED)
125126
commands = list()
126127
self.exportedLayers = {}
@@ -206,19 +207,19 @@ def processAlgorithm(self, progress):
206207
filename += ".tif"
207208
out.value = filename
208209
filename = SextanteUtils.tempFolder() + os.sep + os.path.basename(filename) + ".sgrd"
209-
command+=(" -" + out.name + " " + filename);
210+
command+=(" -" + out.name + " \"" + filename + "\"");
210211
if isinstance(out, OutputVector):
211212
filename = out.value
212213
if not filename.endswith(".shp"):
213214
filename += ".shp"
214215
out.value = filename
215-
command+=(" -" + out.name + " " + filename);
216+
command+=(" -" + out.name + " \"" + filename + "\"");
216217
if isinstance(out, OutputTable):
217218
filename = out.value
218219
if not filename.endswith(".dbf"):
219220
filename += ".dbf"
220221
out.value = filename
221-
command+=(" -" + out.name + " " + filename);
222+
command+=(" -" + out.name + " \"" + filename + "\"");
222223

223224
commands.append(command)
224225

@@ -228,9 +229,9 @@ def processAlgorithm(self, progress):
228229
filename = out.value
229230
filename2 = SextanteUtils.tempFolder() + os.sep + os.path.basename(filename) + ".sgrd"
230231
if SextanteUtils.isWindows():
231-
commands.append("io_gdal 1 -GRIDS " + filename2 + " -FORMAT 1 -TYPE 0 -FILE " + filename);
232+
commands.append("io_gdal 1 -GRIDS \"" + filename2 + "\" -FORMAT 1 -TYPE 0 -FILE \"" + filename + "\"");
232233
else:
233-
commands.append("libio_gdal 1 -GRIDS " + filename2 + " -FORMAT 1 -TYPE 0 -FILE " + filename);
234+
commands.append("libio_gdal 1 -GRIDS \"" + filename2 + "\" -FORMAT 1 -TYPE 0 -FILE " + filename + "\"");
234235

235236
#4 Run SAGA
236237
SagaUtils.createSagaBatchJobFileFromSagaCommands(commands)
@@ -250,13 +251,13 @@ def resampleRasterLayer(self,layer):
250251
destFilename = self.getTempFilename("sgrd")
251252
self.exportedLayers[layer]= destFilename
252253
if SextanteUtils.isWindows():
253-
s = "grid_tools \"Resampling\" -INPUT " + inputFilename + " -TARGET 0 -SCALE_UP_METHOD 4 -SCALE_DOWN_METHOD 4 -USER_XMIN " +\
254+
s = "grid_tools \"Resampling\" -INPUT \"" + inputFilename + "\" -TARGET 0 -SCALE_UP_METHOD 4 -SCALE_DOWN_METHOD 4 -USER_XMIN " +\
254255
str(self.xmin) + " -USER_XMAX " + str(self.xmax) + " -USER_YMIN " + str(self.ymin) + " -USER_YMAX " + str(self.ymax) +\
255-
" -USER_SIZE " + str(self.cellsize) + " -USER_GRID " + destFilename
256+
" -USER_SIZE " + str(self.cellsize) + " -USER_GRID \"" + destFilename + "\""
256257
else:
257-
s = "libgrid_tools \"Resampling\" -INPUT " + inputFilename + " -TARGET 0 -SCALE_UP_METHOD 4 -SCALE_DOWN_METHOD 4 -USER_XMIN " +\
258+
s = "libgrid_tools \"Resampling\" -INPUT \"" + inputFilename + "\" -TARGET 0 -SCALE_UP_METHOD 4 -SCALE_DOWN_METHOD 4 -USER_XMIN " +\
258259
str(self.xmin) + " -USER_XMAX " + str(self.xmax) + " -USER_YMIN " + str(self.ymin) + " -USER_YMAX " + str(self.ymax) +\
259-
" -USER_SIZE " + str(self.cellsize) + " -USER_GRID " + destFilename
260+
" -USER_SIZE " + str(self.cellsize) + " -USER_GRID \"" + destFilename + "\""
260261
return s
261262

262263

@@ -300,9 +301,9 @@ def exportRasterLayer(self, layer):
300301
destFilename = self.getTempFilename("sgrd")
301302
self.exportedLayers[layer]= destFilename
302303
if SextanteUtils.isWindows():
303-
return "io_gdal 0 -GRIDS " + destFilename + " -FILES " + layer
304+
return "io_gdal 0 -GRIDS \"" + destFilename + "\" -FILES \"" + layer+"\""
304305
else:
305-
return "libio_gdal 0 -GRIDS " + destFilename + " -FILES " + layer
306+
return "libio_gdal 0 -GRIDS \"" + destFilename + "\" -FILES \"" + layer + "\""
306307

307308
def getTempFilename(self, ext):
308309
self.numExportedLayers+=1

‎src/sextante/saga/SagaAlgorithmProvider.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from sextante.core.SextanteConfig import SextanteConfig, Setting
77
from sextante.core.AlgorithmProvider import AlgorithmProvider
88
from sextante.core.SextanteLog import SextanteLog
9+
from sextante.core.SextanteUtils import SextanteUtils
910

1011
class SagaAlgorithmProvider(AlgorithmProvider):
1112

@@ -16,7 +17,8 @@ def __init__(self):
1617

1718
def initializeSettings(self):
1819
AlgorithmProvider.initializeSettings(self)
19-
SextanteConfig.addSetting(Setting("SAGA", SagaUtils.SAGA_FOLDER, "SAGA folder", SagaUtils.sagaPath()))
20+
if SextanteUtils.isWindows():
21+
SextanteConfig.addSetting(Setting("SAGA", SagaUtils.SAGA_FOLDER, "SAGA folder", SagaUtils.sagaPath()))
2022
SextanteConfig.addSetting(Setting("SAGA", SagaUtils.SAGA_AUTO_RESAMPLING, "Use min covering grid system for resampling", True))
2123
SextanteConfig.addSetting(Setting("SAGA", SagaUtils.SAGA_RESAMPLING_REGION_XMIN, "Resampling region min x", 0))
2224
SextanteConfig.addSetting(Setting("SAGA", SagaUtils.SAGA_RESAMPLING_REGION_YMIN, "Resampling region min y", 0))
@@ -27,7 +29,8 @@ def initializeSettings(self):
2729

2830
def unload(self):
2931
AlgorithmProvider.unload(self)
30-
SextanteConfig.removeSetting(SagaUtils.SAGA_FOLDER)
32+
if SextanteUtils.isWindows():
33+
SextanteConfig.removeSetting(SagaUtils.SAGA_FOLDER)
3134
SextanteConfig.removeSetting(SagaUtils.SAGA_AUTO_RESAMPLING)
3235
SextanteConfig.removeSetting(SagaUtils.SAGA_RESAMPLING_REGION_XMIN)
3336
SextanteConfig.removeSetting(SagaUtils.SAGA_RESAMPLING_REGION_YMIN)

‎src/sextante/saga/SagaUtils.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ class SagaUtils:
1414
SAGA_RESAMPLING_REGION_XMAX = "SAGA_RESAMPLING_REGION_XMAX"
1515
SAGA_RESAMPLING_REGION_YMAX = "SAGA_RESAMPLING_REGION_YMAX"
1616
SAGA_RESAMPLING_REGION_CELLSIZE = "SAGA_RESAMPLING_REGION_CELLSIZE"
17-
1817
SAGA_FOLDER = "SAGA_FOLDER"
1918

2019
@staticmethod
@@ -50,10 +49,10 @@ def createSagaBatchJobFileFromSagaCommands(commands):
5049
fout.write("set SAGA_MLB=" + SagaUtils.sagaPath()+ os.sep + "modules" + "\n");
5150
fout.write("PATH=PATH;%SAGA%;%SAGA_MLB%\n");
5251
else:
53-
fout.write("!#/bin/sh\n");
54-
fout.write("export SAGA_MLB=" + SagaUtils.sagaPath() + os.sep + "modules" + "\n");
55-
fout.write("PATH=$PATH:" + SagaUtils.sagaPath() + os.sep + "modules" + "\n");
56-
fout.write("export PATH\n");
52+
pass
53+
#fout.write("export SAGA_MLB=" + SagaUtils.sagaPath() + os.sep + "modules" + "\n");
54+
#fout.write("PATH=$PATH:" + SagaUtils.sagaPath() + os.sep + "modules" + "\n");
55+
#fout.write("export PATH\n");
5756

5857
for command in commands:
5958
fout.write("saga_cmd " + command + "\n")
@@ -66,7 +65,7 @@ def executeSaga(progress):
6665
if SextanteUtils.isWindows():
6766
command = ["cmd.exe", "/C ", SagaUtils.sagaBatchJobFilename()]
6867
else:
69-
os.chmod(SagaUtils.sagaBatchJobFilename(), stat.S_IEXEC)
68+
os.chmod(SagaUtils.sagaBatchJobFilename(), stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE)
7069
command = [SagaUtils.sagaBatchJobFilename()]
7170
loglines = []
7271
loglines.append("SAGA execution console output")

‎src/sextante/saga/UnwrappableSagaAlgorithmException.py

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,76 @@
11
from sextante.core.GeoAlgorithm import GeoAlgorithm
2+
from sextante.outputs.OutputVector import OutputVector
3+
from sextante.parameters.ParameterVector import ParameterVector
4+
from sextante.core.Sextante import Sextante
5+
from qgis.core import *
6+
from PyQt4.QtCore import *
7+
from PyQt4.QtGui import *
8+
29

310
class ExampleAlgorithm(GeoAlgorithm):
4-
pass
11+
'''This is an example algorithm that takes a vector layer and creates
12+
a new one just with just those features of the input layer that are
13+
selected.
14+
It is meant to be used as an example of how to create your own SEXTANTE
15+
algorithms and explain methods and variables used to do it.
16+
An algorithm like this will be available in all SEXTANTE elements, and
17+
there is not need for additional work.
18+
19+
All SEXTANTE algorithms should extend the GeoAlgorithm class'''
20+
21+
#constants used to refer to parameters and outputs.
22+
#They will be used when calling the algorithm from another algorithm,
23+
#or when calling SEXTANTE from the QGIS console.
24+
OUTPUT_LAYER = "OUTPUT_LAYER"
25+
INPUT_LAYER = "INPUT_LAYER"
26+
27+
def defineCharacteristics(self):
28+
'''Here we define the inputs and output of the algorithm, along
29+
with some other properties'''
30+
31+
#the name that the user will see in the toolbox
32+
self.name = "Create new layer with selected features"
33+
34+
#the branch of the toolbox under which the algorithm will appear
35+
self.group = "Algorithms for vector layers"
36+
37+
#we add the input vector layer. It can have any kind of geometry
38+
#It is a mandatory (not optional) one, hence the False argument
39+
self.addParameter(ParameterVector(self.INPUT_LAYER, "Input layer", ParameterVector.VECTOR_TYPE_ANY, False))
40+
41+
# we add a vector layer as output
42+
self.addOutput(OutputVector(self.OUTPUT_LAYER, "Output layer with selected features"))
43+
44+
45+
def processAlgorithm(self, progress):
46+
'''Here is where the processing itself takes place'''
47+
48+
#the first thing to do is retrieve the values of the parameters
49+
#entered by the user
50+
inputFilename = self.getParameterValue(self.INPUT_LAYER)
51+
output = self.getOutputValue(self.OUTPUT_LAYER)
52+
53+
#input layers vales are always a string whit its location.
54+
#That string can be converted into a QGIS object (a QgsVectorLayer in this case))
55+
#using the Sextante.getObject() method
56+
vectorLayer = Sextante.getObject(inputFilename)
57+
58+
#And now we can process
59+
60+
#First we create the output layer.
61+
#The output value entered by the user is a string containing a filename,
62+
#so we can use it directly
63+
settings = QSettings()
64+
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
65+
provider = vectorLayer.dataProvider()
66+
writer = QgsVectorFileWriter( output, systemEncoding,provider.fields(), provider.geometryType(), provider.crs() )
67+
68+
#Now we take the selected features and add them to the output layer
69+
selection = vectorLayer.selectedFeatures()
70+
for feat in selection:
71+
writer.addFeature(feat)
72+
del writer
73+
74+
#There is nothing more to do here. We do not have to open the layer that we have created.
75+
#SEXTANTE will take care of that, or will handle it if this algorithm is executed within
76+
#a complex model

‎src/sextanteexampleprovider/ExampleAlgorithmProvider.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,33 @@
11
from sextante.core.AlgorithmProvider import AlgorithmProvider
22
from sextanteexampleprovider.ExampleAlgorithm import ExampleAlgorithm
3+
from sextante.core.SextanteConfig import Setting, SextanteConfig
34

45
class ExampleAlgorithmProvider(AlgorithmProvider):
56

7+
MY_DUMMY_SETTING = "MY_DUMMY_SETTING"
8+
69
def __init__(self):
710
AlgorithmProvider.__init__(self)
811
self.alglist = [ExampleAlgorithm()]
912
for alg in self.alglist:
1013
alg.provider = self
1114

15+
def initializeSettings(self):
16+
'''In this method we add settings needed to configure our provider.
17+
Do not forget to call the parent method, since it takes care or
18+
automatically adding a setting for activating or deactivating the
19+
algorithms in the provider'''
20+
AlgorithmProvider.initializeSettings(self)
21+
SextanteConfig.addSetting(Setting("Example algorithms", ExampleAlgorithmProvider.MY_DUMMY_SETTING, "Example setting", "Default value"))
22+
23+
24+
def unload(self):
25+
'''Setting should be removed here, so they do not appear anymore
26+
when the plugin is unloaded'''
27+
AlgorithmProvider.unload(self)
28+
SextanteConfig.removeSetting( ExampleAlgorithmProvider.MY_DUMMY_SETTING)
29+
30+
1231
def getName(self):
1332
'''This is the name that will appear on the toolbox group.
1433
It is also used to create the command line name of all the algorithms
@@ -25,9 +44,9 @@ def _loadAlgorithms(self):
2544
This method is called whenever the list of algorithms should be updated.
2645
If the list of algorithms can change while executing SEXTANTE for QGIS
2746
(for instance, if it contains algorithms from user-defined scripts and
28-
a new algorithm might have been added), you should create the list again
47+
a new script might have been added), you should create the list again
2948
here.
30-
In this case, since the list is always de same, we assign from the premade list.
49+
In this case, since the list is always the same, we assign from the pre-made list.
3150
This assignment has to be done in this method even if the list does not change,
3251
since the self.algs list is cleared before calling this method'''
3352
self.algs = self.alglist

‎src/sextanteexampleprovider/SextanteExampleProviderPlugin.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,5 @@ def initGui(self):
1717
Sextante.addProvider(self.provider)
1818

1919
def unload(self):
20-
#Uncomment to add provider
2120
Sextante.removeProvider(self.provider)
2221

0 commit comments

Comments
 (0)
Please sign in to comment.