def get_boundingpolygon(self): """ TODO: Implement ncell bbox order of lines creation (assumes 0,0 is x) -----3----- | | 4 2 | | x----1----- """ if self._ndim == 2: # CGRID nx,ny = self._xarray.shape one = MultiLineString([((self._xarray[i][0],self._yarray[i][0]),(self._xarray[i+1][0],self._yarray[i+1][0])) for i in range(nx-1)]) two = MultiLineString([((self._xarray[nx-1][j],self._yarray[nx-1][j]),(self._xarray[nx-1][j+1],self._yarray[nx-1][j+1])) for j in range(ny-1)]) three = MultiLineString([((self._xarray[i][ny-1],self._yarray[i][ny-1]),(self._xarray[i-1][ny-1],self._yarray[i-1][ny-1])) for i in reversed(list(range(1,nx)))]) four = MultiLineString([((self._xarray[0][j],self._yarray[0][j]),(self._xarray[0][j-1],self._yarray[0][j-1])) for j in reversed(list(range(1,ny)))]) m = one.union(two).union(three).union(four) else: # RGRID nx,ny = self._xarray.shape[0], self._yarray.shape[0] one = LineString([(self._xarray[i], self._yarray[0]) for i in range(nx)]) two = LineString([(self._xarray[-1], self._yarray[i]) for i in range(ny)]) three = LineString([(self._xarray[i], self._yarray[-1]) for i in reversed(list(range(nx)))]) four = LineString([(self._xarray[0], self._yarray[i]) for i in reversed(list(range(ny)))]) m = MultiLineString([one,two,three,four]) polygons = list(polygonize(m)) # -- polygonize returns a list of polygons, including interior features, the largest in area "should" be the full feature assert len(polygons) > 0, "Could not determine a polygon" polygon = sorted(polygons, key=lambda x: x.area)[-1] return polygon
def processAlgorithm(self, progress): try: from shapely.ops import polygonize from shapely.geometry import Point, MultiLineString except ImportError: raise GeoAlgorithmExecutionException( 'Polygonize algorithm requires shapely module!') vlayer = QGisLayers.getObjectFromUri(self.getParameterValue( self.INPUT)) output = self.getOutputFromName(self.OUTPUT) vprovider = vlayer.dataProvider() if self.getParameterValue(self.FIELDS): fields = vprovider.fields() else: fields = QgsFields() if self.getParameterValue(self.GEOMETRY): fieldsCount = fields.count() fields.append(QgsField("area", QVariant.Double, "double", 16, 2)) fields.append( QgsField("perimeter", QVariant.Double, "double", 16, 2)) allLinesList = [] features = QGisLayers.features(vlayer) current = 0 total = 40.0 / float(len(features)) for inFeat in features: inGeom = inFeat.geometry() if inGeom.isMultipart(): allLinesList.extend(inGeom.asMultiPolyline()) else: allLinesList.append(inGeom.asPolyline()) current += 1 progress.setPercentage(int(current * total)) progress.setPercentage(40) allLines = MultiLineString(allLinesList) allLines = allLines.union(Point(0, 0)) progress.setPercentage(45) polygons = list(polygonize([allLines])) progress.setPercentage(50) writer = output.getVectorWriter(fields, QGis.WKBPolygon, vlayer.crs()) outFeat = QgsFeature() current = 0 total = 50.0 / float(len(polygons)) for polygon in polygons: outFeat.setGeometry(QgsGeometry.fromWkt(polygon.wkt)) if self.getParameterValue(self.GEOMETRY): outFeat.setAttributes( [None] * fieldsCount + [QVariant(polygon.area), QVariant(polygon.length)]) writer.addFeature(outFeat) current += 1 progress.setPercentage(50 + int(current * total)) del writer
def processAlgorithm(self, progress): try: from shapely.ops import polygonize from shapely.geometry import Point, MultiLineString except ImportError: raise GeoAlgorithmExecutionException( 'Polygonize algorithm requires shapely module!') vlayer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) output = self.getOutputFromName(self.OUTPUT) vprovider = vlayer.dataProvider() if self.getParameterValue(self.FIELDS): fields = vprovider.fields() else: fields = QgsFields() if self.getParameterValue(self.GEOMETRY): fieldsCount = fields.count() fields.append(QgsField('area', QVariant.Double, 'double', 16, 2)) fields.append(QgsField('perimeter', QVariant.Double, 'double', 16, 2)) allLinesList = [] features = vector.features(vlayer) current = 0 total = 40.0 / float(len(features)) for inFeat in features: inGeom = inFeat.geometry() if inGeom.isMultipart(): allLinesList.extend(inGeom.asMultiPolyline()) else: allLinesList.append(inGeom.asPolyline()) current += 1 progress.setPercentage(int(current * total)) progress.setPercentage(40) allLines = MultiLineString(allLinesList) allLines = allLines.union(Point(0, 0)) progress.setPercentage(45) polygons = list(polygonize([allLines])) progress.setPercentage(50) writer = output.getVectorWriter(fields, QGis.WKBPolygon, vlayer.crs()) outFeat = QgsFeature() current = 0 total = 50.0 / float(len(polygons)) for polygon in polygons: outFeat.setGeometry(QgsGeometry.fromWkt(polygon.wkt)) if self.getParameterValue(self.GEOMETRY): outFeat.setAttributes([None] * fieldsCount + [polygon.area, polygon.length]) writer.addFeature(outFeat) current += 1 progress.setPercentage(50 + int(current * total)) del writer
def check_intersections(self): checks_done = MultiLineString() for subpath, elem in self.get_line_strings(): line = subpath.as_linestring() if not line.is_simple: # TODO: find location of self-intersection and introduce some # tolerance # checks_done = checks_done.union(line) yield CheckerResult("self-intersection found", elem) # continue if checks_done.intersects(line): intersection = checks_done.intersection(line) yield CheckerResult("intersection found", elem, extra={"intersection": intersection}) checks_done = checks_done.union(line)
def union(self): '''new method using Union function''' global polyCount inFeat = QgsFeature() progress = 0. self.emit(SIGNAL('progress'), 0) self.parent.layer = getMapLayerByName(self.ui.cmbLayer.currentText()) provider = self.parent.layer.dataProvider() #user can't toggle edit mode of line layer while polygonizing, plugin automatically turn it off QObject.connect(self.parent.layer,SIGNAL("editingStarted()"), self.parent.startEditing) allAttrs = provider.attributeIndexes() provider.select(allAttrs) provider.select() step = 45. / self.parent.layer.featureCount() allLinesList = [] allLinesListExtend = allLinesList.extend allLinesListAppend = allLinesList.append while provider.nextFeature(inFeat): geom = inFeat.geometry() if geom.isMultipart(): allLinesListExtend(geom.asMultiPolyline() ) else: allLinesListAppend(geom.asPolyline()) progress += step self.emit(SIGNAL('progress'), progress) allLines = MultiLineString(allLinesList) allLines = allLines.union(Point(0,0)) polygons = list(polygonize([allLines])) polyCount = len(polygons) #if no polygons where created then exit from thread if polyCount == 0: QObject.disconnect(self.parent.polygonizeThread,SIGNAL("finished()"), self.parent.threadFinished) self.emit(SIGNAL('noPolygons')) return else: if self.ui.cbOutput.isChecked(): self.saveAsFile(polygons, progress) else: self.saveInMemory(polygons, progress)
def overlay(df1, df2, how, use_sindex=True): """Perform spatial overlay between two polygons. Currently only supports data GeoDataFrames with polygons. Implements several methods that are all effectively subsets of the union. Parameters ---------- df1 : GeoDataFrame with MultiPolygon or Polygon geometry column df2 : GeoDataFrame with MultiPolygon or Polygon geometry column how : string Method of spatial overlay: 'intersection', 'union', 'identity', 'symmetric_difference' or 'difference'. use_sindex : boolean, default True Use the spatial index to speed up operation if available. Returns ------- df : GeoDataFrame GeoDataFrame with new set of polygons and attributes resulting from the overlay """ allowed_hows = [ 'intersection', 'union', 'identity', 'symmetric_difference', 'difference', # aka erase ] if how not in allowed_hows: raise ValueError("`how` was \"%s\" but is expected to be in %s" % \ (how, allowed_hows)) if isinstance(df1, GeoSeries) or isinstance(df2, GeoSeries): raise NotImplementedError("overlay currently only implemented for GeoDataFrames") # Collect the interior and exterior rings rings1 = _extract_rings(df1) rings2 = _extract_rings(df2) mls1 = MultiLineString(rings1) mls2 = MultiLineString(rings2) # Union and polygonize try: # calculating union (try the fast unary_union) mm = unary_union([mls1, mls2]) except: # unary_union FAILED # see https://github.com/Toblerity/Shapely/issues/47#issuecomment-18506767 # calculating union again (using the slow a.union(b)) mm = mls1.union(mls2) newpolys = polygonize(mm) # determine spatial relationship collection = [] for fid, newpoly in enumerate(newpolys): cent = newpoly.representative_point() # Test intersection with original polys # FIXME there should be a higher-level abstraction to search by bounds # and fall back in the case of no index? if use_sindex and df1.sindex is not None: candidates1 = [x.object for x in df1.sindex.intersection(newpoly.bounds, objects=True)] else: candidates1 = [i for i, x in df1.iterrows()] if use_sindex and df2.sindex is not None: candidates2 = [x.object for x in df2.sindex.intersection(newpoly.bounds, objects=True)] else: candidates2 = [i for i, x in df2.iterrows()] df1_hit = False df2_hit = False prop1 = None prop2 = None for cand_id in candidates1: cand = df1.loc[cand_id] if cent.intersects(cand[df1.geometry.name]): df1_hit = True prop1 = cand break # Take the first hit for cand_id in candidates2: cand = df2.loc[cand_id] if cent.intersects(cand[df2.geometry.name]): df2_hit = True prop2 = cand break # Take the first hit # determine spatial relationship based on type of overlay hit = False if how == "intersection" and (df1_hit and df2_hit): hit = True elif how == "union" and (df1_hit or df2_hit): hit = True elif how == "identity" and df1_hit: hit = True elif how == "symmetric_difference" and not (df1_hit and df2_hit): hit = True elif how == "difference" and (df1_hit and not df2_hit): hit = True if not hit: continue # gather properties if prop1 is None: prop1 = pd.Series(dict.fromkeys(df1.columns, None)) if prop2 is None: prop2 = pd.Series(dict.fromkeys(df2.columns, None)) # Concat but don't retain the original geometries out_series = pd.concat([prop1.drop(df1._geometry_column_name), prop2.drop(df2._geometry_column_name)]) out_series.index = _uniquify(out_series.index) # Create a geoseries and add it to the collection out_series['geometry'] = newpoly collection.append(out_series) # Return geodataframe with new indicies return GeoDataFrame(collection, index=range(len(collection)))
def overlay(df1, df2, how, use_sindex=True): """Perform spatial overlay between two polygons. Currently only supports data GeoDataFrames with polygons. Implements several methods that are all effectively subsets of the union. Parameters ---------- df1 : GeoDataFrame with MultiPolygon or Polygon geometry column df2 : GeoDataFrame with MultiPolygon or Polygon geometry column how : string Method of spatial overlay: 'intersection', 'union', 'identity', 'symmetric_difference' or 'difference'. use_sindex : boolean, default True Use the spatial index to speed up operation if available. Returns ------- df : GeoDataFrame GeoDataFrame with new set of polygons and attributes resulting from the overlay """ allowed_hows = [ 'intersection', 'union', 'identity', 'symmetric_difference', 'difference', # aka erase ] if how not in allowed_hows: raise ValueError("`how` was \"%s\" but is expected to be in %s" % \ (how, allowed_hows)) if isinstance(df1, GeoSeries) or isinstance(df2, GeoSeries): raise NotImplementedError("overlay currently only implemented for GeoDataFrames") # Collect the interior and exterior rings rings1 = _extract_rings(df1) rings2 = _extract_rings(df2) mls1 = MultiLineString(rings1) mls2 = MultiLineString(rings2) # Union and polygonize try: # calculating union (try the fast unary_union) mm = unary_union([mls1, mls2]) except: # unary_union FAILED # see https://github.com/Toblerity/Shapely/issues/47#issuecomment-18506767 # calculating union again (using the slow a.union(b)) mm = mls1.union(mls2) newpolys = polygonize(mm) # determine spatial relationship collection = [] for fid, newpoly in enumerate(newpolys): cent = newpoly.representative_point() # Test intersection with original polys # FIXME there should be a higher-level abstraction to search by bounds # and fall back in the case of no index? if use_sindex and df1.sindex is not None: candidates1 = [x.object for x in df1.sindex.intersection(newpoly.bounds, objects=True)] else: candidates1 = [i for i, x in df1.iterrows()] if use_sindex and df2.sindex is not None: candidates2 = [x.object for x in df2.sindex.intersection(newpoly.bounds, objects=True)] else: candidates2 = [i for i, x in df2.iterrows()] df1_hit = False df2_hit = False prop1 = None prop2 = None for cand_id in candidates1: cand = df1.ix[cand_id] if cent.intersects(cand[df1.geometry.name]): df1_hit = True prop1 = cand break # Take the first hit for cand_id in candidates2: cand = df2.ix[cand_id] if cent.intersects(cand[df2.geometry.name]): df2_hit = True prop2 = cand break # Take the first hit # determine spatial relationship based on type of overlay hit = False if how == "intersection" and (df1_hit and df2_hit): hit = True elif how == "union" and (df1_hit or df2_hit): hit = True elif how == "identity" and df1_hit: hit = True elif how == "symmetric_difference" and not (df1_hit and df2_hit): hit = True elif how == "difference" and (df1_hit and not df2_hit): hit = True if not hit: continue # gather properties if prop1 is None: prop1 = pd.Series(dict.fromkeys(df1.columns, None)) if prop2 is None: prop2 = pd.Series(dict.fromkeys(df2.columns, None)) # Concat but don't retain the original geometries out_series = pd.concat([prop1.drop(df1._geometry_column_name), prop2.drop(df2._geometry_column_name)]) out_series.index = _uniquify(out_series.index) # Create a geoseries and add it to the collection out_series['geometry'] = newpoly collection.append(out_series) # Return geodataframe with new indicies return GeoDataFrame(collection, index=range(len(collection)))
#print "\t", len([x for x in rings if not x.is_valid]), "invalid rings" #rings = [x for x in rings if x.is_valid] from shapely.geometry import MultiLineString mls1 = MultiLineString(rings1) mls2 = MultiLineString(rings2) try: print "calculating union (try the fast unary_union)" mm = unary_union([mls1, mls2]) except: print "FAILED" print "calculating union again (using the slow a.union(b))" mm = mls1.union(mls2) print "polygonize rings" newpolys = polygonize(mm) print "determine spatial relationship and plot new polys" for newpoly in newpolys: cent = newpoly.representative_point() # Test intersection with original polys layer1_hit = False layer2_hit = False candidates1 = list(idx1.intersection(cent.bounds)) candidates2 = list(idx2.intersection(cent.bounds)) for cand in candidates1:
def _overlay(self, layer2, method): assert method in ['union', 'intersection', 'identity'] idx1 = index.Index() idx2 = index.Index() # for fast lookup of geometry and properties after spatial index # advantage: don't have to reopen ds and seek on disk # disadvantage: have to keep everything in memory # {id: (shapely geom, properties dict) } # TODO just use the index as the id and just copy the fiona records? features1 = {} features2 = {} rings1 = [] rings2 = [] log.debug("gathering LinearRings") log.debug("\tself") for rec in self.collection(): geom = shape(rec['geometry']) rid = int(rec['id']) features1[rid] = (geom, rec['properties']) idx1.insert(rid, geom.bounds) if hasattr(geom, 'geoms'): for poly in geom.geoms: # if it's a multipolygon if not poly.is_valid: log.debug("\tgeom from self layer is not valid," + " attempting fix by buffer 0") poly = poly.buffer(0) rings1.append(poly.exterior) rings1.extend(poly.interiors) else: if not geom.is_valid: log.debug("\tgeom from self layer is not valid," + " attempting fix by buffer 0") geom = geom.buffer(0) rings1.append(geom.exterior) rings1.extend(geom.interiors) log.debug("\tlayer2") for rec in layer2.collection(): geom = shape(rec['geometry']) rid = int(rec['id']) features2[rid] = (geom, rec['properties']) idx2.insert(rid, geom.bounds) if hasattr(geom, 'geoms'): for poly in geom.geoms: # multipolygon if not poly.is_valid: log.debug("\t geom from layer2 is not valid," + " attempting fix by buffer 0") poly = poly.buffer(0) rings2.append(poly.exterior) rings2.extend(poly.interiors) else: if not geom.is_valid: log.debug("\t geom from layer2 is not valid," + " attempting fix by buffer 0") geom = geom.buffer(0) rings2.append(geom.exterior) rings2.extend(geom.interiors) #rings = [x for x in rings if x.is_valid] mls1 = MultiLineString(rings1) mls2 = MultiLineString(rings2) try: log.debug("calculating union (try the fast unary_union)") mm = unary_union([mls1, mls2]) except: log.exception("unary_union FAILED") log.debug("calculating union again (using the slow a.union(b))") mm = mls1.union(mls2) log.debug("polygonize rings") newpolys = polygonize(mm) log.debug("constructing new schema") out_schema = self.collection().schema.copy() # TODO polygon geomtype layer2_schema_map = {} # {old: new} for key, value in layer2.collection().schema['properties'].items(): if key not in out_schema['properties']: out_schema['properties'][key] = value layer2_schema_map[key] = key else: # try to rename it i = 2 while True: newkey = "%s_%d" % (key, i) if newkey not in out_schema['properties']: out_schema['properties'][newkey] = value layer2_schema_map[key] = newkey break i += 1 tempds = self.tempds(method) out_collection = fiona.collection(tempds, "w", "ESRI Shapefile", out_schema) log.debug("determine spatial relationship") for fid, newpoly in enumerate(newpolys): cent = newpoly.representative_point() # Test intersection with original polys layer1_hit = False layer2_hit = False prop1 = None prop2 = None candidates1 = list(idx1.intersection(cent.bounds)) candidates2 = list(idx2.intersection(cent.bounds)) for cand in candidates1: if cent.intersects(features1[cand][0]): layer1_hit = True prop1 = features1[cand][1] # properties break for cand in candidates2: if cent.intersects(features2[cand][0]): layer2_hit = True prop2 = features2[cand][1] # properties break # determine whether to output based on type of overlay hit = False if method == "intersection" and (layer1_hit and layer2_hit): hit = True elif method == "union" and (layer1_hit or layer2_hit): hit = True elif method == "identity" and ((layer1_hit and layer2_hit) or (layer1_hit and not layer2_hit)): hit = True if not hit: continue log.debug("write newpoly with attrs gathered from prop1 & prop2") if not prop1: prop1 = dict.fromkeys( self.collection().schema['properties'].keys(), None) if not prop2: prop2 = dict.fromkeys(layer2_schema_map.keys(), None) newprop = prop1 for key, value in prop2.items(): newkey = layer2_schema_map[key] newprop[newkey] = value out_feature = { 'id': fid, 'properties': newprop, 'geometry': mapping(newpoly) } out_collection.write(out_feature) out_collection.close() return Layer(tempds)
def _overlay(self, layer2, method): assert method in ['union', 'intersection', 'identity'] idx1 = index.Index() idx2 = index.Index() # for fast lookup of geometry and properties after spatial index # advantage: don't have to reopen ds and seek on disk # disadvantage: have to keep everything in memory # {id: (shapely geom, properties dict) } # TODO just use the index as the id and just copy the fiona records? features1 = {} features2 = {} rings1 = [] rings2 = [] log.debug("gathering LinearRings") log.debug("\tself") for rec in self.collection(): geom = shape(rec['geometry']) rid = int(rec['id']) features1[rid] = (geom, rec['properties']) idx1.insert(rid, geom.bounds) if hasattr(geom, 'geoms'): for poly in geom.geoms: # if it's a multipolygon if not poly.is_valid: log.debug("\tgeom from self layer is not valid," + " attempting fix by buffer 0") poly = poly.buffer(0) rings1.append(poly.exterior) rings1.extend(poly.interiors) else: if not geom.is_valid: log.debug("\tgeom from self layer is not valid," + " attempting fix by buffer 0") geom = geom.buffer(0) rings1.append(geom.exterior) rings1.extend(geom.interiors) log.debug("\tlayer2") for rec in layer2.collection(): geom = shape(rec['geometry']) rid = int(rec['id']) features2[rid] = (geom, rec['properties']) idx2.insert(rid, geom.bounds) if hasattr(geom, 'geoms'): for poly in geom.geoms: # multipolygon if not poly.is_valid: log.debug("\t geom from layer2 is not valid," + " attempting fix by buffer 0") poly = poly.buffer(0) rings2.append(poly.exterior) rings2.extend(poly.interiors) else: if not geom.is_valid: log.debug("\t geom from layer2 is not valid," + " attempting fix by buffer 0") geom = geom.buffer(0) rings2.append(geom.exterior) rings2.extend(geom.interiors) #rings = [x for x in rings if x.is_valid] mls1 = MultiLineString(rings1) mls2 = MultiLineString(rings2) try: log.debug("calculating union (try the fast unary_union)") mm = unary_union([mls1, mls2]) except: log.exception("unary_union FAILED") log.debug("calculating union again (using the slow a.union(b))") mm = mls1.union(mls2) log.debug("polygonize rings") newpolys = polygonize(mm) log.debug("constructing new schema") out_schema = self.collection().schema.copy() # TODO polygon geomtype layer2_schema_map = {} # {old: new} for key, value in layer2.collection().schema['properties'].items(): if key not in out_schema['properties']: out_schema['properties'][key] = value layer2_schema_map[key] = key else: # try to rename it i = 2 while True: newkey = "%s_%d" % (key, i) if newkey not in out_schema['properties']: out_schema['properties'][newkey] = value layer2_schema_map[key] = newkey break i += 1 tempds = self.tempds(method) out_collection = fiona.collection( tempds, "w", "ESRI Shapefile", out_schema) log.debug("determine spatial relationship") for fid, newpoly in enumerate(newpolys): cent = newpoly.representative_point() # Test intersection with original polys layer1_hit = False layer2_hit = False prop1 = None prop2 = None candidates1 = list(idx1.intersection(cent.bounds)) candidates2 = list(idx2.intersection(cent.bounds)) for cand in candidates1: if cent.intersects(features1[cand][0]): layer1_hit = True prop1 = features1[cand][1] # properties break for cand in candidates2: if cent.intersects(features2[cand][0]): layer2_hit = True prop2 = features2[cand][1] # properties break # determine whether to output based on type of overlay hit = False if method == "intersection" and (layer1_hit and layer2_hit): hit = True elif method == "union" and (layer1_hit or layer2_hit): hit = True elif method == "identity" and ((layer1_hit and layer2_hit) or (layer1_hit and not layer2_hit)): hit = True if not hit: continue log.debug("write newpoly with attrs gathered from prop1 & prop2") if not prop1: prop1 = dict.fromkeys( self.collection().schema['properties'].keys(), None) if not prop2: prop2 = dict.fromkeys(layer2_schema_map.keys(), None) newprop = prop1 for key, value in prop2.items(): newkey = layer2_schema_map[key] newprop[newkey] = value out_feature = { 'id': fid, 'properties': newprop, 'geometry': mapping(newpoly)} out_collection.write(out_feature) out_collection.close() return Layer(tempds)
def polygonize(self, outputLayer, append): try: from shapely.ops import polygonize from shapely.geometry import Point, MultiLineString except ImportError: self.messageBarUtils.showMessage("Polygonize", "Polygonize requires the Shapely Python module. Please contact your administrator.", QgsMessageBar.CRITICAL, 5) return self.outputLayer = outputLayer self.append = append outputEditable = False if self.outputLayer.isEditable(): outputEditable = True self.outputLayer.beginEditCommand("Polygonize") else: self.outputLayer.startEditing() grassOutputLayer=None tempDir = None try: selected = self.layer.selectedFeatureCount() > 0 tempDir = tempfile.mkdtemp() shpPath = os.path.join(tempDir, "temp.shp") QgsVectorFileWriter.writeAsVectorFormat(self.layer, shpPath, self.layer.dataProvider().encoding(), self.layer.crs(), onlySelected=selected) grassOutputLayer = self.cleanupGRASS(shpPath) self.iface.mainWindow().statusBar().showMessage("Cleanup duplicate and degenerate lines") allLinesList = self.cleanupDuplicateAndDegenerateLines(grassOutputLayer) _, progress = self.messageBarUtils.showProgress("Polygonize", "Running...", QgsMessageBar.INFO) self.iface.mainWindow().statusBar().showMessage("Shapely polygonize") progress.setValue(10) allLines = MultiLineString(allLinesList) allLines = allLines.union(Point(0, 0)) progress.setValue(25) polygons = list(polygonize([allLines])) progress.setValue(35) outFeat = QgsFeature() outputFields = self.outputLayer.dataProvider().fields() self.iface.mainWindow().statusBar().showMessage("Freeze canvas before update") self.iface.mapCanvas().freeze(True) if not append: # delete all features in outputlayer for feature in self.outputLayer.getFeatures(): self.outputLayer.deleteFeature(feature.id()) progress.setValue(50) self.iface.mainWindow().statusBar().showMessage("add to output") current = 0 if len(polygons) > 0: total = 50.0 / float(len(polygons)) for polygon in polygons: geom = QgsGeometry.fromWkt(polygon.wkt) outFeat.setGeometry(geom) outFeat.initAttributes(outputFields.count()) self.outputLayer.addFeature(outFeat) current += 1 progress.setValue(50 + int(current * total)) self.messageBarUtils.showMessage("Polygonize", "Success: %d polygons created in %s" %(current, self.outputLayer.name()), QgsMessageBar.INFO, 2) else: self.messageBarUtils.showMessage("Polygonize", "No polygon was created", QgsMessageBar.WARNING, 2) except Exception as e: QgsMessageLog.logMessage(repr(e)) self.messageBarUtils.removeAllMessages() self.messageBarUtils.showMessage("Polygonize", "There was an error performing this command. See QGIS Message log for details.", QgsMessageBar.CRITICAL, duration=5) if outputEditable: self.outputLayer.destroyEditCommand() else: self.outputLayer.rollBack() return finally: if tempDir: shutil.rmtree(tempDir, True) if grassOutputLayer: del grassOutputLayer self.iface.mapCanvas().freeze(False) self.iface.mapCanvas().refresh() if outputEditable: self.outputLayer.endEditCommand() else: self.outputLayer.commitChanges()