1

I try to use clip vector by polygon in pyqgis.

My code (minimal working example)

import sys
from qgis.core import *
import qgis.utils


QgsApplication.setPrefixPath("/usr",True)
qgs = QgsApplication([],True)
qgs.initQgis()

# load base layer
blayer = QgsVectorLayer("lokale_orte.shp", "lokale_orte", "ogr")
if not blayer.isValid():
        print "Layer failed to load!"
else:
        print "success:  load layer"


# load clip layer
clayer = QgsVectorLayer("kleine_kreise.shp", "kleine_kreise", "ogr")
if not clayer.isValid():
        print "Layer failed to load!"
else:
        print "success:  load layer"


# Prepare processing framework 
sys.path.append('/usr/share/qgis/python/plugins') # Dir where Processing is located
from processing.core.Processing import Processing
Processing.initialize()
from processing.tools import *


# run clip
general.runalg('gdalogr:clipvectorsbypolygon', 'lokale_orte.shp',                 'kleine_kreise.shp', None, None)

The complete output and error message is:

success:  load layer
success:  load layer

Error in sys.excepthook:

Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/qgis/utils.py", line 196, in qgis_excepthook
    showException(type, value, tb, None, messagebar=True)

  File "/usr/lib/python2.7/dist-packages/qgis/utils.py", line 107, in showException
    open_stack_dialog(type, value, tb, msg)

  File "/usr/lib/python2.7/dist-packages/qgis/utils.py", line 142, in open_stack_dialog
    iface.messageBar().popWidget()

AttributeError: 'NoneType' object has no attribute 'messageBar'


Original exception was:

Traceback (most recent call last):
  File "a.py", line 34, in <module>
    general.runalg('gdalogr:clipvectorsbypolygon', 'lokale_orte.shp', 
'kleine_kreise.shp', None, None)

  File "/usr/share/qgis/python/plugins/processing/tools/general.py", line 75, in runalg
    alg = Processing.runAlgorithm(algOrName, None, *args, **kwargs)

  File "/usr/share/qgis/python/plugins/processing
/core/Processing.py", line 300, in runAlgorithm
    ret = runalg(alg, progress)

  File "/usr/share/qgis/python/plugins/processing
/gui/AlgorithmExecutor.py", line 52, in runalg
    progress.error(e.msg)

AttributeError: 'NoneType' object has no attribute 'error'

I guess my problem is the runalg call, according to http://docs.qgis.org/2.6/de/docs/user_manual/processing_algs/gdalogr/ogr_geoprocessing/clipvectorsbypolygon.html

I think I can write None for output layer to force QGIS to write the output in an memory layer. But what about options? What to write? Where is a proper documentation?

6
  • Are you running it as a standalone script?
    – mgri
    Commented May 2, 2017 at 19:02
  • yes. It is not part of an qgis extension. Basically it works, general.alglist creates the proper output.
    – dlg_
    Commented May 2, 2017 at 19:16
  • versions: python: 2.7; qgis: 2.16; OS: Ubuntu 16.4
    – dlg_
    Commented May 2, 2017 at 19:18
  • So, you only want to call the output from the general.runalg (i.e. the last operation of your code) as a memory output?
    – mgri
    Commented May 2, 2017 at 19:22
  • yes. I want to iterate over all features in the output layer and do some calculations. I think a memory output is enough. But the basic input layer (lokale_orte.shp in the example script) has thousands of features, so i like to clip it to get a usable subset.
    – dlg_
    Commented May 2, 2017 at 19:30

2 Answers 2

1

You may continue using the memory layer by loading it as an object. Before doing this, you need to know how the output from the algorithm is called, so typing these lines in the Python Console:

import processing
processing.alghelp('gdalogr:clipvectorsbypolygon')

you will see that the output's name is OUTPUT_LAYER:

ALGORITHM: Clip vectors by polygon
INPUT_LAYER <ParameterVector>
CLIP_LAYER <ParameterVector>
OPTIONS <ParameterString>
OUTPUT_LAYER <OutputVector>

This means that you will be able to use it if you add a new variable and call it in this way:

# change 'my_algorithm' name as you want
my_algorithm = general.runalg('gdalogr:clipvectorsbypolygon', 'lokale_orte.shp', 'kleine_kreise.shp', None, None)

# change 'my_output' name as you want
my_output = processing.getObject(my_algorithm['OUTPUT_LAYER'])

By now, my_output will be the object to use for calling the layer returned by the clip operation and you are ready to do something with it.

EDIT For getting your script working, you may try using the following code (slightly different from yours):

import sys
from qgis.core import *
import qgis.utils

qgs = QApplication([], True)
QgsApplication.setPrefixPath("/usr", True)
QgsApplication.initQgis()

# Prepare processing framework 
sys.path.append('/usr/share/qgis/python/plugins') # Dir where Processing is located
from processing.core.Processing import Processing
from processing.tools import *
Processing.initialize()

# load base layer
blayer = QgsVectorLayer("path/to/the/shapefile/lokale_orte.shp", "lokale_orte", "ogr")
if not blayer.isValid():
    print "Layer failed to load!"
else:
    print "success:  load layer"

# load clip layer
clayer = QgsVectorLayer("path/to/the/shapefile/kleine_kreise.shp", "kleine_kreise", "ogr")
if not clayer.isValid():
    print "Layer failed to load!"
else:
    print "success:  load layer"

# run clip
# change 'my_algorithm' name as you want
my_algorithm = general.runalg('gdalogr:clipvectorsbypolygon', 'lokale_orte.shp', 'kleine_kreise.shp', None, None)

# change 'my_output' name as you want
my_output = processing.getObject(my_algorithm['OUTPUT_LAYER'])

QgsApplication.exitQgis()
qgs.exit()
9
  • Thanks for this. Generating a memory layer is now much clearer for me. But I still get the same error: AttributeError: 'NoneType' object has no attribute 'error'
    – dlg_
    Commented May 2, 2017 at 19:52
  • @dlg_ are you sure that the output from the 'gdalogr:clipvectorsbypolygon' is correctly created? Maybe there is some other error before this operation?
    – mgri
    Commented May 2, 2017 at 19:56
  • OK, I checked it. Everything befor calling runalg works fine. Even processing.alghelp('gdalogr:clipvectorsbypolygon') works. So I don't think that there is an issue by loading the library.
    – dlg_
    Commented May 2, 2017 at 20:02
  • So, nothing is returned if you write print my_output?
    – mgri
    Commented May 2, 2017 at 20:07
  • No. I checked this, but the script terminates with exactly the same error message as I wrote in the question. I checked also clipping the shapefile from qgis user interface which works fine. There might be no problem with the input files.
    – dlg_
    Commented May 2, 2017 at 20:14
0

You will make a CRS reference before clipping.

# PostGIS SRID 4326 is allocated for WGS84
crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.PostgisCrsId) 
my_algorithm = general.runalg('gdalogr:clipvectorsbypolygon', 'lokale_orte.shp', 'kleine_kreise.shp', None, None,rcs)

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.