Błąd importowania qgis.core podczas uruchamiania skryptu powłoki OSGeo4w

17

Próbowałem wraz z tym postem uruchomić skrypt w OSGeo4w Shell , poza QGIS. Ale pojawia się następujący błąd:

ImportError: Brak modułu o nazwie qgis.core

Przeczytałem również następujące posty i próbowałem zaimportować różne moduły, ale bezskutecznie:

Oto prosty skrypt, który tworzy siatkę i przypina do niej plik kształtu wielokąta.

Uwaga: ten skrypt został przetestowany i działa z powodzeniem podczas uruchamiania w QGIS.

##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

Po odpowiedzi i skrypcie opublikowanym przez @gcarrillo mogę wreszcie qgis.core.pomyślnie zaimportować moduły. Skrypt dostarczony przez @gcarrillo działa, ale pojawia się błąd Traceback:

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
źródło
1
Czy poprawnie ustawiłeś PYTHONPATH? Sugeruję uruchomienie skryptu z tymi samymi zmiennymi ENV, które są ustawione w qgis.bat wskazywanym przez ikonę qgis.
Luigi Pirelli,
Dzięki @LuigiPirelli, spróbuję i zdam raport.
Joseph
Dziękuję za sugestię @LigiigiPirelli, ale problem nadal występuje (chyba że niepoprawnie dodałem zmienne środowiskowe!)
Joseph
1
Dla mnie ŚCIEŻKA systemu Windows powinna być ustawiona z „ustaw” w następujący sposób: ustaw ścieżkę =% OSGEO4W_ROOT% \ apps \ qgis \ bin;% OSGEO4W_ROOT% \ apps \ grass \ grass-6.4.3 \ lib;% PATH%
Stefan

Odpowiedzi:

17

Wreszcie znalazł właściwy sposób uruchamiania algorytmów przetwarzania w samodzielnych skryptach PyQGIS.

Ta odpowiedź jest oparta na odpowiedziach na problem z importem qgis.core podczas pisania samodzielnego skryptu PyQGIS oraz na błąd: Nie znaleziono algorytmu , który z kolei jest oparty na dyskusji na liście dyskusyjnej Qgis-dev .

Sugeruję, abyś postępował zgodnie z obiegiem pracy podanym w Problem z importem qgis.core podczas pisania samodzielnego skryptu PyQGIS, aby włączyć biblioteki QGIS w powłoce OSGeo4W. Po poprawnym działaniu bibliotek QGIS możemy przejść do drugiej części pytania: uruchomienie algorytmów przetwarzania w samodzielnym skrypcie PyQGIS.

Zmodyfikowałem nieco twój oryginalny skrypt i przetestowałem go w systemie Windows 7 i GNU / Linux. Korzystam z wersji do przetwarzania 2.2.0-2 i sugeruję, abyś użył tej wersji, która jest aktualna w momencie pisania odpowiedzi.

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

Zauważ, że wyjąłem tworzenie siatki z pętli for, ponieważ tak naprawdę nie potrzebujesz nowej siatki do wykonania każdego klipu.

To powinno wystarczyć!

Germán Carrillo
źródło
Piękny! Przyjmę tę odpowiedź, ponieważ jest ona znacznie bardziej czytelna i zwarta, przynajmniej moim zdaniem. Jeszcze raz bardzo dziękuję kolego!
Joseph
Zauważyłem, że ten skrypt tworzy Processingfolder na pulpicie, podobny do /qgis.2folderu zawartego w folderze. Czy to się powinno stać?
Joseph
Tworzy również ten sam folder, z którego odczytuje pliki kształtów i dodaje pusty plik bazy danych „qgis”. Co jest dość denerwujące, ponieważ modyfikowany przeze mnie skrypt pobiera pliki kształtów z kilku folderów, co oznacza, że ​​te nowe pliki / foldery również wyskakują. Nadal wolę tę odpowiedź od twojej drugiej.
Joseph
Właśnie @Joseph, nie wiem o tworzeniu tych folderów, struktura przetwarzania tworzy je z jakiegokolwiek powodu, którego nie rozumiem. Zgadzam się z tobą, to jest właściwa odpowiedź, pozwala uniknąć dodatkowych kroków i faktycznie korzysta z frameworka. Dzięki za nagrodę!
Germán Carrillo,
2
To jest bardzo pomocne. Duża słabość QGIS pozwala początkującym pisać proste skrypty. To jak ciągnięcie zębów.
Damien
7

Ta odpowiedź jest oparta na odpowiedziach na Problem z importem qgis.core podczas pisania samodzielnego skryptu PyQGIS oraz Jak uzyskać dostęp do `przetwarzania` za pomocą Pythona? .

Sugeruję, abyś postępował zgodnie z obiegiem pracy podanym w Problem z importem qgis.core podczas pisania samodzielnego skryptu PyQGIS, aby włączyć biblioteki QGIS w powłoce OSGeo4W. Po poprawnym działaniu bibliotek QGIS możemy przejść do drugiej części pytania: uruchomienie algorytmów przetwarzania w samodzielnym skrypcie PyQGIS.

Jak w Jak mogę uzyskać dostęp do „przetwarzania” za pomocą Pythona? , Dam ci obejście, dopóki nie będę w stanie uruchomić algorytmów według nazwy (np processing.runalg('provider:algorithm_name').). Korzystam z przetwarzania w wersji 2.2.0-2 i sugeruję korzystanie z tej wersji.

Możemy użyć konsoli QGIS Python, aby dowiedzieć się, gdzie znajduje się skrypt algorytmu w przetwarzaniu folderów wtyczek. Na przykład, aby wiedzieć, skąd importować qgis:creategrid, napisz w konsoli QGIS Python:

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

Powinieneś uzyskać:

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

co wystarczy nam zauważyć zarówno ścieżkę modułu ( processing.algs.qgis.mmqgisx.MMQGISXAlgorithms), jak i klasę algorytmów ( mmqgisx_grid_algorithm). Użyjesz tych informacji w skrypcie poniżej.

Zmodyfikowałem trochę skrypt i przetestowałem go w systemie Windows 7. Może być konieczne dostosowanie ścieżek w celu uruchomienia skryptu we własnym środowisku.

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

To powinno wystarczyć!

Jak widać, utworzyłem folder Test / Grids, abyś przechowywał jeden plik Shapefile z siatki zamiast tworzyć plik tymczasowy w każdej pętli for, co nie wydaje się konieczne.

Germán Carrillo
źródło
Wielkie dzięki @gcarrillo, przetestuję to i zdam relację.
Joseph
Jeszcze raz dziękuję za pomoc! Mogę z powodzeniem importować moduły! Ale po uruchomieniu skryptu pojawia się błąd Traceback. Zredagowałem pytanie, aby to uwzględnić.
Joseph
Zapomniałeś utworzyć folder Test/Grids/przed uruchomieniem skryptu.
Germán Carrillo
Przepraszam, zapomniałem o tym wspomnieć. Zrobiłem utworzyć /Grids/folder i plik grid.shp jest tworzony. To działa idealnie! Problem stanowi coś innego.
Joseph
Czy wprowadziłeś jakieś zmiany / poprawki w skrypcie? Właśnie przetestowałem to na GNU / Linux bez problemu. Występuje błąd, ponieważ algorytm Clip nie może uzyskać dostępu do ścieżki path_dir + "Grids\grid.shp", co byłobyC:\Users\your_username\Desktop\Test\Grids\grid.shp
Germán Carrillo
4

Musiałem wprowadzić niewielkie zmiany w skrypcie udostępnionym przez @gcarrillo, aby uwzględnić ścieżkę OSGEO4W64 (musiałem ponownie zainstalować QGIS za pomocą instalatora OSGEO4W64, ponieważ początkowo korzystałem z samodzielnego instalatora) i uwzględnić podwójne ukośniki. Oto ostatni skrypt i wielkie podziękowania dla wszystkich za ich pomoc:

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
źródło