Tuesday, 1 October 2019

pyqgis - Using in-memory vector layer with QGIS processing / SEXTANTE


I'm trying to run the qgis:clip algorithm from console, but am getting an error when using an in-memory layer as the overlay parameter. Is this to be expected, or am I doing something wrong?


Code:


mem_layer = QgsVectorLayer("Polygon?crs=epsg:4326", "temp_layer", "memory")
if not mem_layer.isValid(): raise Exception("Failed to create memory layer")
mem_layer_provider = mem_layer.dataProvider()

clip_polygon = QgsFeature()
clip_polygon.setGeometry(QgsGeometry.fromRect(

QgsRectangle(
self.output_layer.extent().xMinimum() + 10,
self.output_layer.extent().yMinimum() + 10,
self.output_layer.extent().xMaximum() - 10,
self.output_layer.extent().yMaximum() - 10
)
))
mem_layer_provider.addFeatures([clip_polygon])
mem_layer.updateExtents()


output = self.output_layer_path + "2"
processing.runalg("qgis:clip", layer, mem_layer, output) # Fails

In the code above, self.output_layer and layer are vector layer objects (QgsVectorLayer - proper ones, loaded from shapefiles on disk), self.output_layer_path is a python string object with a path.


Here is the error I'm getting:


"C:/OSGEO4~1/apps/qgis/./python/plugins\processing\core\GeoAlgorithm.py", line 150, in     
execute self.processAlgorithm(progress)
File "C:/OSGEO4~1/apps/qgis/./python/plugins\processing\algs\ftools\Clip.py", line 72,
in processAlgorithm index = utils.createSpatialIndex(layerB)
File "C:/OSGEO4~1/apps/qgis/./python/plugins\processing\algs\ftools\FToolsUtils.py",

line 31, in createSpatialIndex features = QGisLayers.features(layer)
File "C:/OSGEO4~1/apps/qgis/./python/plugins\processing\core\QGisLayers.py", line 211,
in features return Features(layer)
File "C:/OSGEO4~1/apps/qgis/./python/plugins\processing\core\QGisLayers.py", line 218,
in __init__ self.iter = layer.getFeatures()
AttributeError: 'NoneType' object has no attribute 'getFeatures'

If I change my processing call to the following, it runs without error:


processing.runalg("qgis:clip", layer, self.output_layer, output) # Runs fine


Also, if of any help, this is the failing algorithm as it is logged in processing_qgis.log:


processing.runalg("qgis:clip","C:/path/to/shapefile.shp|layerid=0|subset=CONTINENT = 
'Europe'","Polygon?crs=epsg:4326","C:/path/to/output")

Answer



As it turns out, this works fine as long as you add the memory layer to the table of contents before using it. It seems the dataobjects.getObjectFromUri function in the QGIS source can't handle it otherwise.


So the following works very well:


QgsMapLayerRegistry.instance().addMapLayer(mem_layer)
processing.runalg("qgis:clip", layer, mem_layer, output)

Also see my recent question for how to use memory layers as output from processing functions (basically use processing.runandload instead of processing.runalg).



No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...