def highlight_features(self): for item in self.highlight: self.canvas.scene().removeItem(item) del self.highlight[:] del self.highlight_rows[:] index = self.tabWidget.currentIndex() tab = self.tabWidget.widget(index) if self.tabWidget.count() != 0: table = self.tabWidget.widget(index).findChildren(QTableWidget)[0] nb = 0 area = 0 length = 0 items = table.selectedItems() for item in items: if item.row() not in self.highlight_rows: if self.selectGeom: highlight = QgsHighlight(self.canvas, item.feature.geometry(), self.tabWidget.widget(index).layer) else: highlight = QgsHighlight(self.canvas, item.feature.geometry().centroid(), self.tabWidget.widget(index).layer) highlight.setColor(QColor(255,0,0)) self.highlight.append(highlight) self.highlight_rows.append(item.row()) g = QgsGeometry(item.feature.geometry()) g.transform(QgsCoordinateTransform(tab.layer.crs(), QgsCoordinateReferenceSystem(2154), QgsProject.instance())) # geometry reprojection to get meters nb += 1 area += g.area() length += g.length() if tab.layer.geometryType()==QgsWkbTypes.PolygonGeometry: tab.sb.showMessage(self.tr('Selected features')+': '+str(nb)+' '+self.tr('Area')+': '+"%.2f"%area+' m'+u'²') elif tab.layer.geometryType()==QgsWkbTypes.LineGeometry: tab.sb.showMessage(self.tr('Selected features')+': '+str(nb)+' '+self.tr('Length')+': '+"%.2f"%length+' m') else: tab.sb.showMessage(self.tr('Selected features')+': '+str(nb))
def __calcMapCurvesGeom(self, g: QgsGeometry, g2: QgsGeometry): """Calculating MapCurve using geometry. :param g QgsGeometry: First geometry for calculation :param g2 QgsGeometry: Second geometry for calculation """ if (not g.isGeosValid()): # print("not valid geom") g = QgsGeometry(g.makeValid()) if (not g2.isGeosValid()): # print("not valid geom2") g2 = QgsGeometry(g2.makeValid()) inter = g.intersection(g2) # print("intersection created") if (inter.isEmpty()): # print("empty geom") return 0 else: # print("calculating score") score = (inter.area() / g.area()) * (inter.area() / g2.area()) # print("score calculated") return round(score, 4)
def processAlgorithm(self, parameters, context, feedback): feedback.setProgressText('Associando...') layers = self.parameterAsLayerList(parameters, 'INPUT_LAYERS', context) input_frame = self.parameterAsVectorLayer(parameters, 'INPUT_FRAME', context) input_frame_features = self.createFeaturesArray(input_frame) listSize = len(input_frame_features) progressStep = 100 / listSize if listSize else 0 step = 0 setCRS = input_frame.crs() frame_layer_pairs = [] for step, feat in enumerate(input_frame_features): inter_over_poly_list = [] inter_over_image_list = [] for j, pct_layer in enumerate(layers): if feedback.isCanceled(): return {self.OUTPUT: 'cancelado'} rect = QgsGeometry().fromRect(pct_layer.extent()) intersec = feat.geometry().intersection(rect) inter_area = intersec.area() feat_area = feat.geometry().area() image_area = rect.area() inter_over_poly = inter_area / feat_area inter_over_poly_list.append(inter_over_poly) inter_over_image = inter_area / image_area inter_over_image_list.append(inter_over_image) image_index = self.selectImageIndex(inter_over_poly_list, inter_over_image_list) frame_layer_pairs.append( [feat.geometry(), layers[image_index].name()]) feedback.setProgress(step * progressStep) newLayer = self.outLayer(parameters, context, frame_layer_pairs, setCRS) return {self.OUTPUT: newLayer}
def area_crs(crs_id, feature, parent, context): """ <h4>Return</h4>Area using the CRS ID <p><h4>Syntax</h4>area_crs(CRS ID)</p> <p><h4>Argument</h4>CRS ID</p> <p><h4>Example</h4>area_crs('EPSG:5671')</p> """ geom = QgsGeometry(feature.geometry()) if not isinstance(crs_id, str): raise Exception("Enter with ID CRS with string type(Ex.: 'EPSG:4326')") crsDest = QgsCoordinateReferenceSystem(crs_id) if not crsDest.isValid(): msg = "ID EPSG '{}' is not valid".format(crs_id) raise Exception(msg) if crsDest.isGeographic(): msg = "ID CRS '{}' is Geographic".format(crs_id) raise Exception(msg) layer_id = context.variable('layer_id') crsLayer = getCRSLayer(layer_id) if not crsDest == crsLayer: ct = QgsCoordinateTransform(crsLayer, crsDest, QgsCoordinateTransformContext()) geom.transform(ct) return geom.area()
class Bend: """Define a Bend object which is the reduction goal of this algorithm""" @staticmethod def calculate_min_adj_area(diameter_tol): """Static method to calculate the adjusted area of the maximum diameter tolerance. :param: diameter_tol: float diameter tolerance to used for bend reduction :return: Minimum adjusted area of a polygon to reduce :rtype: Real """ min_adj_area = .75 * math.pi * (diameter_tol / 2.)**2 return min_adj_area @staticmethod def calculate_adj_area(area, perimeter): """Static method to calculate the adjusted area. The adjusted area is used to determine if a bend must be reduce. :param: real area: area of a polygon. :param: real perimeter: perimeter of a polygon. :return: Adjusted area of a polygon :rtype: Real """ try: compactness_index = 4 * area * math.pi / perimeter**2 adj_area = area * (.75 / compactness_index) except ZeroDivisionError: # Catch division by zero adj_area = Epsilon.ZERO_RELATIVE return adj_area __slots__ = ('i', 'j', 'area', 'perimeter', 'adj_area', 'to_reduce', '_qgs_geom_new_subline', '_qgs_geom_old_subline', '_qgs_points', 'qgs_geom_bend') def __init__(self, i, j, qgs_points): """Constructor that initialize a Bend object. :param: int i: start position of the vertice in the LineString to reduce :param: int j: end position of the vertice in the LineString to reduce :param: qgs_points: List of QgsPoint defining the bend :return: None :rtype: None """ self.i = i self.j = j self._qgs_points = qgs_points self._qgs_geom_new_subline = None self._qgs_geom_old_subline = None self.qgs_geom_bend = QgsGeometry(QgsPolygon( QgsLineString(qgs_points))) # QgsPolygon will close the polygon self.area = self.qgs_geom_bend.area() self.perimeter = self.qgs_geom_bend.length() self.adj_area = Bend.calculate_adj_area(self.area, self.perimeter) self.to_reduce = False @property def qgs_geom_new_subline(self): """Late attribute evaluation as this attribute is costly to evaluate""" if self._qgs_geom_new_subline is None: self._qgs_geom_new_subline = QgsGeometry( QgsLineString(self._qgs_points[0], self._qgs_points[-1])) return self._qgs_geom_new_subline @property def qgs_geom_old_subline(self): """Late attribute evaluation as this attribute is costly to evaluate""" if self._qgs_geom_old_subline is None: self._qgs_geom_old_subline = QgsGeometry( QgsLineString(self._qgs_points)) return self._qgs_geom_old_subline
def run(self): #CARREGA A LISTA DOS NOMES DOS LAYER DA TOC layers = self.iface.legendInterface().layers() layer_list = [] i = 0 iObra = 0 iLote = 0 for layer in layers: nomeLayer = layer.name() layer_list.append(nomeLayer) if 'obra' in str(nomeLayer).lower(): iObra = i if 'lote' in str(nomeLayer).lower(): iLote = i i = i + 1 #SELECIONAR O SHP DA OBRA self.dlg.comboBox_obra.clear() self.dlg.comboBox_obra.addItems(layer_list) #SELECIONAR O SHP DOS LOTES self.dlg.comboBox_lote.clear() self.dlg.comboBox_lote.addItems(layer_list) #SELECIONAR OBRA E LOTE AUTOMATICAMENTE self.dlg.comboBox_obra.setCurrentIndex(iObra) self.dlg.comboBox_lote.setCurrentIndex(iLote) """Run method that performs all the real work""" # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. # pass selectedLayerIndex = self.dlg.comboBox_obra.currentIndex() selectedLayerObra = layers[selectedLayerIndex] selectedLayerIndex = self.dlg.comboBox_lote.currentIndex() selectedLayerLote = layers[selectedLayerIndex] #LISTA DOS CAMPOS OBTIDA PELO dataProvider lotes = selectedLayerLote.dataProvider() #CRIACAO DE NOVO CAMPOS EM LOTES field_dista1_index = lotes.fields().indexFromName("area") if field_dista1_index == -1: #CRIAR O CAMPO AREA, POIS ELE NAO EXISTE lotes.addAttributes( [QgsField("area", QVariant.Double, 'double', 20, 2)]) selectedLayerLote.updateFields() field_dista1_index = lotes.fields().indexFromName("distobra") if field_dista1_index == -1: #CRIAR O CAMPO DISTOBRA, POIS ELE NAO EXISTE lotes.addAttributes( [QgsField("distobra", QVariant.Double, 'double', 20, 2)]) selectedLayerLote.updateFields() field_valor_index = lotes.fields().indexFromName("valor") if field_valor_index == -1: #CRIAR O CAMPO VALOR, POIS ELE NAO EXISTE lotes.addAttributes( [QgsField("valor", QVariant.Double, 'double', 20, 2)]) selectedLayerLote.updateFields() field_valtot_index = lotes.fields().indexFromName("valtot") if field_valtot_index == -1: #CRIAR O CAMPO VALTOT, POIS ELE NAO EXISTE lotes.addAttributes( [QgsField("valtot", QVariant.Double, 'double', 20, 2)]) selectedLayerLote.updateFields() #DETECTA OS IDs DOS NOVOS CAMPOS CRIADOS id_field_area = lotes.fields().indexFromName('area') id_field_distObra = lotes.fields().indexFromName('distobra') id_field_valor = lotes.fields().indexFromName('valor') id_field_valtot = lotes.fields().indexFromName('valtot') #PARAMETRO PARA O CALCULO DE VALOR1 if self.dlg.radioButton_pav.isChecked(): #radioButton_pavimentacao_via localmin1 = 0.00 localmax1 = 100.00 valor1 = 10.00 localmin2 = 100.00 localmax2 = 200.00 valor2 = 5.00 localmin3 = 200.00 localmax3 = 300.00 valor3 = 2.50 #LE AS COORDENADA DA OBRA for fObra in selectedLayerObra.getFeatures(): geomObra = fObra.geometry() #INICIO DA EDICAO DOS DADOS selectedLayerLote.startEditing() #LE AS COORDENADA DOS LOTES val_tot_geral = 0.00 val_tot_area = 0.00 tot_lotes = 0 for fLote in selectedLayerLote.getFeatures(): id = fLote.id() geomLote = fLote.geometry() #CALCULO DA DISTANCIA ENTRE POLIGONOS E AREA DO LOTE distobra = QgsGeometry.distance(geomLote, geomObra) val_area = QgsGeometry.area(geomLote) valor = 0.0 if localmin1 <= distobra < localmax1: valor = valor1 elif localmin2 <= distobra < localmax2: valor = valor2 elif localmin3 <= distobra < localmax3: valor = valor3 #TOTALIZA VALOR POR LOTE val_tot_lot = val_area * valor #TOTALIZA POR LOTE AFETADO if valor > 0: val_tot_area = val_tot_area + val_area val_tot_geral = val_tot_geral + val_tot_lot tot_lotes = tot_lotes + 1 #GRAVA OS VALORES NA CAMADA DE LOTES selectedLayerLote.changeAttributeValue(id, id_field_area, geomLote.area()) selectedLayerLote.changeAttributeValue(id, id_field_distObra, distobra) selectedLayerLote.changeAttributeValue(id, id_field_valor, valor) selectedLayerLote.changeAttributeValue(id, id_field_valtot, val_tot_lot) #COMITA AS MUDANCAS selectedLayerLote.commitChanges() iface.messageBar().pushMessage("BID - VALORIZA SOLO URBANO", "Calculo realizado com sucesso!", level=QgsMessageBar.INFO, duration=5) #ABRE A TABELA DE ATRIBUTOS DOS LOTES iface.showAttributeTable(selectedLayerLote) #FORMATA A MENSAGEM tot_tributo_geral = val_tot_geral * 0.02 tot_valor = round(val_tot_geral, 2) tot_area = round(val_tot_area, 2) tot_tributo = round(tot_tributo_geral, 2) tot_valor_formatado = '{0:,}'.format(tot_valor).replace(',', '.') tot_tributo_formatado = '{0:,}'.format(tot_tributo).replace( ',', '.') tot_area_formatado = '{0:,}'.format(tot_area).replace(',', '.') tot_lotes_formatado = '{0:,}'.format(tot_lotes).replace(',', '.') txt1 = '%s' % ("VALORIZA SOLO URBANO\n\n\n") txt2 = 'Total Lotes......................= %s\n\n' % ( tot_lotes_formatado) txt3 = 'Total Area (m2)..............= %s\n\n' % ( tot_area_formatado) txt4 = 'Total Incremento ($).....= %s\n\n' % (tot_valor_formatado) txt5 = 'Total Aliquota a 2 ($).....= %s\n' % ( tot_tributo_formatado) txt6 = '%s%s%s%s%s' % (txt1, txt2, txt3, txt4, txt5) import ctypes MessageBox = ctypes.windll.user32.MessageBoxA MessageBox(None, txt6, ' B I D / A B R A S F', 0)
def processAlgorithm(self, progress): inLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY smallestArea = self.getParameterValue( self.MODE) == self.MODE_SMALLEST_AREA keepSelection = self.getParameterValue(self.KEEPSELECTION) processLayer = vector.duplicateInMemory(inLayer) if not keepSelection: # Make a selection with the values provided attribute = self.getParameterValue(self.ATTRIBUTE) comparison = self.comparisons[self.getParameterValue( self.COMPARISON)] comparisonvalue = self.getParameterValue(self.COMPARISONVALUE) selectindex = vector.resolveFieldIndex(processLayer, attribute) selectType = processLayer.fields()[selectindex].type() selectionError = False if selectType == 2: try: y = int(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to integer' % unicode(comparisonvalue)) elif selectType == 6: try: y = float(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to float' % unicode(comparisonvalue)) elif selectType == 10: # 10: string, boolean try: y = unicode(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to unicode' % unicode(comparisonvalue)) elif selectType == 14: # date dateAndFormat = comparisonvalue.split(' ') if len(dateAndFormat) == 1: # QDate object y = QLocale.system().toDate(dateAndFormat[0]) if y.isNull(): msg = self.tr( 'Cannot convert "%s" to date with system date format %s' % (unicode(dateAndFormat), QLocale.system().dateFormat())) elif len(dateAndFormat) == 2: y = QDate.fromString(dateAndFormat[0], dateAndFormat[1]) if y.isNull(): msg = self.tr( 'Cannot convert "%s" to date with format string "%s"' % (unicode(dateAndFormat[0]), dateAndFormat[1])) else: y = QDate() msg = '' if y.isNull(): # Conversion was unsuccessfull selectionError = True msg += self.tr( 'Enter the date and the date format, e.g. "07.26.2011" "MM.dd.yyyy".' ) if (comparison == 'begins with' or comparison == 'contains') \ and selectType != 10: selectionError = True msg = self.tr('"%s" can only be used with string fields' % comparison) selected = [] if selectionError: raise GeoAlgorithmExecutionException( self.tr('Error in selection input: %s' % msg)) else: for feature in processLayer.getFeatures(): aValue = feature.attributes()[selectindex] if aValue is None: continue if selectType == 2: x = int(aValue) elif selectType == 6: x = float(aValue) elif selectType == 10: # 10: string, boolean x = unicode(aValue) elif selectType == 14: # date x = aValue # should be date match = False if comparison == '==': match = x == y elif comparison == '!=': match = x != y elif comparison == '>': match = x > y elif comparison == '>=': match = x >= y elif comparison == '<': match = x < y elif comparison == '<=': match = x <= y elif comparison == 'begins with': match = x.startswith(y) elif comparison == 'contains': match = x.find(y) >= 0 if match: selected.append(feature.id()) processLayer.setSelectedFeatures(selected) if processLayer.selectedFeatureCount() == 0: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr('%s: (No selection in input layer "%s")' % (self.commandLineName(), self.getParameterValue(self.INPUT)))) # Keep references to the features to eliminate featToEliminate = [] for aFeat in processLayer.selectedFeatures(): featToEliminate.append(aFeat) # Delete all features to eliminate in processLayer (we won't save this) processLayer.startEditing() processLayer.deleteSelectedFeatures() # ANALYZE if len(featToEliminate) > 0: # Prevent zero division start = 20.00 add = 80.00 / len(featToEliminate) else: start = 100 progress.setPercentage(start) madeProgress = True # We go through the list and see if we find any polygons we can # merge the selected with. If we have no success with some we # merge and then restart the whole story. while madeProgress: # Check if we made any progress madeProgress = False featNotEliminated = [] # Iterate over the polygons to eliminate for i in range(len(featToEliminate)): feat = featToEliminate.pop() geom2Eliminate = QgsGeometry(feat.geometry()) bbox = geom2Eliminate.boundingBox() fit = processLayer.getFeatures( QgsFeatureRequest().setFilterRect(bbox)) mergeWithFid = None mergeWithGeom = None max = 0 min = -1 selFeat = QgsFeature() while fit.nextFeature(selFeat): selGeom = QgsGeometry(selFeat.geometry()) if geom2Eliminate.intersects(selGeom): # We have a candidate iGeom = geom2Eliminate.intersection(selGeom) if iGeom is None: continue if boundary: selValue = iGeom.length() else: # area. We need a common boundary in # order to merge if 0 < iGeom.length(): selValue = selGeom.area() else: selValue = -1 if -1 != selValue: useThis = True if smallestArea: if -1 == min: min = selValue else: if selValue < min: min = selValue else: useThis = False else: if selValue > max: max = selValue else: useThis = False if useThis: mergeWithFid = selFeat.id() mergeWithGeom = QgsGeometry(selGeom) # End while fit if mergeWithFid is not None: # A successful candidate newGeom = mergeWithGeom.combine(geom2Eliminate) if processLayer.changeGeometry(mergeWithFid, newGeom): madeProgress = True else: raise GeoAlgorithmExecutionException( self. tr('Could not replace geometry of feature with id %s' % mergeWithFid)) start = start + add progress.setPercentage(start) else: featNotEliminated.append(feat) # End for featToEliminate featToEliminate = featNotEliminated # End while # Create output provider = processLayer.dataProvider() output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(provider.fields(), provider.geometryType(), processLayer.crs()) # Write all features that are left over to output layer iterator = processLayer.getFeatures() for feature in iterator: writer.addFeature(feature) # Leave processLayer untouched processLayer.rollBack() for feature in featNotEliminated: writer.addFeature(feature)
def processAlgorithm(self, progress): inLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY smallestArea = self.getParameterValue(self.MODE) == self.MODE_SMALLEST_AREA keepSelection = self.getParameterValue(self.KEEPSELECTION) processLayer = vector.duplicateInMemory(inLayer) if not keepSelection: # Make a selection with the values provided attribute = self.getParameterValue(self.ATTRIBUTE) comparison = self.comparisons[self.getParameterValue(self.COMPARISON)] comparisonvalue = self.getParameterValue(self.COMPARISONVALUE) selectindex = vector.resolveFieldIndex(processLayer, attribute) selectType = processLayer.fields()[selectindex].type() selectionError = False if selectType == 2: try: y = int(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to integer' % unicode(comparisonvalue)) elif selectType == 6: try: y = float(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to float' % unicode(comparisonvalue)) elif selectType == 10: # 10: string, boolean try: y = unicode(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to unicode' % unicode(comparisonvalue)) elif selectType == 14: # date dateAndFormat = comparisonvalue.split(' ') if len(dateAndFormat) == 1: # QDate object y = QLocale.system().toDate(dateAndFormat[0]) if y.isNull(): msg = self.tr('Cannot convert "%s" to date with system date format %s' % (unicode(dateAndFormat), QLocale.system().dateFormat())) elif len(dateAndFormat) == 2: y = QDate.fromString(dateAndFormat[0], dateAndFormat[1]) if y.isNull(): msg = self.tr('Cannot convert "%s" to date with format string "%s"' % (unicode(dateAndFormat[0]), dateAndFormat[1])) else: y = QDate() msg = '' if y.isNull(): # Conversion was unsuccessfull selectionError = True msg += self.tr('Enter the date and the date format, e.g. "07.26.2011" "MM.dd.yyyy".') if (comparison == 'begins with' or comparison == 'contains') \ and selectType != 10: selectionError = True msg = self.tr('"%s" can only be used with string fields' % comparison) selected = [] if selectionError: raise GeoAlgorithmExecutionException( self.tr('Error in selection input: %s' % msg)) else: for feature in processLayer.getFeatures(): aValue = feature.attributes()[selectindex] if aValue is None: continue if selectType == 2: x = int(aValue) elif selectType == 6: x = float(aValue) elif selectType == 10: # 10: string, boolean x = unicode(aValue) elif selectType == 14: # date x = aValue # should be date match = False if comparison == '==': match = x == y elif comparison == '!=': match = x != y elif comparison == '>': match = x > y elif comparison == '>=': match = x >= y elif comparison == '<': match = x < y elif comparison == '<=': match = x <= y elif comparison == 'begins with': match = x.startswith(y) elif comparison == 'contains': match = x.find(y) >= 0 if match: selected.append(feature.id()) processLayer.setSelectedFeatures(selected) if processLayer.selectedFeatureCount() == 0: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, self.tr('%s: (No selection in input layer "%s")' % (self.commandLineName(), self.getParameterValue(self.INPUT)))) # Keep references to the features to eliminate featToEliminate = [] for aFeat in processLayer.selectedFeatures(): featToEliminate.append(aFeat) # Delete all features to eliminate in processLayer (we won't save this) processLayer.startEditing() processLayer.deleteSelectedFeatures() # ANALYZE if len(featToEliminate) > 0: # Prevent zero division start = 20.00 add = 80.00 / len(featToEliminate) else: start = 100 progress.setPercentage(start) madeProgress = True # We go through the list and see if we find any polygons we can # merge the selected with. If we have no success with some we # merge and then restart the whole story. while madeProgress: # Check if we made any progress madeProgress = False featNotEliminated = [] # Iterate over the polygons to eliminate for i in range(len(featToEliminate)): feat = featToEliminate.pop() geom2Eliminate = QgsGeometry(feat.geometry()) bbox = geom2Eliminate.boundingBox() fit = processLayer.getFeatures( QgsFeatureRequest().setFilterRect(bbox)) mergeWithFid = None mergeWithGeom = None max = 0 min = -1 selFeat = QgsFeature() while fit.nextFeature(selFeat): selGeom = QgsGeometry(selFeat.geometry()) if geom2Eliminate.intersects(selGeom): # We have a candidate iGeom = geom2Eliminate.intersection(selGeom) if iGeom is None: continue if boundary: selValue = iGeom.length() else: # area. We need a common boundary in # order to merge if 0 < iGeom.length(): selValue = selGeom.area() else: selValue = -1 if -1 != selValue: useThis = True if smallestArea: if -1 == min: min = selValue else: if selValue < min: min = selValue else: useThis = False else: if selValue > max: max = selValue else: useThis = False if useThis: mergeWithFid = selFeat.id() mergeWithGeom = QgsGeometry(selGeom) # End while fit if mergeWithFid is not None: # A successful candidate newGeom = mergeWithGeom.combine(geom2Eliminate) if processLayer.changeGeometry(mergeWithFid, newGeom): madeProgress = True else: raise GeoAlgorithmExecutionException( self.tr('Could not replace geometry of feature with id %s' % mergeWithFid)) start = start + add progress.setPercentage(start) else: featNotEliminated.append(feat) # End for featToEliminate featToEliminate = featNotEliminated # End while # Create output provider = processLayer.dataProvider() output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(provider.fields(), provider.geometryType(), processLayer.crs()) # Write all features that are left over to output layer iterator = processLayer.getFeatures() for feature in iterator: writer.addFeature(feature) # Leave processLayer untouched processLayer.rollBack() for feature in featNotEliminated: writer.addFeature(feature)