Importfehler für qgis.core beim Ausführen des OSGeo4w-Shell-Skripts

17

Ich habe zusammen mit diesem Beitrag versucht, ein Skript in OSGeo4w Shell außerhalb von QGIS auszuführen . Aber ich bekomme folgenden Fehler:

ImportError: Kein Modul mit dem Namen qgis.core

Ich habe auch die folgenden Beiträge gelesen und versucht, verschiedene Module zu importieren, aber ohne Erfolg:

Hier ist ein einfaches Skript, mit dem ein Raster erstellt und ein Polygon-Shapefile darauf geklippt wird.

Hinweis: Dieses Skript wurde getestet und funktioniert erfolgreich, wenn es in QGIS ausgeführt wird.

##Test=name

import os
import glob
import sys

sys.path.append("C:\Program Files\QGIS Brighton\lib;%OSGEO4W_ROOT:\=/%/apps/qgis;%OSGEO4W_ROOT%\apps\qgis\bin;%OSGEO4W_ROOT%\apps\grass\grass-6.4.3\lib;%PATH%")

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *

QgsApplication.setPrefixPath("C:\Program Files\QGIS Brighton\apps\qgis", True)
QgsApplication.initQgis()

from os.path import expanduser
home = expanduser("~")

#   Folder path of the Results for shapefiles
path_dir = home + "\Desktop\Test\\"
path_res = path_dir + "Results\\"

def run():
#   Set directory, search for all polygon .shp files and run the Create Grid and Clip algorithms then output results into Results folder
    os.chdir(path_dir + "Shapefiles\\")
    for fname in glob.glob("*.shp"):
            outputs_1=processing.runalg("qgis:creategrid", 1000, 1000, 24108, 18351.157175, 258293.802316, 665638.226408, 1, 'EPSG:7405',  None)
            outputs_2=processing.runalg("qgis:clip", outputs_1['SAVENAME'], fname, path_res  + "/"+ fname)
run()

QgsApplication.exitQgis()
#   Remove the above line when running in QGIS

Nach der Antwort und dem Skript von @gcarrillo kann ich die qgis.core.Module endlich erfolgreich importieren . Das von @gcarrillo bereitgestellte Skript wird ausgeführt, es wird jedoch ein Traceback-Fehler angezeigt:

Traceback (most recent call last):
  File "Test.py", line 55, in <module>
    run()
  File "Test.py", line 53, in run
    algClip.processAlgorithm(progress)
  File "C:\Users\username\.qgis2\python\plugins\processing\algs\qgis\ftools\Clip.py", line 59, in processAlgorithm
    layerA.pendingFields(),
AttributeError: 'NoneType' object has no attribute 'pendingFields'
Joseph
quelle
1
Haben Sie PYTHONPATH richtig eingestellt? Ich empfehle, das Skript mit denselben ENV-Variablen wie in der Datei qgis.bat auszuführen, auf die durch das Symbol qgis verwiesen wird.
Luigi Pirelli,
Danke @LuigiPirelli, ich werde es versuchen und berichten.
Joseph
Vielen Dank für Ihren Vorschlag @LuigiPirelli, aber das Problem bleibt bestehen (es sei denn, ich habe die Umgebungsvariablen falsch hinzugefügt!)
Joseph
1
Für mich sollte ein Windows-Pfad mit "set" wie folgt festgelegt werden: set path =% OSGEO4W_ROOT% \ apps \ qgis \ bin;% OSGEO4W_ROOT% \ apps \ grass \ grass-6.4.3 \ lib;% PATH%
Stefan

Antworten:

17

Endlich den richtigen Weg gefunden, um Verarbeitungsalgorithmen in PyQGIS-Standalone-Skripten auszuführen.

Diese Antwort basiert auf den Antworten auf Problem mit dem Import von qgis.core beim Schreiben eines eigenständigen PyQGIS-Skripts und auf Fehler: Algorithmus nicht gefunden , der wiederum auf einer Qgis-dev-Mailinglistendiskussion basiert .

Ich empfehle Ihnen, den in Problem mit dem Import von qgis.core angegebenen Arbeitsablauf zu befolgen, wenn Sie ein eigenständiges PyQGIS-Skript schreiben , um Ihre QGIS-Bibliotheken in Ihrer OSGeo4W-Shell zu aktivieren. Sobald Ihre QGIS-Bibliotheken ordnungsgemäß funktionieren, können Sie mit dem zweiten Teil Ihrer Frage fortfahren: Ausführen von Verarbeitungsalgorithmen in einem eigenständigen PyQGIS-Skript.

Ich habe Ihr ursprüngliches Skript ein wenig modifiziert und es unter Windows 7 und GNU / Linux getestet. Ich verwende die Verarbeitungsversion 2.2.0-2 und schlage vor, diese Version zu verwenden, die zum Zeitpunkt des Schreibens der Antwort aktuell ist.

import os, sys, glob

# Prepare the environment
from qgis.core import * # qgis.core must be imported before PyQt4.QtGui!!!
from PyQt4.QtGui import *
app = QApplication([])
QgsApplication.setPrefixPath("C:\\Program Files\\QGIS Brighton\\apps\\qgis", True) # The True value is important
QgsApplication.initQgis()

from os.path import expanduser
home = expanduser("~")

#   Folder path of the Results for shapefiles
path_dir = home + "\Desktop\Test\\"
path_res = path_dir + "Results\\"

# Prepare processing framework 
sys.path.append( home + '\.qgis2\python\plugins' )
from processing.core.Processing import Processing
Processing.initialize()
from processing.tools import *

def run():
    outputs_1=general.runalg("qgis:creategrid", 1000, 1000, 24108, 18351.157175, 258293.802316, 665638.226408, 1, 'EPSG:7405',  None)
    #   Set directory, search for all polygon .shp files and run the Create Grid and Clip algorithms then output results into Results folder
    os.chdir(path_dir + "Shapefiles\\")
    for fname in glob.glob("*.shp"):        
        outputs_2=general.runalg("qgis:clip", outputs_1['SAVENAME'], fname, path_res  + "/"+ fname)

run()

QgsApplication.exitQgis()
#   Remove the above line when running in QGIS

Beachten Sie, dass ich die Rastererstellung aus der for-Schleife entfernt habe, da Sie nicht wirklich für jeden Clip ein neues Raster benötigen.

Dies sollte den Trick machen!

Germán Carrillo
quelle
Schön! Ich werde diese Antwort akzeptieren, da sie meiner Meinung nach viel lesbarer und kompakter ist. Vielen Dank nochmal Kumpel!
Joseph
Ich habe gerade bemerkt, dass dieses Skript einen ProcessingOrdner auf dem Desktop erstellt, der dem /qgis.2Ordner ähnelt . Sollte das passieren?
Joseph
Außerdem wird derselbe Ordner erstellt, aus dem die Shapefiles gelesen und eine leere 'qgis'-Datenbankdatei hinzugefügt werden. Was ziemlich ärgerlich ist, da das Skript, das ich ändere, Shapefiles aus mehreren Ordnern entnimmt, was bedeutet, dass diese neuen Dateien / Ordner auch auftauchen. Ich ziehe diese Antwort immer noch Ihrer anderen vor.
Joseph
Richtig, @Joseph, ich weiß nicht, wie diese Ordner erstellt werden. Das Verarbeitungsframework erstellt sie aus irgendeinem Grund, den ich nicht verstehe. Ich stimme Ihnen zu, dies ist die richtige Antwort, sie vermeidet zusätzliche Schritte und nutzt das Framework tatsächlich aus. Danke für das Kopfgeld!
Germán Carrillo
2
Das ist sehr hilfreich. Die große Schwäche von QGIS besteht darin, dass Anfänger einfache Skripte schreiben können. Es ist wie Zähne ziehen.
Damien
7

Diese Antwort basiert auf den Antworten auf Problem mit dem Import von qgis.core beim Schreiben eines eigenständigen PyQGIS-Skripts und auf Wie kann ich mit Python auf die Verarbeitung zugreifen? .

Ich empfehle Ihnen, den in Problem mit dem Import von qgis.core angegebenen Arbeitsablauf zu befolgen, wenn Sie ein eigenständiges PyQGIS-Skript schreiben , um Ihre QGIS-Bibliotheken in Ihrer OSGeo4W-Shell zu aktivieren. Sobald Ihre QGIS-Bibliotheken ordnungsgemäß funktionieren, können Sie mit dem zweiten Teil Ihrer Frage fortfahren: Ausführen von Verarbeitungsalgorithmen in einem eigenständigen PyQGIS-Skript.

Wie in Wie kann ich `VERARBEITUNG mit Python? Ich gebe Ihnen eine Problemumgehung, bis ich in der Lage bin, Algorithmen nach Namen auszuführen (z processing.runalg('provider:algorithm_name'). B. ). Ich verwende die Verarbeitungsversion 2.2.0-2 und empfehle Ihnen, diese Version zu verwenden.

Wir können die QGIS Python-Konsole verwenden, um herauszufinden, wo sich ein Algorithmus-Skript in der Verarbeitung von Plugin-Ordnern befindet. Wenn Sie beispielsweise wissen qgis:creategridmöchten , woher Sie importieren möchten, schreiben Sie in die QGIS Python-Konsole:

from processing.core.Processing import Processing
Processing.getAlgorithm('qgis:creategrid')

Sie sollten erhalten:

<processing.algs.qgis.mmqgisx.MMQGISXAlgorithms.mmqgisx_grid_algorithm instance at 0xae7382c>

Dies reicht aus, um sowohl den Modulpfad ( processing.algs.qgis.mmqgisx.MMQGISXAlgorithms) als auch die Algorithmusklasse ( mmqgisx_grid_algorithm) zu erkennen. Sie werden diese Informationen im folgenden Skript verwenden.

Ich habe Ihr Skript ein wenig geändert und unter Windows 7 getestet. Möglicherweise müssen Sie die Pfade anpassen, um das Skript in Ihrer eigenen Umgebung auszuführen.

import os
import glob
import sys

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *

app = QApplication([])
QgsApplication.setPrefixPath("C:\\Program Files\\QGIS Brighton\\apps\\qgis", True)
QgsApplication.initQgis()

from os.path import expanduser
home = expanduser("~")

#   Folder path of the Results for shapefiles
path_dir = home + "\Desktop\Test\\"
path_res = path_dir + "Results\\"

# Tell Python where you will get processing from
sys.path.append(home + "\.qgis2\python\plugins")

# Reference the algorithms you want to run
from processing.algs.qgis.mmqgisx.MMQGISXAlgorithms import *
from processing.algs.qgis.ftools.Clip import *
algGrid = mmqgisx_grid_algorithm()
algClip = Clip()

from processing.core.SilentProgress import SilentProgress
progress = SilentProgress()

def run():
    # Create a grid 
    grid = path_dir + "Grids\grid.shp"
    algGrid.setParameterValue('HSPACING', 1000)
    algGrid.setParameterValue('VSPACING', 1000)
    algGrid.setParameterValue('WIDTH', 24108)
    algGrid.setParameterValue('HEIGHT', 18351.157175)
    algGrid.setParameterValue('CENTERX', 258293.802316)
    algGrid.setParameterValue('CENTERY', 665638.226408)
    algGrid.setParameterValue('GRIDTYPE', 1)
    algGrid.setParameterValue('CRS', 'EPSG:7405')
    algGrid.setOutputValue('SAVENAME', grid)
    algGrid.processAlgorithm(progress)

    # Set directory, search for all polygon .shp files 
    os.chdir(path_dir + "Shapefiles\\")    
    for fname in glob.glob("*.shp"):
        # Run the Clip algorithm, then output results into Results folder
        algClip.setParameterValue('INPUT', grid)
        algClip.setParameterValue('OVERLAY', fname)
        algClip.setOutputValue('OUTPUT', path_res  + "/"+ fname)
        algClip.processAlgorithm(progress)

run()
QgsApplication.exitQgis()

Dies sollte den Trick machen!

Wie Sie sehen, habe ich einen Test / Grids-Ordner erstellt, in dem Sie ein einzelnes Grid-Shapefile speichern, anstatt in jeder for-Schleife eine temporäre Datei zu erstellen, was anscheinend nicht erforderlich ist.

Germán Carrillo
quelle
Vielen Dank @gcarrillo, ich werde dies testen und zurückmelden.
Joseph
Nochmals vielen Dank für Ihre Hilfe! Ich kann erfolgreich Module importieren! Aber wenn ich Ihr Skript ausführe, erhalte ich einen Traceback-Fehler. Ich habe die Frage bearbeitet, um dies einzuschließen.
Joseph
Sie haben vergessen, den Ordner zu erstellen, Test/Grids/bevor Sie das Skript ausführen.
Germán Carrillo
Entschuldigung, das habe ich vergessen zu erwähnen. Ich habe den /Grids/Ordner erstellt und die Datei grid.shp wird erstellt. Das funktioniert einwandfrei Etwas anderes ist das Problem.
Joseph
Haben Sie Änderungen / Anpassungen am Skript vorgenommen? Ich habe es gerade unter GNU / Linux ohne Probleme getestet. Der Fehler, den Sie erhalten, ist, weil der Clip-Algorithmus nicht auf den Pfad zugreifen kann path_dir + "Grids\grid.shp", der lauten würdeC:\Users\your_username\Desktop\Test\Grids\grid.shp
Germán Carrillo
4

Ich musste geringfügige Änderungen an dem von @gcarrillo bereitgestellten Skript vornehmen, um den OSGEO4W64-Pfad einzuschließen (ich musste QGIS über das OSGEO4W64-Installationsprogramm neu installieren, da ich das eigenständige Installationsprogramm ursprünglich verwendete) und doppelte Schrägstriche einschließen. Hier ist das endgültige Drehbuch und vielen Dank an alle für ihre Hilfe:

import os, sys, glob

# Prepare the environment
from qgis.core import * # qgis.core must be imported before PyQt4.QtGui!!!
from PyQt4.QtGui import *
app = QgsApplication([]) # instantiation of QgsApplication
QgsApplication.setPrefixPath("C:\\OSGeo4W64\\apps\\qgis", True) # The True value is important
QgsApplication.initQgis()

from os.path import expanduser
home = expanduser("~")

#   Folder path of the Results for shapefiles
path_dir = home + "\Desktop\Test\\"
path_res = path_dir + "Results\\"

# Prepare processing framework 
sys.path.append( home + '\.qgis2\python\plugins' )
from processing.core.Processing import Processing
Processing.initialize()
from processing.tools import *

def run():
    outputs_1=general.runalg("qgis:creategrid", 1000, 1000, 24108, 18351.157175, 258293.802316, 665638.226408, 1, 'EPSG:7405',  None)
    #   Set directory, search for all polygon .shp files and run the Create Grid and Clip algorithms then output results into Results folder
    os.chdir(path_dir + "Shapefiles\\")
    for fname in glob.glob("*.shp"):        
        outputs_2=general.runalg("qgis:clip", outputs_1['SAVENAME'], fname, path_res  + "/"+ fname)
run()

QgsApplication.exitQgis()
#   Remove the above line when running in QGIS
Joseph
quelle