18 changes: 9 additions & 9 deletions python/plugins/sextante/ftools/ConvexHull.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/convex_hull.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(ConvexHull.OUTPUT)
useSelection = self.getParameterValue(ConvexHull.USE_SELECTED)
useField = (self.getParameterValue(ConvexHull.METHOD) == 1)
field = self.getParameterValue(ConvexHull.FIELD)
Expand All @@ -39,27 +36,30 @@ def processAlgorithm(self, progress):
vproviderA = vlayerA.dataProvider()
allAttrsA = vproviderA.attributeIndexes()
vproviderA.select(allAttrsA)
fields = vproviderA.fields()
writer = QgsVectorFileWriter(output, systemEncoding, fields, QGis.WKBPolygon, vproviderA.crs() )
fields = { 0 : QgsField("ID", QVariant.Int),
1 : QgsField("Area", QVariant.Double),
2 : QgsField("Perim", QVariant.Double) }
writer = self.getOutputFromName(ConvexHull.OUTPUT).getVectorWriter(fields, QGis.WKBPolygon, vproviderA.crs())
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
outGeom = QgsGeometry()
nElement = 0
index = vproviderA.fieldNameIndex(field)
# there is selection in input layer
if useSelection:
nFeat = vlayerA.selectedFeatureCount()
selectionA = vlayerA.selectedFeatures()
if useField:
unique = ftools_utils.getUniqueValues( vproviderA, field )
unique = ftools_utils.getUniqueValues( vproviderA, index )
nFeat = nFeat * len( unique )
for i in unique:
hull = []
first = True
outID = 0
for inFeat in selectionA:
atMap = inFeat.attributeMap()
idVar = atMap[ self.myParam ]
idVar = atMap[ index ]
if idVar.toString().trimmed() == i.toString().trimmed():
if first:
outID = idVar
Expand Down Expand Up @@ -102,7 +102,7 @@ def processAlgorithm(self, progress):
rect = vlayerA.extent()
nFeat = vproviderA.featureCount()
if useField:
unique = ftools_utils.getUniqueValues( vproviderA, self.myParam )
unique = ftools_utils.getUniqueValues( vproviderA, index )
nFeat = nFeat * len( unique )
for i in unique:
hull = []
Expand All @@ -112,7 +112,7 @@ def processAlgorithm(self, progress):
#vproviderA.rewind()
while vproviderA.nextFeature( inFeat ):
atMap = inFeat.attributeMap()
idVar = atMap[ self.myParam ]
idVar = atMap[ index ]
if idVar.toString().trimmed() == i.toString().trimmed():
if first:
outID = idVar
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/Delaunay.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/delaunay.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(Delaunay.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(Delaunay.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
Expand All @@ -30,7 +27,7 @@ def processAlgorithm(self, progress):
0 : QgsField( "POINTA", QVariant.Double ),
1 : QgsField( "POINTB", QVariant.Double ),
2 : QgsField( "POINTC", QVariant.Double ) }
writer = QgsVectorFileWriter( output, systemEncoding, fields, QGis.WKBPolygon, vprovider.crs() )
writer = self.getOutputFromName(Delaunay.OUTPUT).getVectorWriter(fields, QGis.WKBPolygon, vprovider.crs() )
inFeat = QgsFeature()
c = voronoi.Context()
pts = []
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/Difference.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/difference.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(Difference.OUTPUT)
useSelection = self.getParameterValue(Difference.USE_SELECTED)
useSelection2 = self.getParameterValue(Difference.USE_SELECTED2)
vlayerA = QGisLayers.getObjectFromUri(self.getParameterValue(Difference.INPUT))
Expand All @@ -48,7 +45,7 @@ def processAlgorithm(self, progress):
else:
if not crsA != crsB:
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Difference. Non-matching CRSs. Results might be unexpected")
writer = QgsVectorFileWriter(output, systemEncoding, fields, vproviderA.geometryType(), vproviderA.crs() )
writer = self.getOutputFromName(Difference.OUTPUT).getVectorWriter(fields, vproviderA.geometryType(), vproviderA.crs() )
inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
Expand Down
7 changes: 1 addition & 6 deletions python/plugins/sextante/ftools/Dissolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/dissolve.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(Dissolve.OUTPUT)
useSelection = self.getParameterValue(Dissolve.USE_SELECTED)
useField = not self.getParameterValue(Dissolve.USE_SELECTED)
fieldname = self.getParameterValue(Dissolve.FIELD)
Expand All @@ -37,9 +34,7 @@ def processAlgorithm(self, progress):
vproviderA = vlayerA.dataProvider()
allAttrsA = vproviderA.attributeIndexes()
fields = vproviderA.fields()
writer = QgsVectorFileWriter( output, systemEncoding, fields, vproviderA.geometryType(), vproviderA.crs() )
if writer.hasError():
raise GeoAlgorithmExecutionException("Could not create output file");
writer = self.getOutputFromName(Dissolve.OUTPUT).getVectorWriter(fields, vproviderA.geometryType(), vproviderA.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
vproviderA.rewind()
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/ExportGeometryInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/export_geometry.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(ExportGeometryInfo.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(ExportGeometryInfo.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
( fields, index1, index2 ) = self.checkGeometryFields(vlayer)
writer = QgsVectorFileWriter( output, systemEncoding,fields, vprovider.geometryType(), vprovider.crs() )
writer = self.getOutputFromName(ExportGeometryInfo.OUTPUT).getVectorWriter(fields, vprovider.geometryType(), vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/ExtentFromLayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/layer_extent.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(ExtentFromLayer.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(ExtentFromLayer.INPUT))
fields = {
0 : QgsField( "MINX", QVariant.Double ),
Expand All @@ -33,7 +30,7 @@ def processAlgorithm(self, progress):
8 : QgsField( "HEIGHT", QVariant.Double ),
9 : QgsField( "WIDTH", QVariant.Double ) }

writer = QgsVectorFileWriter(output, systemEncoding, fields, QGis.WKBPolygon, vlayer.crs() )
writer = self.getOutputFromName(ExtentFromLayer.OUTPUT).getVectorWriter(fields, QGis.WKBPolygon, vlayer.crs() )
rect = vlayer.extent()
minx = rect.xMinimum()
miny = rect.yMinimum()
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/ExtractNodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/extract_nodes.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(ExtractNodes.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(ExtractNodes.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
writer = QgsVectorFileWriter( output, systemEncoding, fields, QGis.WKBPoint, vprovider.crs() )
writer = self.getOutputFromName(ExtractNodes.OUTPUT).getVectorWriter(fields, QGis.WKBPoint, vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
Expand Down
3 changes: 3 additions & 0 deletions python/plugins/sextante/ftools/FToolsAlgorithmProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,6 @@ def _loadAlgorithms(self):

def getSupportedOutputTableExtensions(self):
return ["csv"]

def supportsNonFileBasedOutput(self):
return True
8 changes: 6 additions & 2 deletions python/plugins/sextante/ftools/FixedDistanceBuffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/buffer.png")

def processAlgorithm(self, progress):
output = self.getOutputValue(FixedDistanceBuffer.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(FixedDistanceBuffer.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select(allAttrs)
writer = self.getOutputFromName(FixedDistanceBuffer.OUTPUT).getVectorWriter(vprovider.fields(), QGis.WKBPolygon, vprovider.crs() )
useSelection = self.getParameterValue(FixedDistanceBuffer.USE_SELECTED)
distance = self.getParameterValue(FixedDistanceBuffer.DISTANCE)
dissolve = self.getParameterValue(FixedDistanceBuffer.DISSOLVE)
segments = int(self.getParameterValue(FixedDistanceBuffer.SEGMENTS))
layer = QGisLayers.getObjectFromUri(self.getParameterValue(FixedDistanceBuffer.INPUT))
buff.buffering(progress, output, distance, None, useSelection, False, layer, dissolve, segments)
buff.buffering(progress, writer, distance, None, useSelection, False, layer, dissolve, segments)

def defineCharacteristics(self):
self.name = "Fixed distance buffer"
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/Intersection.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/intersect.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(Intersection.OUTPUT)
useSelection = self.getParameterValue(Intersection.USE_SELECTED)
useSelection2 = self.getParameterValue(Intersection.USE_SELECTED2)
vlayerA = QGisLayers.getObjectFromUri(self.getParameterValue(Intersection.INPUT))
Expand All @@ -51,7 +48,7 @@ def processAlgorithm(self, progress):
longNames = ftools_utils.checkFieldNameLength( fields )
if not longNames.isEmpty():
raise GeoAlgorithmExecutionException("Following field names are longer than 10 characters:\n" + longNames.join('\n') )
writer = QgsVectorFileWriter( output, systemEncoding, fields, vproviderA.geometryType(), vproviderA.crs() )
writer = self.getOutputFromName(Intersection.OUTPUT).getVectorWriter(fields, vproviderA.geometryType(), vproviderA.crs() )
inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/LayerFromExtent.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/layer_extent.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(LayerFromExtent.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(LayerFromExtent.INPUT))
fields = {
0 : QgsField( "MINX", QVariant.Double ),
Expand All @@ -34,7 +31,7 @@ def processAlgorithm(self, progress):
8 : QgsField( "HEIGHT", QVariant.Double ),
9 : QgsField( "WIDTH", QVariant.Double ) }

writer = QgsVectorFileWriter( output, systemEncoding, fields, QGis.WKBPolygon, self.vlayer.crs() )
writer = self.getOutputFromName(LayerFromExtent.OUTPUT).getVectorWriter(fields, QGis.WKBPolygon, self.vlayer.crs() )
rect = vlayer.extent()
minx = rect.xMinimum()
miny = rect.yMinimum()
Expand Down
9 changes: 1 addition & 8 deletions python/plugins/sextante/ftools/LinesIntersection.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/intersections.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(LinesIntersection.OUTPUT)
layer1 = QGisLayers.getObjectFromUri(self.getParameterValue(LinesIntersection.INPUT1))
layer2 = QGisLayers.getObjectFromUri(self.getParameterValue(LinesIntersection.INPUT2))
field1 = self.getParameterValue(LinesIntersection.FIELD1)
Expand All @@ -46,11 +43,7 @@ def processAlgorithm(self, progress):
field2.setName(unicode(field2.name()) + "_2")
fieldList = {0:field1, 1:field2}
sRs = provider1.crs()
check = QFile(output)
if check.exists():
if not QgsVectorFileWriter.deleteShapeFile(output):
raise GeoAlgorithmExecutionException("Could not delete existing output file")
writer = QgsVectorFileWriter(output, systemEncoding, fieldList, QGis.WKBPoint, sRs)
writer = self.getOutputFromName(LinesIntersection.OUTPUT).getVectorWriter(fieldList, QGis.WKBPoint, sRs)
#writer = QgsVectorFileWriter(outPath, "UTF-8", fieldList, QGis.WKBPoint, sRs)
inFeat = QgsFeature()
inFeatB = QgsFeature()
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/LinesToPolygons.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,12 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/to_lines.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(LinesToPolygons.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(LinesToPolygons.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
writer = QgsVectorFileWriter( output, systemEncoding, fields, QGis.WKBPolygon, vprovider.crs() )
writer = self.getOutputFromName(LinesToPolygons.OUTPUT).getVectorWriter(fields, QGis.WKBPolygon, vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/MeanCoords.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/mean.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(MeanCoords.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(MeanCoords.POINTS))
weightField = self.getParameterValue(MeanCoords.WEIGHT)
uniqueField = self.getParameterValue(MeanCoords.UID)
Expand All @@ -42,7 +39,7 @@ def processAlgorithm(self, progress):
uniqueValues = [QVariant(1)]
single = True
fieldList = { 0 : QgsField("MEAN_X", QVariant.Double), 1 : QgsField("MEAN_Y", QVariant.Double), 2 : QgsField("UID", QVariant.String) }
writer = QgsVectorFileWriter(output, systemEncoding, fieldList, QGis.WKBPoint, sRs)
writer = self.getOutputFromName(MeanCoords.OUTPUT).getVectorWriter(fieldList, QGis.WKBPoint, sRs)
outfeat = QgsFeature()
points = []
weights = []
Expand Down
6 changes: 1 addition & 5 deletions python/plugins/sextante/ftools/MultipartToSingleparts.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,13 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/multi_to_single.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)
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
geomType = self.multiToSingleGeom(vprovider.geometryType())
writer = QgsVectorFileWriter( output, systemEncoding,
fields, geomType, vprovider.crs() )
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, geomType, vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
Expand Down
9 changes: 1 addition & 8 deletions python/plugins/sextante/ftools/PointsInPolygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/sum_points.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(PointsInPolygon.OUTPUT)
inField = self.getParameterValue(PointsInPolygon.FIELD)
polyLayer = QGisLayers.getObjectFromUri(self.getParameterValue(PointsInPolygon.POLYGONS))
pointLayer = QGisLayers.getObjectFromUri(self.getParameterValue(PointsInPolygon.POINTS))
Expand All @@ -45,11 +42,7 @@ def processAlgorithm(self, progress):
field = QgsField(unicode(inField), QVariant.Double, "real", 24, 15, "point count field")
fieldList[index] = field
sRs = polyProvider.crs()
check = QFile(output)
if check.exists():
if not QgsVectorFileWriter.deleteShapeFile(output):
raise GeoAlgorithmExecutionException("could not delete file: " + output)
writer = QgsVectorFileWriter(output, systemEncoding, fieldList, polyProvider.geometryType(), sRs)
writer = self.getOutputFromName(PointsInPolygon.OUTPUT).getVectorWriter(fieldList, polyProvider.geometryType(), sRs)
inFeat = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
Expand Down
8 changes: 1 addition & 7 deletions python/plugins/sextante/ftools/PolygonsToLines.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,22 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/to_lines.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(PolygonsToLines.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(PolygonsToLines.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
writer = QgsVectorFileWriter( output, systemEncoding,fields, QGis.WKBLineString, vprovider.crs() )
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QGis.WKBLineString, vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
outGeom = QgsGeometry()
nFeat = vprovider.featureCount()
nElement = 0
#self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), 0)
#self.emit( SIGNAL( "runRange(PyQt_PyObject)" ), ( 0, nFeat ) )
while vprovider.nextFeature(inFeat):
multi = False
nElement += 1
progress.setPercentage(int(nElement/nFeat * 100))
#self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), nElement )
inGeom = inFeat.geometry()
if inGeom.isMultipart():
multi = True
Expand Down
13 changes: 3 additions & 10 deletions python/plugins/sextante/ftools/SimplifyGeometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,10 @@ def getIcon(self):
def processAlgorithm(self, progress):
self.processedFeatures = 0
self.progress = progress
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(SimplifyGeometries.OUTPUT)
tolerance =self.getParameterValue(SimplifyGeometries.TOLERANCE)
useSelection = self.getParameterValue(SimplifyGeometries.USE_SELECTION)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(SimplifyGeometries.INPUT))
self.generalize(vlayer, useSelection, tolerance, output, systemEncoding)
self.generalize(vlayer, useSelection, tolerance)


def defineCharacteristics(self):
Expand All @@ -56,16 +53,12 @@ def geomVertexCount(self, geometry):
else:
return None

def generalize( self, inputLayer, useSelection, tolerance, shapePath, shapeEncoding ):
def generalize( self, inputLayer, useSelection, tolerance):
self.inputLayer = inputLayer
self.useSelection = useSelection
self.tolerance = tolerance
self.outputFileName = shapePath
self.outputEncoding = shapeEncoding
self.shapeFileWriter = None
self.pointsBefore = 0
self.pointsAfter = 0
shapeFileWriter = None
vProvider = self.inputLayer.dataProvider()
allAttrs = vProvider.attributeIndexes()
vProvider.select( allAttrs )
Expand All @@ -74,7 +67,7 @@ def generalize( self, inputLayer, useSelection, tolerance, shapePath, shapeEncod
wkbType = self.inputLayer.wkbType()
if not crs.isValid():
crs = None
shapeFileWriter = QgsVectorFileWriter( self.outputFileName, self.outputEncoding, shapeFields, wkbType, crs )
shapeFileWriter = self.getOutputFromName(SimplifyGeometries.OUTPUT).getVectorWriter(shapeFields, wkbType, crs )
featureId = 0
if self.useSelection:
selection = self.inputLayer.selectedFeatures()
Expand Down
43 changes: 32 additions & 11 deletions python/plugins/sextante/ftools/SinglePartsToMultiparts.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,22 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/single_to_multi.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(SinglePartsToMultiparts.INPUT))
output = self.getOutputValue(SinglePartsToMultiparts.OUTPUT)
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
fields = vprovider.fields()
geomType = self.singleToMultiGeom(vprovider.geometryType())
writer = QgsVectorFileWriter( output, systemEncoding,
fields, geomType, vprovider.crs() )
writer = self.getOutputFromName(SinglePartsToMultiparts.OUTPUT).getVectorWriter(fields, geomType, vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
inGeom = QgsGeometry()
outGeom = QgsGeometry()
index = int(self.getParameterValue(SinglePartsToMultiparts.FIELD))
field = self.getParameterValue(SinglePartsToMultiparts.FIELD)
index = vprovider.fieldNameIndex(field)
unique = ftools_utils.getUniqueValues( vprovider, int( index ) )
nFeat = vprovider.featureCount() * len( unique )
nElement = 0
#self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), 0 )
# self.emit( SIGNAL( "runRange(PyQt_PyObject)" ), ( 0, nFeat ) )
if not len( unique ) == vlayer.featureCount():
for i in unique:
vprovider.rewind()
Expand All @@ -60,7 +55,6 @@ def processAlgorithm(self, progress):
feature_list = self.extractAsMulti( inGeom )
multi_feature.extend( feature_list )
nElement += 1
#self.emit( SIGNAL( "runStatus(PyQt_PyObject)" ), nElement )
outFeat.setAttributeMap( atts )
outGeom = QgsGeometry( self.convertGeometry(multi_feature, vType) )
outFeat.setGeometry(outGeom)
Expand All @@ -69,8 +63,26 @@ def processAlgorithm(self, progress):
else:
raise GeoAlgorithmExecutionException("Invalid unique ID Field")

def extractAsMulti( self, geom ):
temp_geom = []
if geom.type() == 0:
if geom.isMultipart():
return geom.asMultiPoint()
else:
return [ geom.asPoint() ]
elif geom.type() == 1:
if geom.isMultipart():
return geom.asMultiPolyline()
else:
return [ geom.asPolyline() ]
else:
if geom.isMultipart():
return geom.asMultiPolygon()
else:
return [ geom.asPolygon() ]

def singleToMultiGeom(self, wkbType):
try:
try:
if wkbType in (QGis.WKBPoint, QGis.WKBMultiPoint,
QGis.WKBPoint25D, QGis.WKBMultiPoint25D):
return QGis.WKBMultiPoint
Expand All @@ -82,9 +94,18 @@ def singleToMultiGeom(self, wkbType):
return QGis.WKBMultiPolygon
else:
return QGis.WKBUnknown
except Exception, err:
except Exception, err:
print str(err)

def convertGeometry( self, geom_list, vType ):
if vType == 0:
return QgsGeometry().fromMultiPoint( geom_list )
elif vType == 1:
return QgsGeometry().fromMultiPolyline( geom_list )
else:
return QgsGeometry().fromMultiPolygon( geom_list )


def defineCharacteristics(self):
self.name = "Singleparts to multipart"
self.group = "Geometry tools"
Expand Down
10 changes: 1 addition & 9 deletions python/plugins/sextante/ftools/SumLines.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/sum_lines.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(SumLines.OUTPUT)
inField = self.getParameterValue(SumLines.FIELD)
lineLayer = QGisLayers.getObjectFromUri(self.getParameterValue(SumLines.LINES))
polyLayer = QGisLayers.getObjectFromUri(self.getParameterValue(SumLines.POLYGONS))
Expand Down Expand Up @@ -54,12 +51,7 @@ def processAlgorithm(self, progress):
lineProvider.rewind()
start = 15.00
add = 85.00 / polyProvider.featureCount()
check = QFile(output)
if check.exists():
if not QgsVectorFileWriter.deleteShapeFile(output):
raise GeoAlgorithmExecutionException("Could not delete existing output file")
writer = QgsVectorFileWriter(output, systemEncoding, fieldList, polyProvider.geometryType(), sRs)
#writer = QgsVectorFileWriter(outPath, "UTF-8", fieldList, polyProvider.geometryType(), sRs)
writer = self.getOutputFromName(SumLines.OUTPUT).getVectorWriter(fieldList, polyProvider.geometryType(), sRs)
spatialIndex = ftools_utils.createIndex( lineProvider )
while polyProvider.nextFeature(inFeat):
inGeom = QgsGeometry(inFeat.geometry())
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/Union.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/union.png")

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(Union.OUTPUT)
vlayerA = QGisLayers.getObjectFromUri(self.getParameterValue(Union.INPUT))
vlayerB = QGisLayers.getObjectFromUri(self.getParameterValue(Union.INPUT2))
GEOS_EXCEPT = True
Expand All @@ -47,7 +44,7 @@ def processAlgorithm(self, progress):
longNames = ftools_utils.checkFieldNameLength( fields )
if not longNames.isEmpty():
raise GeoAlgorithmExecutionException("Following field names are longer than 10 characters:\n" + longNames.join('\n') )
writer = QgsVectorFileWriter( output, systemEncoding, fields, vproviderA.geometryType(), vproviderA.crs() )
writer = self.getOutputFromName(Union.OUTPUT).getVectorWriter(fields, vproviderA.geometryType(), vproviderA.crs() )
inFeatA = QgsFeature()
inFeatB = QgsFeature()
outFeat = QgsFeature()
Expand Down
8 changes: 6 additions & 2 deletions python/plugins/sextante/ftools/VariableDistanceBuffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,17 @@ def getIcon(self):
return QtGui.QIcon(os.path.dirname(__file__) + "/icons/buffer.png")

def processAlgorithm(self, progress):
output = self.getOutputValue(VariableDistanceBuffer.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(VariableDistanceBuffer.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select(allAttrs)
writer = self.getOutputFromName(VariableDistanceBuffer.OUTPUT).getVectorWriter(vprovider.fields(), QGis.WKBPolygon, vprovider.crs() )
useSelection = self.getParameterValue(VariableDistanceBuffer.USE_SELECTED)
dissolve = self.getParameterValue(VariableDistanceBuffer.DISSOLVE)
field = self.getParameterValue(VariableDistanceBuffer.FIELD)
segments = int(self.getParameterValue(VariableDistanceBuffer.SEGMENTS))
layer = QGisLayers.getObjectFromUri(self.getParameterValue(VariableDistanceBuffer.INPUT))
buff.buffering(progress, output, 0, field, useSelection, True, layer, dissolve, segments)
buff.buffering(progress, writer, 0, field, useSelection, True, layer, dissolve, segments)

def defineCharacteristics(self):
self.name = "Variable distance buffer"
Expand Down
5 changes: 1 addition & 4 deletions python/plugins/sextante/ftools/VoronoiPolygons.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,11 @@ class VoronoiPolygons(GeoAlgorithm):
OUTPUT = "OUTPUT"

def processAlgorithm(self, progress):
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" ).toString()
output = self.getOutputValue(VoronoiPolygons.OUTPUT)
vlayer = QGisLayers.getObjectFromUri(self.getParameterValue(VoronoiPolygons.INPUT))
vprovider = vlayer.dataProvider()
allAttrs = vprovider.attributeIndexes()
vprovider.select( allAttrs )
writer = QgsVectorFileWriter( output, systemEncoding, vprovider.fields(), QGis.WKBPolygon, vprovider.crs() )
writer = self.getOutputFromName(VoronoiPolygons.OUTPUT).getVectorWriter(vprovider.fields(), QGis.WKBPolygon, vprovider.crs() )
inFeat = QgsFeature()
outFeat = QgsFeature()
extent = vlayer.extent()
Expand Down
3 changes: 2 additions & 1 deletion python/plugins/sextante/grass/GrassAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,7 @@ def processAlgorithm(self, progress):
loglines = []
loglines.append("GRASS execution commands")
for line in commands:
progress.setCommand(line)
loglines.append(line)
if SextanteConfig.getSetting(GrassUtils.GRASS_LOG_COMMANDS):
SextanteLog.addToLog(SextanteLog.LOG_INFO, loglines)
Expand Down Expand Up @@ -340,4 +341,4 @@ def commandLineName(self):
# return "This algorithm cannot be run with the 'auto-region' setting\nPlease set a GRASS region before running it"
# else:
# return None
#===============================================================================
#===============================================================================
1 change: 1 addition & 0 deletions python/plugins/sextante/grass/GrassUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ def executeGrass(commands, progress):
pass
else:
loglines.append(line)
progress.setConsoleInfo(line)
if SextanteConfig.getSetting(GrassUtils.GRASS_LOG_CONSOLE):
SextanteLog.addToLog(SextanteLog.LOG_INFO, loglines)
shutil.rmtree(GrassUtils.grassMapsetFolder(), True)
Expand Down
117 changes: 84 additions & 33 deletions python/plugins/sextante/gui/AlgorithmExecutionDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from sextante.parameters.ParameterRange import ParameterRange
from sextante.parameters.ParameterNumber import ParameterNumber

from sextante.gui.ParametersPanel import ParametersPanel
from sextante.parameters.ParameterFile import ParameterFile
from sextante.parameters.ParameterCrs import ParameterCrs
from sextante.core.SextanteConfig import SextanteConfig
Expand All @@ -30,13 +29,18 @@
from sextante.core.WrongHelpFileException import WrongHelpFileException
import os
from sextante.gui.UnthreadedAlgorithmExecutor import UnthreadedAlgorithmExecutor
from sextante.parameters.ParameterString import ParameterString

try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s

class AlgorithmExecutionDialog(QtGui.QDialog):
class InvalidParameterValue(Exception):
def __init__(self, param, widget):
self.parameter, self.widget = param, widget

'''Base class for dialogs that execute algorithms'''
def __init__(self, alg, mainWidget):
QtGui.QDialog.__init__(self, None, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
Expand Down Expand Up @@ -69,7 +73,9 @@ def __init__(self, alg, mainWidget):
self.verticalLayout.addWidget(self.tabWidget)
self.logText = QTextEdit()
self.logText.readOnly = True
if SextanteConfig.getSetting(SextanteConfig.USE_THREADS):
useThreads = SextanteConfig.getSetting(SextanteConfig.USE_THREADS)
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
if useThreads or keepOpen:
self.tabWidget.addTab(self.logText, "Log")
self.webView = QtWebKit.QWebView()
cssUrl = QtCore.QUrl(os.path.join(os.path.dirname(__file__), "help", "help.css"))
Expand Down Expand Up @@ -112,15 +118,15 @@ def setParamValues(self):
if isinstance(param, ParameterExtent):
continue
if not self.setParamValue(param, self.paramTable.valueItems[param.name]):
return False
raise AlgorithmExecutionDialog.InvalidParameterValue(param, self.paramTable.valueItems[param.name])

for param in params:
if isinstance(param, ParameterExtent):
value = self.paramTable.valueItems[param.name].getValue()
if value is not None:
param.value = value
else:
return False
raise AlgorithmExecutionDialog.InvalidParameterValue(param, self.paramTable.valueItems[param.name])

for output in outputs:
if output.hidden:
Expand Down Expand Up @@ -161,15 +167,27 @@ def setParamValue(self, param, widget):
return param.setValue(value)
elif isinstance(param, (ParameterNumber, ParameterFile, ParameterCrs, ParameterExtent)):
return param.setValue(widget.getValue())
elif isinstance(param, ParameterString):
if param.multiline:
return param.setValue(unicode(widget.toPlainText()))
else:
return param.setValue(unicode(widget.text()))
else:
return param.setValue(str(widget.text()))

return param.setValue(unicode(widget.text()))
@pyqtSlot()
def accept(self):
if self.setParamValues():
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
useThread = SextanteConfig.getSetting(SextanteConfig.USE_THREADS)
try:
self.setParamValues()
msg = self.alg.checkParameterValuesBeforeExecuting()
if msg:
QMessageBox.critical(self, "Unable to execute algorithm", msg)
if keepOpen or useThread:
self.setInfo("Unable to execute algorithm: %s" % msg, True)
self.tabWidget.setCurrentIndex(1) # log tab
else:
QMessageBox.critical(self, "Unable to execute algorithm", msg)
return
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(False)
self.buttonBox.button(QtGui.QDialogButtonBox.Close).setEnabled(False)
Expand All @@ -185,7 +203,6 @@ def accept(self):
self.progress.setMaximum(0)
self.progressLabel.setText("Processing algorithm...")
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
useThread = SextanteConfig.getSetting(SextanteConfig.USE_THREADS)
if useThread:
if iterateParam:
self.algEx = AlgorithmExecutor(self.alg, iterateParam)
Expand All @@ -200,11 +217,15 @@ def accept(self):
self.algEx.textChanged.connect(self.setText)
self.algEx.iterated.connect(self.iterate)
self.algEx.infoSet.connect(self.setInfo)
if SextanteConfig.getSetting(SextanteConfig.SHOW_DEBUG_IN_DIALOG):
self.algEx.commandSet.connect(self.setCommand)
self.algEx.debugInfoSet.connect(self.setDebugInfo)
self.algEx.consoleInfoSet.connect(self.setConsoleInfo)
self.algEx.start()
self.setInfo("Algorithm %s started" % self.alg.name)
self.setInfo("<b>Algorithm %s started</b>" % self.alg.name)
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(True)
self.tabWidget.setCurrentIndex(1) # log tab
else:
self.setInfo("<b>Algorithm %s starting...</b>" % self.alg.name)
if iterateParam:
UnthreadedAlgorithmExecutor.runalgIterating(self.alg, iterateParam, self)
else:
Expand All @@ -213,64 +234,94 @@ def accept(self):
SextanteLog.addToLog(SextanteLog.LOG_ALGORITHM, command)
if UnthreadedAlgorithmExecutor.runalg(self.alg, self):
self.finish()
else:
QMessageBox.critical(self, "Unable to execute algorithm", "Wrong or missing parameter values")
else:
QApplication.restoreOverrideCursor()
if not keepOpen:
self.close()
else:
self.resetGUI()
self.tabWidget.setCurrentIndex(1) # log tab
except AlgorithmExecutionDialog.InvalidParameterValue as ex:
try:
self.buttonBox.accepted.connect(lambda: ex.widget.setPalette(QPalette()))
palette = ex.widget.palette()
palette.setColor(QPalette.Base, QColor(255, 255, 0))
ex.widget.setPalette(palette)
self.progressLabel.setText("<b>Missing parameter value</b>")
return
except:
QMessageBox.critical(self, "Unable to execute algorithm", "Wrong or missing parameter values")

@pyqtSlot()
def finish(self):
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
SextantePostprocessing.handleAlgorithmResults(self.alg, not keepOpen)
self.executed = True
self.setInfo("Algorithm %s finished correctly" % self.alg.name)
self.setInfo("Algorithm %s finished" % self.alg.name)
QApplication.restoreOverrideCursor()
if not keepOpen:
self.close()
else:
self.progressLabel.setText("")
self.progress.setMaximum(100)
self.progress.setValue(0)
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True)
self.buttonBox.button(QtGui.QDialogButtonBox.Close).setEnabled(True)
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(False)
self.resetGUI()

@pyqtSlot(str)
def error(self, msg):
self.algEx.finished.disconnect()
QApplication.restoreOverrideCursor()
self.setInfo(msg, True)
QMessageBox.critical(self, "Error", msg)
keepOpen = SextanteConfig.getSetting(SextanteConfig.KEEP_DIALOG_OPEN)
self.setInfo(msg, True)
self.algEx.finished.disconnect()
if not keepOpen:
QMessageBox.critical(self, "Error", msg)
self.close()
else:
self.progressLabel.setText("")
self.progress.setValue(0)
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True)
self.resetGUI()
self.setInfo(msg, True)
self.tabWidget.setCurrentIndex(1) # log tab

@pyqtSlot(int)
def iterate(self, i):
self.setInfo("Algorithm %s iteration #%i completed" % (self.alg.name, i))
self.setInfo("<b>Algorithm %s iteration #%i completed</b>" % (self.alg.name, i))

@pyqtSlot()
def cancel(self):
self.setInfo("Algorithm %s canceled" % self.alg.name)
self.setInfo("<b>Algorithm %s canceled</b>" % self.alg.name)
try:
self.algEx.finished.disconnect()
self.algEx.terminate()
QApplication.restoreOverrideCursor()
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(False)
except:
pass
self.resetGUI()

def resetGUI(self):
QApplication.restoreOverrideCursor()
self.progressLabel.setText("")
self.progress.setValue(0)
self.progress.setMaximum(100)
self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(True)
self.buttonBox.button(QtGui.QDialogButtonBox.Close).setEnabled(True)
self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(False)


@pyqtSlot(str)
@pyqtSlot(str, bool)
def setInfo(self, msg, error = False):
if error:
SextanteLog.addToLog(SextanteLog.LOG_ERROR, msg)
self.logText.append('<b>' + msg + '</b>')
self.logText.append('<span style="color:red">' + msg + '</span>')
else:
SextanteLog.addToLog(SextanteLog.LOG_INFO, msg)
self.logText.append(msg)

@pyqtSlot(str)
def setCommand(self, cmd):
self.setInfo('<tt>' + cmd + '<tt>')

@pyqtSlot(str)
def setDebugInfo(self, msg):
self.setInfo('<span style="color:blue">' + msg + '</span>')

@pyqtSlot(str)
def setConsoleInfo(self, msg):
self.setCommand('<span style="color:darkgray">' + msg + '</span>')

def setPercentage(self, i):
if self.progress.maximum() == 0:
self.progress.setMaximum(100)
Expand Down
26 changes: 21 additions & 5 deletions python/plugins/sextante/gui/AlgorithmExecutor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
from sextante.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from sextante.core.QGisLayers import QGisLayers
from sextante.core.SextanteUtils import SextanteUtils
import sys

class AlgorithmExecutor(QThread):
percentageChanged = pyqtSignal(int)
textChanged = pyqtSignal(QString)
error = pyqtSignal(str)
internalError = pyqtSignal(BaseException)
iterated = pyqtSignal(int)
infoSet = pyqtSignal(str)
commandSet = pyqtSignal(str)
debugInfoSet = pyqtSignal(str)
consoleInfoSet = pyqtSignal(str)
#started & finished inherited from QThread

def __init__(self, alg, iterParam = None, parent = None):
Expand All @@ -27,6 +32,12 @@ def setPercentage(self, p):
self.algorithmExecutor.percentageChanged.emit(p)
def setInfo(self, info):
self.algorithmExecutor.infoSet.emit(info)
def setCommand(self, cmd):
self.algorithmExecutor.commandSet.emit(cmd)
def setDebugInfo(self, info):
self.algorithmExecutor.debugInfoSet.emit(info)
def setConsoleInfo(self, info):
self.algorithmExecutor.consoleInfoSet.emit(info)
self.progress = Progress(self)
if self.parameterToIterate:
self.run = self.runalgIterating
Expand All @@ -49,19 +60,24 @@ def setInfo(self, info):
del writer
else:
self.run = self.runalg
self.internalError.connect(self.raiseInternalError)

def raiseInternalError(self, error):
raise error

def runalg(self):
try:
self.algorithm.execute(self.progress)
except GeoAlgorithmExecutionException,e :
except GeoAlgorithmExecutionException, e :
self.error.emit(e.msg)
except BaseException,e:
self.error.emit(str(e))
print str(e)
except BaseException, e:
self.internalError.emit(e)
# catch *all* errors, because QGIS tries to handle them in the GUI, which is fatal, this
# being a separate thread.
except:
print "Error executing " + str(self)
msg = "Error executing " + str(self.alg.name) + "\n" + sys.exc_info()[0]
print msg
self.internalError.emit(msg)

def runalgIterating(self):
try:
Expand Down
2 changes: 2 additions & 0 deletions python/plugins/sextante/gui/ConfigDialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def fillTree(self):
groupItem.setIcon(0, icon)
#groupItem.setIcon(0,self.groupIcon)
for setting in settings[group]:
if setting.hidden:
continue
if text =="" or text.lower() in setting.description.lower():
settingItem = TreeSettingItem(setting, icon)
self.items[setting]=settingItem
Expand Down
61 changes: 48 additions & 13 deletions python/plugins/sextante/gui/OutputSelectionPanel.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from PyQt4 import QtGui, QtCore
import os.path
from sextante.core.SextanteConfig import SextanteConfig

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

from qgis.gui import *

class OutputSelectionPanel(QtGui.QWidget):
from sextante.core.SextanteConfig import SextanteConfig

class OutputSelectionPanel(QWidget):

lastOutputFolder = None
SAVE_TO_TEMP_FILE = "[Save to temporary file]"
Expand All @@ -12,36 +16,67 @@ def __init__(self, output, alg):
self.output = output
self.alg = alg
super(OutputSelectionPanel, self).__init__(None)
self.horizontalLayout = QtGui.QHBoxLayout(self)
self.horizontalLayout = QHBoxLayout(self)
self.horizontalLayout.setSpacing(2)
self.horizontalLayout.setMargin(0)
self.text = QtGui.QLineEdit()
self.text = QLineEdit()
if hasattr(self.text, 'setPlaceholderText'):
self.text.setPlaceholderText(OutputSelectionPanel.SAVE_TO_TEMP_FILE)
self.text.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
self.text.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.horizontalLayout.addWidget(self.text)
self.pushButton = QtGui.QPushButton()
self.pushButton = QPushButton()
self.pushButton.setText("...")
self.pushButton.clicked.connect(self.showSelectionDialog)
self.pushButton.clicked.connect(self.buttonPushed)
self.horizontalLayout.addWidget(self.pushButton)
self.setLayout(self.horizontalLayout)

def showSelectionDialog(self):
def buttonPushed(self):
popupmenu = QMenu()
saveToTemporaryFileAction = QAction("Save to a temporary file", self.pushButton)
saveToTemporaryFileAction.triggered.connect(self.saveToTemporaryFile)
popupmenu.addAction(saveToTemporaryFileAction )
if (self.alg.provider.supportsNonFileBasedOutput()):
saveToMemoryAction= QAction("Save to a memory layer...", self.pushButton)
saveToMemoryAction.triggered.connect(self.saveToMemory)
popupmenu.addAction(saveToMemoryAction)
saveToFileAction = QAction("Save to file...", self.pushButton)
saveToFileAction.triggered.connect(self.saveToFile)
popupmenu.addAction(saveToFileAction)

popupmenu.exec_(QCursor.pos())

def saveToTemporaryFile(self):
self.text.setText("")

def saveToMemory(self):
self.text.setText("memory:")

def saveToFile(self):
filefilter = self.output.getFileFilter(self.alg)
settings = QtCore.QSettings()
settings = QSettings()
if settings.contains("/SextanteQGIS/LastOutputPath"):
path = str(settings.value( "/SextanteQGIS/LastOutputPath", QtCore.QVariant( "" ) ).toString())
path = str(settings.value( "/SextanteQGIS/LastOutputPath", QVariant( "" ) ).toString())
else:
path = SextanteConfig.getSetting(SextanteConfig.OUTPUT_FOLDER)
filename = QtGui.QFileDialog.getSaveFileName(self, "Save file", QtCore.QString(path), filefilter)
if filename:
lastEncoding = settings.value("/SextanteQGIS/encoding", "System").toString()
fileDialog = QgsEncodingFileDialog(self, "Save file", QString(path), filefilter, lastEncoding)
fileDialog.setFileMode(QFileDialog.AnyFile)
fileDialog.setAcceptMode(QFileDialog.AcceptSave)
fileDialog.setConfirmOverwrite(True)
if fileDialog.exec_() == QDialog.Accepted:
filename = fileDialog.selectedFiles().first()
encoding = fileDialog.encoding()
self.output.encoding = encoding
self.text.setText(str(filename))
settings.setValue("/SextanteQGIS/LastOutputPath", os.path.dirname(str(filename)))
settings.setValue("/SextanteQGIS/encoding", encoding)

def getValue(self):
filename = str(self.text.text())
if filename.strip() == "" or filename == OutputSelectionPanel.SAVE_TO_TEMP_FILE:
return None
if filename.startswith("memory:"):
return filename
else:
if not os.path.isabs(filename):
filename = SextanteConfig.getSetting(SextanteConfig.OUTPUT_FOLDER) + os.sep + filename
Expand Down
12 changes: 12 additions & 0 deletions python/plugins/sextante/gui/ParametersPanel.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from sextante.outputs.OutputRaster import OutputRaster
from sextante.outputs.OutputTable import OutputTable
from sextante.outputs.OutputVector import OutputVector
from sextante.parameters.ParameterString import ParameterString

class ParametersPanel(QtGui.QWidget):

Expand Down Expand Up @@ -256,6 +257,17 @@ def getWidgetFromParameter(self, param):
item = ExtentSelectionPanel(self.parent, self.alg, param.default)
elif isinstance(param, ParameterCrs):
item = CrsSelectionPanel(param.default)
elif isinstance(param, ParameterString):
if param.multiline:
verticalLayout = QtGui.QVBoxLayout()
verticalLayout.setSizeConstraint(QtGui.QLayout.SetDefaultConstraint)
textEdit = QtGui.QPlainTextEdit()
textEdit.setPlainText(param.default)
verticalLayout.addWidget(textEdit)
item = textEdit
else:
item = QtGui.QLineEdit()
item.setText(str(param.default))
else:
item = QtGui.QLineEdit()
item.setText(str(param.default))
Expand Down
13 changes: 9 additions & 4 deletions python/plugins/sextante/gui/SextantePostprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from sextante.gui.RenderingStyles import RenderingStyles
from sextante.outputs.OutputHTML import OutputHTML
from PyQt4.QtGui import *
from qgis.core import *
from sextante.core.SextanteConfig import SextanteConfig
import os
class SextantePostprocessing:
Expand All @@ -19,11 +20,15 @@ def handleAlgorithmResults(alg, showResults = True):
continue
if isinstance(out, (OutputRaster, OutputVector, OutputTable)):
try:
if SextanteConfig.getSetting(SextanteConfig.USE_FILENAME_AS_LAYER_NAME):
name = os.path.basename(out.value)
if out.value.startswith("memory:"):
layer = out.memoryLayer
QgsMapLayerRegistry.instance().addMapLayer(layer)
else:
name = out.description
QGisLayers.load(out.value, name, alg.crs, RenderingStyles.getStyle(alg.commandLineName(),out.name))
if SextanteConfig.getSetting(SextanteConfig.USE_FILENAME_AS_LAYER_NAME):
name = os.path.basename(out.value)
else:
name = out.description
QGisLayers.load(out.value, name, alg.crs, RenderingStyles.getStyle(alg.commandLineName(),out.name))
except Exception, e:
QMessageBox.critical(None, "Error", str(e))
elif isinstance(out, OutputHTML):
Expand Down
9 changes: 9 additions & 0 deletions python/plugins/sextante/gui/UnthreadedAlgorithmExecutor.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,12 @@ def setPercentage(self, i):

def setInfo(self, _):
pass

def setCommand(self, _):
pass

def setDebugInfo(self, _):
pass

def setConsoleInfo(self, _):
pass
15 changes: 14 additions & 1 deletion python/plugins/sextante/modeler/ModelerAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from sextante.parameters.ParameterTableField import ParameterTableField
from sextante.gui.Help2Html import Help2Html
import codecs
import time

class ModelerAlgorithm(GeoAlgorithm):

Expand Down Expand Up @@ -370,18 +371,30 @@ def processAlgorithm(self, progress):
if canExecute:
try:
alg = alg.getCopy()
progress.setDebugInfo("Prepare algorithm %i: %s" % (iAlg, alg.name))
self.prepareAlgorithm(alg, iAlg)
progress.setText("Running " + alg.name + " [" + str(iAlg+1) + "/"
+ str(len(self.algs) - len(self.deactivated)) +"]")
outputs = {}
progress.setDebugInfo("Parameters: " +
', '.join([str(p).strip() + "=" + str(p.value) for p in alg.parameters]))
t0 = time.time()
alg.execute(progress)
dt = time.time() - t0
for out in alg.outputs:
outputs[out.name] = out.value
progress.setDebugInfo("Outputs: " +
', '.join([str(out).strip() + "=" + str(outputs[out.name]) for out in alg.outputs]))
self.producedOutputs[iAlg] = outputs
executed.append(iAlg)
progress.setDebugInfo("OK. Execution took %0.3f ms (%i outputs)." % (dt, len(outputs)))
except GeoAlgorithmExecutionException, e :
progress.setDebugInfo("Failed")
raise GeoAlgorithmExecutionException("Error executing algorithm " + str(iAlg) + "\n" + e.msg)
else:
progress.setDebugInfo("Algorithm %s deactivated (or already executed)" % alg.name)
iAlg += 1
progress.setDebugInfo("Model processed ok. Executed %i algorithms total" % iAlg)

def getOutputType(self, i, outname):
for out in self.algs[i].outputs:
Expand Down Expand Up @@ -509,4 +522,4 @@ def name(self):
return self.paramName

def __str__(self):
return str(self.alg) + "|" + str(self.param)
return str(self.alg) + "|" + str(self.param)
6 changes: 4 additions & 2 deletions python/plugins/sextante/otb/OTBAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ def processAlgorithm(self, progress):
"-sizex", str(sizeX),
"-sizey", str(sizeY)]
SextanteLog.addToLog(SextanteLog.LOG_INFO, helperCommands)
progress.setCommand(helperCommands)
OTBUtils.executeOtb(helperCommands, progress)

if self.roiRasters:
Expand All @@ -154,13 +155,14 @@ def processAlgorithm(self, progress):
"-io.out", roiFile,
"-elev.dem.path", OTBUtils.otbSRTMPath()]
SextanteLog.addToLog(SextanteLog.LOG_INFO, helperCommands)
progress.setCommand(helperCommands)
OTBUtils.executeOtb(helperCommands, progress)

loglines = []
loglines.append("OTB execution command")
for line in commands:
loglines.append(line)

SextanteLog.addToLog(SextanteLog.LOG_INFO, loglines)
progress.setCommand(loglines)
OTBUtils.executeOtb(commands, progress)


1 change: 1 addition & 0 deletions python/plugins/sextante/otb/OTBUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def executeOtb(commands, progress):
progress.setPercentage(perc)
else:
loglines.append(line)
progress.setConsoleInfo(line)
SextanteLog.addToLog(SextanteLog.LOG_INFO, loglines)


Expand Down
34 changes: 33 additions & 1 deletion python/plugins/sextante/outputs/OutputVector.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,44 @@
from PyQt4.QtCore import *

from sextante.outputs.Output import Output
from sextante.core.SextanteVectorWriter import SextanteVectorWriter

class OutputVector(Output):

encoding = None

def getFileFilter(self,alg):
exts = alg.provider.getSupportedOutputVectorLayerExtensions()
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]
return alg.provider.getSupportedOutputVectorLayerExtensions()[0]

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
values instead of creating your own method.
Executing this method might modify the object, adding additional
information to it, so the writer can be later accessed and processed
within QGIS. It should be called just once, since a new call might
result in previous data being replaced, thus rendering a previously
obtained writer useless
@param fields a dict of int-QgsField
@param geomType a suitable geometry type, as it would be passed
to a QgsVectorFileWriter constructor
@param crs the crs of the layer to create
@return writer instance of the vectoe writer class
'''

if self.encoding is None:
settings = QSettings()
self.encoding = settings.value("/SextanteQGIS/encoding", "System").toString()

w = SextanteVectorWriter(self.value, self.encoding, fields, geomType, crs, options)
self.memoryLayer = w.memLayer
return w
3 changes: 2 additions & 1 deletion python/plugins/sextante/parameters/ParameterString.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

class ParameterString(Parameter):

def __init__(self, name="", description="", default=""):
def __init__(self, name="", description="", default="", multiline = False):
Parameter.__init__(self, name, description)
self.default = default
self.value = None
self.multiline = multiline

def setValue(self, obj):
if obj is None:
Expand Down
11 changes: 10 additions & 1 deletion python/plugins/sextante/r/RAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,10 @@ def processAlgorithm(self, progress):
loglines = []
loglines.append("R execution commands")
loglines += self.getFullSetOfRCommands()
for line in loglines:
progress.setCommand(line)
SextanteLog.addToLog(SextanteLog.LOG_INFO, loglines)
RUtils.executeRAlgorithm(self)
RUtils.executeRAlgorithm(self, progress)
if self.showPlots:
htmlfilename = self.getOutputValue(RAlgorithm.RPLOTS)
f = open(htmlfilename, "w")
Expand Down Expand Up @@ -225,6 +227,13 @@ def getExportCommands(self):

def getImportCommands(self):
commands = []
# if rgdal is not available, try to install it
# just use US mirror
commands.append('options("repos"="http://cran.us.r-project.org")')
rLibDir = "%s/rlibs" % SextanteUtils.userFolder()
if not os.path.isdir(rLibDir): os.mkdir(rLibDir)
commands.append(
'tryCatch(find.package("rgdal"), error=function(e) install.packages("rgdal", lib="%s"))' % rLibDir)
commands.append("library(\"rgdal\")");
for param in self.parameters:
if isinstance(param, ParameterRaster):
Expand Down
4 changes: 3 additions & 1 deletion python/plugins/sextante/r/RUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def getConsoleOutputFilename():


@staticmethod
def executeRAlgorithm(alg):
def executeRAlgorithm(alg, progress):
RUtils.verboseCommands = alg.getVerboseCommands();
RUtils.createRScriptFromRCommands(alg.getFullSetOfRCommands())
if SextanteUtils.isWindows():
Expand All @@ -64,6 +64,8 @@ def executeRAlgorithm(alg):
loglines = []
loglines.append("R execution console output")
loglines += RUtils.allConsoleResults
for line in loglines:
progress.setConsoleInfo(line)
SextanteLog.addToLog(SextanteLog.LOG_INFO, loglines)

@staticmethod
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/sextante/saga/SagaAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ def processAlgorithm(self, progress):
loglines = []
loglines.append("SAGA execution commands")
for line in commands:
progress.setInfo(line)
progress.setCommand(line)
loglines.append(line)
if SextanteConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS):
SextanteLog.addToLog(SextanteLog.LOG_INFO, loglines)
Expand Down
1 change: 1 addition & 0 deletions python/plugins/sextante/saga/SagaUtils.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def executeSaga(progress):
line = line.strip()
if line!="/" and line!="-" and line !="\\" and line!="|":
loglines.append(line)
progress.setConsoleInfo(line)
if SextanteConfig.getSetting(SagaUtils.SAGA_LOG_CONSOLE):
SextanteLog.addToLog(SextanteLog.LOG_INFO, loglines)

Expand Down
2 changes: 1 addition & 1 deletion python/plugins/sextante/tests/runtests.sh
Original file line number Diff line number Diff line change
@@ -1 +1 @@
QGISPATH=/usr/local PYTHONPATH=~/Proyectos/qgis/output/python/:~/Proyectos/qgis/python/plugins/ python test.py $@
QGISPATH=/usr/local PYTHONPATH=~/Proyectos/qgis/python/plugins/:~/Proyectos/qgis/output/python/ python test.py $@
214 changes: 214 additions & 0 deletions src/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


49 changes: 49 additions & 0 deletions src/sextante/core/SextanteVectorWriter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from PyQt4.QtCore import *

from qgis.core import *

class SextanteVectorWriter:

MEMORY_LAYER_PREFIX = "memory:"

TYPE_MAP = {QGis.WKBPoint : "Point",
QGis.WKBLineString : "LineString",
QGis.WKBPolygon : "Polygon",
QGis.WKBMultiPoint : "MultiPoint",
QGis.WKBMultiLineString : "MultiLineString",
QGis.WKBMultiPolygon : "MultiPolygon"
}

def __init__(self, fileName, encoding, fields, geometryType, crs, options=None):
self.fileName = fileName
self.isMemory = False
self.memLayer = None
self.writer = None

if self.fileName.startswith(self.MEMORY_LAYER_PREFIX):
self.isMemory = True

uri = self.TYPE_MAP[geometryType]
if crs.isValid():
uri += "?crs=" + crs.authid()
self.memLayer = QgsVectorLayer(uri, self.fileName, "memory")
self.writer = self.memLayer.dataProvider()
self.writer.addAttributes(fields.values())
self.memLayer.updateFieldMap()
else:
formats = QgsVectorFileWriter.supportedFiltersAndFormats()
OGRCodes = {}
for key, value in formats.items():
extension = str(key)
extension = extension[extension.find('*.') + 2:]
extension = extension[:extension.find(" ")]
OGRCodes[extension] = value

extension = self.fileName[self.fileName.find(".") + 1:]
self.writer = QgsVectorFileWriter(self.fileName, encoding, fields, geometryType, crs, OGRCodes[extension])

def addFeature(self, feature):
if self.isMemory:
self.writer.addFeatures([feature])
else:
self.writer.addFeature(feature)