1
  • I have one piece of Python code that I wrote in QGIS 3.6 (I'll call this code1)
  • and I have a second piece of Python code that is a bigger project, which I wrote just in a normal text programme and which I run through the terminal of my xubuntu (I'll call this code2)

They both work seperately in QGIS / the terminal.
Now I want to combine them - code2 should at some point call code1 and run it as well. I don't want to open QGIS and run the code, everything should be done as one single process.

So I copied code1 into code2. Then I wrote this at the beginning of code2

from qgis.core import *
from qgis.gui import *
import qgis.utils
QgsApplication.setPrefixPath("/usr/share/qgis/",True)
qgs = QgsApplication([],False)
qgs.initQgis()

When the code reaches the first QGis function

params_proj = {
    "INPUT": layerinput_proj,
    "TARGET_CRS":"EPSG:4326", 
    "OUTPUT":("/media/vali/project/geodaten/gem_proj.shp")
    }
feedback=QgsProcessingFeedback()    
res_proj=QgsProcessingAlgRunnerTask(u"native:reprojectlayer", params_proj, feedback=feedback)
res_proj["OUTPUT"] 

I get this error:

TypeError: QgsProcessingAlgRunnerTask(): argument 1 has unexpected type 'str'

Why does the code work in QGIS but not when I run it through the terminal?

I searched the Internet and could not find any solutions that work for me or that I can understand, as I am quite a beginner.

Since someone asked, here is a larger bit of my code:

#! /usr/bin/python3
import openpyxl, os, csv
from openpyxl.utils import get_column_letter, column_index_from_string
import xml.etree.ElementTree as ET, pandas as pd, geopandas as gpd, csv
from qgis.core import *# supply path to qgis install location
from qgis.gui import *
import qgis.utils


#------------------------------------------------------------------------
QgsApplication.setPrefixPath("/usr/share/qgis/",True)
# create a reference to the QgsApplication, setting the
# second argument to False disables the GUI
qgs = QgsApplication([],False)
# load providers
qgs.initQgis()

#sys.path.append('/docs/dev/qgis/build/output/python/plugins')

path="/media/valentina/0bc36d5e-1c60-4266-a1ef-a284ac0b5315/project/geodaten/"

#-------------- change projection of gem shape -------------
layerinput_proj=QgsVectorLayer((path+"STATISTIK_AUSTRIA_GEM_20190101Polygon.shp"), "proj", "ogr")

params_proj = {
    "INPUT": layerinput_proj,
    "TARGET_CRS":"EPSG:4326", 
    "OUTPUT":(path+"gem_proj.shp")
    }
feedback=QgsProcessingFeedback()    
res_proj=QgsProcessingAlgRunnerTask(u"native:reprojectlayer", params_proj, feedback=feedback)
res_proj["OUTPUT"]

#-------------- calculate centroids -------------
layerinput=QgsVectorLayer((path+"gem_proj.shp"), "Gemshape", "ogr")

params = {
    "INPUT": layerinput,
    "ALL_PARTS":False, 
    "OUTPUT":(path+"gem_centroid.shp")
    }

res=processing.run("native:centroids", params, feedback=feedback)
res["OUTPUT"]

#-------------- reproject centroids -------------
layerinput_proj=QgsVectorLayer((path+"gem_centroid.shp"), "proj", "ogr")
params_proj2 = {
    "INPUT": layerinput_proj,
    "TARGET_CRS":"EPSG:4326", 
    "OUTPUT":(path+"gem_centroid_proj.shp")
    }

res_proj2=processing.run("native:reprojectlayer", params_proj2, feedback=feedback)
res_proj2["OUTPUT"]

#-------------- calculate geometry attributes -------------
layerinput_geom=QgsVectorLayer((path+"gem_centroid_proj.shp"), "gem_centroid", "ogr")

params_geom = {
    "INPUT": layerinput_geom,
    "CALC_METHOD":0, 
    "OUTPUT":(path+"gem_centroid_geom.shp")
    }

res_geom=processing.run("qgis:exportaddgeometrycolumns", params_geom, feedback=feedback)
res_geom["OUTPUT"]

qgs.exitQgis()
2
  • Can you please post more of your code? I'd like to see whether/how you are importing QgsNativeAlgorithms. – alphabetasoup May 28 '19 at 21:59
  • I edited the original post and pasted a larger part of my code – Vali May 29 '19 at 8:41
1

Once you have the QGIS application (qgs in your code):

from qgis.analysis import QgsNativeAlgorithms
import processing
from processing.core.Processing import Processing
Processing.initialize() # This will emit some warnings that you can ignore
qgs.processingRegistry().addProvider(QgsNativeAlgorithms())

res_proj = processing.run("qgis:reprojectlayer", layerinput_proj,"EPSG:4326", "/media/vali/project/geodaten/gem_proj.shp")

This is untested. Note that the order of imports is important. This is an area QGIS can be improved. In particular, you need to import processing after the call to initQgis(). I have a gist to do something similar here. Sometimes linters like to move all imports to the top of a file and change their order, so I place sequence-sensitive imports in a function and call them when appropriate.

5
  • I put this at the beginning of my code, but now I get this error (for line 2 in your post): " ModuleNotFoundError: No module named 'processing' " --- Do I have to install something? – Vali May 29 '19 at 9:03
  • No, I don't think so. As I said, the order of imports is important. Try to import processing after all of your original imports. – alphabetasoup May 29 '19 at 9:33
  • There are several related questions at this point: gis.stackexchange.com/questions/129513/… – alphabetasoup May 29 '19 at 9:34
  • Surely (for QGIS 3.x) the call to processing.run should only have two arguments, the second of which being a dictionary of parameters? – Mr Purple Jun 23 '19 at 0:24
  • Correct. I did say it was untested. The main demonstration here is getting access to processing at all. Feel free to edit it. – alphabetasoup Jun 23 '19 at 1:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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