Showing with 674 additions and 247 deletions.
  1. +3 −1 python/plugins/sextante/about/about.htm
  2. +2 −4 python/plugins/sextante/algs/AddTableField.py
  3. +2 −4 python/plugins/sextante/algs/AutoincrementalField.py
  4. +2 −4 python/plugins/sextante/algs/EquivalentNumField.py
  5. +2 −5 python/plugins/sextante/algs/Explode.py
  6. +214 −0 python/plugins/sextante/algs/FieldPyculator.py
  7. +2 −4 python/plugins/sextante/algs/FieldsCalculator.py
  8. +4 −6 python/plugins/sextante/algs/SaveSelectedFeatures.py
  9. +5 −1 python/plugins/sextante/algs/SextanteAlgorithmProvider.py
  10. +49 −0 python/plugins/sextante/algs/SextanteVectorWriter.py
  11. +15 −2 python/plugins/sextante/core/AlgorithmProvider.py
  12. +16 −5 python/plugins/sextante/core/GeoAlgorithm.py
  13. +5 −8 python/plugins/sextante/core/Sextante.py
  14. +7 −2 python/plugins/sextante/core/SextanteConfig.py
  15. +8 −0 python/plugins/sextante/core/SextanteLog.py
  16. +3 −9 python/plugins/sextante/ftools/Buffer.py
  17. +1 −6 python/plugins/sextante/ftools/Centroids.py
  18. +9 −9 python/plugins/sextante/ftools/ConvexHull.py
  19. +1 −4 python/plugins/sextante/ftools/Delaunay.py
  20. +1 −4 python/plugins/sextante/ftools/Difference.py
  21. +1 −6 python/plugins/sextante/ftools/Dissolve.py
  22. +1 −4 python/plugins/sextante/ftools/ExportGeometryInfo.py
  23. +1 −4 python/plugins/sextante/ftools/ExtentFromLayer.py
  24. +1 −4 python/plugins/sextante/ftools/ExtractNodes.py
  25. +3 −0 python/plugins/sextante/ftools/FToolsAlgorithmProvider.py
  26. +6 −2 python/plugins/sextante/ftools/FixedDistanceBuffer.py
  27. +1 −4 python/plugins/sextante/ftools/Intersection.py
  28. +1 −4 python/plugins/sextante/ftools/LayerFromExtent.py
  29. +1 −8 python/plugins/sextante/ftools/LinesIntersection.py
  30. +1 −4 python/plugins/sextante/ftools/LinesToPolygons.py
  31. +1 −4 python/plugins/sextante/ftools/MeanCoords.py
  32. +1 −5 python/plugins/sextante/ftools/MultipartToSingleparts.py
  33. +1 −8 python/plugins/sextante/ftools/PointsInPolygon.py
  34. +1 −7 python/plugins/sextante/ftools/PolygonsToLines.py
  35. +3 −10 python/plugins/sextante/ftools/SimplifyGeometries.py
  36. +32 −11 python/plugins/sextante/ftools/SinglePartsToMultiparts.py
  37. +1 −9 python/plugins/sextante/ftools/SumLines.py
  38. +1 −4 python/plugins/sextante/ftools/Union.py
  39. +6 −2 python/plugins/sextante/ftools/VariableDistanceBuffer.py
  40. +1 −4 python/plugins/sextante/ftools/VoronoiPolygons.py
  41. +2 −1 python/plugins/sextante/grass/GrassAlgorithm.py
  42. +1 −0 python/plugins/sextante/grass/GrassUtils.py
  43. +84 −33 python/plugins/sextante/gui/AlgorithmExecutionDialog.py
  44. +21 −5 python/plugins/sextante/gui/AlgorithmExecutor.py
  45. +2 −0 python/plugins/sextante/gui/ConfigDialog.py
  46. +48 −13 python/plugins/sextante/gui/OutputSelectionPanel.py
  47. +12 −0 python/plugins/sextante/gui/ParametersPanel.py
  48. +9 −4 python/plugins/sextante/gui/SextantePostprocessing.py
  49. +9 −0 python/plugins/sextante/gui/UnthreadedAlgorithmExecutor.py
  50. +14 −1 python/plugins/sextante/modeler/ModelerAlgorithm.py
  51. +4 −2 python/plugins/sextante/otb/OTBAlgorithm.py
  52. +1 −0 python/plugins/sextante/otb/OTBUtils.py
  53. +33 −1 python/plugins/sextante/outputs/OutputVector.py
  54. +2 −1 python/plugins/sextante/parameters/ParameterString.py
  55. +10 −1 python/plugins/sextante/r/RAlgorithm.py
  56. +3 −1 python/plugins/sextante/r/RUtils.py
  57. +1 −1 python/plugins/sextante/saga/SagaAlgorithm.py
  58. +1 −0 python/plugins/sextante/saga/SagaUtils.py
  59. +1 −1 python/plugins/sextante/tests/runtests.sh
4 changes: 3 additions & 1 deletion python/plugins/sextante/about/about.htm
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ <h2>SEXTANTE for QGIS</h2>
<p>A development by Victor Olaya (volayaf@gmail.com).</p>
<p>Portions of this software contributed by:
<ul>
<li>Michael Nimm (mmqgis algorithms)</li>
<li>Alexander Bruy</li>
<li>Carson Farmer (fTools algorithms)</li>
<li>Julien Malik (Orfeo Toolbox connectors)</li>
<li>Evgeniy Nikulin (Original Field Pyculator code)</li>
<li>Michael Nimm (mmqgis algorithms)</li>
<li>Camilo Polymeris (Threading). Developed as part of Google Summer of Code 2012</li>
</ul>
</p>
Expand Down
6 changes: 2 additions & 4 deletions python/plugins/sextante/algs/AddTableField.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,14 @@ def defineCharacteristics(self):
def processAlgorithm(self, progress):
fieldtype = self.getParameterValue(self.FIELD_TYPE)
fieldname = self.getParameterValue(self.FIELD_NAME)
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(self.OUTPUT_LAYER)
output = self.getOutputFromName(self.OUTPUT_LAYER)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT_LAYER))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
fields[len(fields)] = QgsField(fieldname, self.TYPES[fieldtype])
writer = QgsVectorFileWriter( output, systemEncoding,fields, vprovider.geometryType(), vprovider.crs() )
writer = output.getVectorWriter(fields, vprovider.geometryType(), vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
Expand Down
6 changes: 2 additions & 4 deletions python/plugins/sextante/algs/AutoincrementalField.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/toolbox.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(self.OUTPUT)
output = self.getOutputFromName(self.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
fields[len(fields)] = QgsField("AUTO", QVariant.Int)
writer = QgsVectorFileWriter( output, systemEncoding,fields, vprovider.geometryType(), vprovider.crs() )
writer = output.getVectorWriter(fields, vprovider.geometryType(), vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
Expand Down
6 changes: 2 additions & 4 deletions python/plugins/sextante/algs/EquivalentNumField.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,14 @@ def getIcon(self):

def processAlgorithm(self, progress):
field_index = self.getParameterValue(self.FIELD)
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(self.OUTPUT)
output = self.getOutputFromName(self.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
fields[len(fields)] = QgsField("NUM_FIELD", QVariant.Int)
writer = QgsVectorFileWriter( output, systemEncoding,fields, vprovider.geometryType(), vprovider.crs() )
writer = output.getVectorWriter(fields, vprovider.geometryType(), vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
Expand Down
7 changes: 2 additions & 5 deletions python/plugins/sextante/algs/Explode.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/../images/toolbox.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT))
output = self.getOutputValue(self.OUTPUT)
output = self.getOutputFromName(self.OUTPUT)
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
writer = QgsVectorFileWriter( output, systemEncoding,
fields, QGis.WKBLineString, vprovider.crs() )
writer = output.getVectorWriter(fields, QGis.WKBLineString, vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
Expand Down
214 changes: 214 additions & 0 deletions python/plugins/sextante/algs/FieldPyculator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
from sextante.core.GeoAlgorithm import GeoAlgorithm
from sextante.outputs.OutputVector import OutputVector
from sextante.parameters.ParameterVector import ParameterVector
from qgis.core import *
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from sextante.parameters.ParameterString import ParameterString
from sextante.core.QGisLayers import QGisLayers
import os
from PyQt4 import QtGui
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from sextante.parameters.ParameterBoolean import ParameterBoolean
import sys


class FieldsPyculator(GeoAlgorithm):

INPUT_LAYER = "INPUT_LAYER"
USE_SELECTED = "USE_SELECTED"
FIELD_NAME = "FIELD_NAME"
GLOBAL = "GLOBAL"
FORMULA = "FORMULA"
OUTPUT_LAYER ="OUTPUT_LAYER"
RESULT_VAR_NAME = "value"

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

def defineCharacteristics(self):
self.name = "Field Pyculator"
self.group = "Algorithms for vector layers"
self.addParameter(ParameterVector(self.INPUT_LAYER, "Input layer", ParameterVector.VECTOR_TYPE_ANY, False))
self.addParameter(ParameterBoolean(self.USE_SELECTED, "Use only selected features", False))
self.addParameter(ParameterString(self.FIELD_NAME, "Result field name", "NewField"))
self.addParameter(ParameterString(self.GLOBAL, "Global expression", multiline = True))
self.addParameter(ParameterString(self.FORMULA, "Formula", "value = ", multiline = True))
self.addOutput(OutputVector(self.OUTPUT_LAYER, "Output layer"))


def processAlgorithm(self, progress):
fieldname = self.getParameterValue(self.FIELD_NAME)
code = self.getParameterValue(self.FORMULA)
globalExpression = self.getParameterValue(self.GLOBAL)
useSelected = self.getParameterValue(self.USE_SELECTED)
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputFromName(self.OUTPUT_LAYER)
layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT_LAYER))
vprovider = layer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
fields[len(fields)] = QgsField(fieldname, QVariant.Double)
writer = output.getVectorWriter(fields, vprovider.geometryType(), vprovider.crs() )
outFeat = QgsFeature()
nFeatures = vprovider.featureCount()
nElement = 0
new_ns = {}

#run global code
if globalExpression.strip() != "":
try:
bytecode = compile(globalExpression, '<string>', 'exec')
exec bytecode in new_ns
except:
raise GeoAlgorithmExecutionException("FieldPyculator code execute error\n" +
"Global code block can't be executed!%s \n %s" %
(unicode(sys.exc_info()[0].__name__), unicode(sys.exc_info()[1])))

#replace all fields tags
field_map = vprovider.fields()
for num, field in field_map.iteritems():
field_name = unicode(field.name())
replval = '__attr[' + str(num) + ']'
code = code.replace("<"+field_name+">",replval)

#replace all special vars
code = code.replace('$id','__id')
code = code.replace('$geom','__geom')
need_id = code.find("__id") != -1
need_geom = code.find("__geom") != -1
need_attrs = code.find("__attr") != -1


#compile
try:
bytecode = compile(code, '<string>', 'exec')
except:
raise GeoAlgorithmExecutionException("FieldPyculator code execute error\n"+
"Field code block can't be executed! %s \n %s"
(unicode(sys.exc_info()[0].__name__), unicode(sys.exc_info()[1])))


#run
if not useSelected:
feat = QgsFeature()
if need_attrs:
attr_ind = vprovider.attributeIndexes()
else:
attr_ind = []
vprovider.select(attr_ind, QgsRectangle(), True)

while vprovider.nextFeature(feat):
progress.setPercentage(int((100 * nElement)/nFeatures))
attrMap = feat.attributeMap()
feat_id = feat.id()

#add needed vars
if need_id:
new_ns['__id'] = feat_id

if need_geom:
geom = feat.geometry()
new_ns['__geom'] = geom

if need_attrs:
attr = []
for num,a in attrMap.iteritems():
attr.append(self.Qvar2py(a))
new_ns['__attr'] = attr

#clear old result
if new_ns.has_key(self.RESULT_VAR_NAME):
del new_ns[self.RESULT_VAR_NAME]


#exec
#try:
exec bytecode in new_ns
#except:
# raise e
#===============================================================
# GeoAlgorithmExecutionException("FieldPyculator code execute error\n"+
# "Field code block can't be executed for feature %s\n%s\n%s" %
# (unicode(sys.exc_info()[0].__name__),
# unicode(sys.exc_info()[1]),
# unicode(feat_id)))
#===============================================================

#check result
if not new_ns.has_key(self.RESULT_VAR_NAME):
raise GeoAlgorithmExecutionException("FieldPyculator code execute error\n" +
"Field code block does not return '%s1' variable! Please declare this variable in your code!" %
self.RESULT_VAR_NAME)


#write feature
nElement += 1
outFeat.setGeometry( feat.geometry() )
outFeat.setAttributeMap( attrMap )
outFeat.addAttribute(len(vprovider.fields()), QVariant(new_ns[self.RESULT_VAR_NAME]))
writer.addFeature(outFeat)

else:
features = layer.selectedFeatures()
nFeatures = len(features)
for feat in features:
progress.setPercentage(int((100 * nElement)/nFeatures))
attrMap = feat.attributeMap()
feat_id = feat.id()

#add needed vars
if need_id:
new_ns['__id'] = feat_id

if need_geom:
geom = feat.geometry()
new_ns['__geom'] = geom

if need_attrs:
attrMap = feat.attributeMap()
attr = []
for num,a in attrMap.iteritems():
attr.append(self.Qvar2py(a))
new_ns['__attr'] = attr

#clear old result
if new_ns.has_key(self.RESULT_VAR_NAME):
del new_ns[self.RESULT_VAR_NAME]

#exec
exec bytecode in new_ns

#check result
if not new_ns.has_key(self.RESULT_VAR_NAME):
raise GeoAlgorithmExecutionException("FieldPyculator code execute error\n" +
"Field code block does not return '%s1' variable! Please declare this variable in your code!" %
self.RESULT_VAR_NAME)

#write feature
nElement += 1
outFeat.setGeometry( feat.geometry() )
outFeat.setAttributeMap( attrMap )
outFeat.addAttribute(len(vprovider.fields()), QVariant(new_ns[self.RESULT_VAR_NAME]))
writer.addFeature(outFeat)

del writer


def Qvar2py(self,qv):
if qv.type() == 2:
return qv.toInt()[0]
if qv.type() == 10:
return unicode(qv.toString())
if qv.type() == 6:
return qv.toDouble()[0]
return None


def checkParameterValuesBeforeExecuting(self):
##TODO check that formula is correct and fields exist
pass


6 changes: 2 additions & 4 deletions python/plugins/sextante/algs/FieldsCalculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,14 @@ def defineCharacteristics(self):
def processAlgorithm(self, progress):
fieldname = self.getParameterValue(self.FIELD_NAME)
formula = self.getParameterValue(self.FORMULA)
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(self.OUTPUT_LAYER)
output = self.getOutputFromName(self.OUTPUT_LAYER)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT_LAYER))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
fields[len(fields)] = QgsField(fieldname, QVariant.Double)
writer = QgsVectorFileWriter( output, systemEncoding,fields, vprovider.geometryType(), vprovider.crs() )
writer = output.getVectorWriter(fields, vprovider.geometryType(), vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
Expand Down
10 changes: 4 additions & 6 deletions python/plugins/sextante/algs/SaveSelectedFeatures.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def processAlgorithm(self, progress):
#the first thing to do is retrieve the values of the parameters
#entered by the user
inputFilename = self.getParameterValue(self.INPUT_LAYER)
output = self.getOutputValue(self.OUTPUT_LAYER)
output = self.getOutputFromName(self.OUTPUT_LAYER)

#input layers values are always a string with its location.
#That string can be converted into a QGIS object (a QgsVectorLayer in this case))
Expand All @@ -60,12 +60,10 @@ def processAlgorithm(self, progress):
#And now we can process

#First we create the output layer.
#The output value entered by the user is a string containing a filename,
#so we can use it directly
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
#To do so, we call the getVectorWriter method in the Output object.
#That will give as a SextanteVectorWriter, that we can later use to add features.
provider = vectorLayer.dataProvider()
writer = QgsVectorFileWriter( output, systemEncoding, provider.fields(), provider.geometryType(), provider.crs() )
writer = output.getVectorWriter( provider.fields(), provider.geometryType(), provider.crs() )

#Now we take the selected features and add them to the output layer
selection = vectorLayer.selectedFeatures()
Expand Down
6 changes: 5 additions & 1 deletion python/plugins/sextante/algs/SextanteAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
from sextante.algs.SaveSelectedFeatures import SaveSelectedFeatures
from sextante.algs.Explode import Explode
from sextante.algs.AutoincrementalField import AutoincrementalField
from sextante.algs.FieldPyculator import FieldsPyculator

class SextanteAlgorithmProvider(AlgorithmProvider):

def __init__(self):
AlgorithmProvider.__init__(self)
self.alglist = [AddTableField(), FieldsCalculator(), SaveSelectedFeatures(),
AutoincrementalField(), Explode()]
AutoincrementalField(), Explode(), FieldsPyculator()]

def initializeSettings(self):
AlgorithmProvider.initializeSettings(self)
Expand All @@ -33,3 +34,6 @@ def getIcon(self):

def _loadAlgorithms(self):
self.algs = self.alglist

def supportsNonFileBasedOutput(self):
return True
Loading