QGIS – Using In-Memory Vector Layer with QGIS Processing/SEXTANTE

memorypyqgisqgisqgis-processingsextante

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")

Best 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).