10

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")
2
  • 1
    It's probably expected as the tool need to address a physical layer on the hard-drive. Just an idea, but why don't you temporarily try to save you layer into a temporary file (If you need a location import tempfile and tempfile.gettempdir). This is how qgis-processing works anyway
    – Curlew
    Commented Nov 1, 2013 at 9:54
  • I will, if I have to.. Just easier and cleaner to work in memory for layers like these. If you are sure it's expected, post it as an answer and I can accept it.
    – user23603
    Commented Nov 1, 2013 at 10:00

1 Answer 1

12

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.