Erreur d'importation pour qgis.core lors de l'exécution du script shell OSGeo4w


17

J'ai essayé, avec ce post , d'exécuter un script dans OSGeo4w Shell , en dehors de QGIS. Mais j'obtiens l'erreur suivante:

ImportError: aucun module nommé qgis.core

J'ai également lu les articles suivants et essayé d'importer divers modules mais en vain:

Voici un script simple qui crée une grille et y clipse un fichier de formes polygonales.

Remarque: ce script a été testé et fonctionne correctement lors de son exécution dans 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

Suite à la réponse et au script posté par @gcarrillo, je peux enfin importer les qgis.core.modules avec succès. Le script fourni par @gcarrillo s'exécute mais je reçois une erreur de trace:

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'

1
Avez-vous correctement réglé PYTHONPATH? Je suggère d'exécuter le script avec les mêmes variables ENV que celles définies dans le qgis.bat pointé par l'icône qgis.
Luigi Pirelli du

Merci @LuigiPirelli, je vais essayer et faire un rapport.
Joseph

Merci pour votre suggestion @LuigiPirelli mais le problème persiste (sauf si j'ai mal ajouté les variables d'environnement!)
Joseph

1
Pour moi, un chemin Windows devrait être défini avec "set" comme ceci: set path =% OSGEO4W_ROOT% \ apps \ qgis \ bin;% OSGEO4W_ROOT% \ apps \ grass \ grass-grass-6.4.3 \ lib;% PATH%
Stefan

Réponses:


17

Enfin trouvé la bonne façon d'exécuter des algorithmes de traitement dans les scripts autonomes PyQGIS.

Cette réponse est basée sur les réponses au problème avec l'importation qgis.core lors de l'écriture d'un script PyQGIS autonome et à l' erreur: algorithme introuvable , qui est à son tour basé sur une discussion de la liste de diffusion Qgis-dev .

Je vous suggère de suivre le flux de travail donné dans Problème avec l'importation qgis.core lors de l'écriture d'un script PyQGIS autonome pour activer vos bibliothèques QGIS dans votre shell OSGeo4W. Une fois que vos bibliothèques QGIS fonctionnent correctement, nous pouvons passer à la 2e partie de votre question: exécuter des algorithmes de traitement dans un script PyQGIS autonome.

J'ai un peu modifié votre script d'origine et l'ai testé sur Windows 7 et GNU / Linux. J'utilise la version de traitement 2.2.0-2 et je vous suggère d'utiliser cette version, qui est la version actuelle au moment d'écrire la réponse.

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

Notez que j'ai retiré la création de la grille de la boucle for, car vous n'avez pas vraiment besoin d'une nouvelle grille pour effectuer chaque clip.

Cela devrait faire l'affaire!


Magnifique! Acceptera cette réponse car elle est beaucoup plus lisible et compacte, du moins à mon avis. Merci encore mon pote!
Joseph

Je viens de remarquer que ce script crée un Processingdossier sur le bureau, similaire à celui contenu dans le /qgis.2dossier. Cela devrait-il arriver?
Joseph

Il crée également le même dossier à partir duquel il lit les fichiers de formes et ajoute un fichier de base de données «qgis» vide. Ce qui est assez ennuyeux car le script que je modifie prend des fichiers de formes de plusieurs dossiers, ce qui signifie que ces nouveaux fichiers / dossiers apparaissent également. Je préfère toujours cette réponse à votre autre.
Joseph

À droite @Joseph, je ne sais pas sur la création de ces dossiers, le cadre de traitement les crée pour une raison que je ne comprends pas. Je suis d'accord avec vous, c'est la bonne réponse, cela vous évite des étapes supplémentaires et profite en fait du cadre. Merci pour la générosité!
Germán Carrillo

2
C'est très utile. La grande faiblesse de QGIS est de permettre aux débutants d'écrire des scripts simples. C'est comme arracher des dents.
Damien

7

Cette réponse est basée sur les réponses à Problème avec l'importation qgis.core lors de l'écriture d'un script PyQGIS autonome et sur Comment puis-je accéder au `traitement` avec Python? .

Je vous suggère de suivre le flux de travail donné dans Problème avec l'importation qgis.core lors de l'écriture d'un script PyQGIS autonome pour activer vos bibliothèques QGIS dans votre shell OSGeo4W. Une fois que vos bibliothèques QGIS fonctionnent correctement, nous pouvons passer à la 2e partie de votre question: exécuter des algorithmes de traitement dans un script PyQGIS autonome.

Comme dans Comment puis-je accéder au `traitement` avec Python? , Je vais vous donner une solution de contournement jusqu'à ce que je puisse exécuter des algorithmes par nom (par exemple, processing.runalg('provider:algorithm_name')). J'utilise la version de traitement 2.2.0-2 et je vous suggère d'utiliser cette version.

Nous pouvons utiliser la console QGIS Python pour déterminer où se trouve un script d'algorithme dans les dossiers de plug-in de traitement. Par exemple, pour savoir d'où importer qgis:creategrid, écrivez dans la console QGIS Python:

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

Vous devez obtenir:

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

ce qui nous suffit de remarquer à la fois le chemin du module ( processing.algs.qgis.mmqgisx.MMQGISXAlgorithms) et la classe d'algorithme (mmqgisx_grid_algorithm ). Vous utiliserez ces informations dans le script ci-dessous.

J'ai un peu modifié votre script et l'ai testé sur Windows 7. Vous devrez peut-être ajuster les chemins afin d'exécuter le script dans votre propre environnement.

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

Cela devrait faire l'affaire!

Comme vous pouvez le voir, j'ai créé un dossier Test / Grilles afin que vous stockiez un seul Shapefile de grille au lieu de créer un fichier temporel dans chaque boucle for, ce qui ne semble pas être nécessaire.


Merci beaucoup @gcarrillo, je vais tester cela et faire rapport.
Joseph

Merci encore pour votre aide! Je peux importer des modules avec succès! Mais lorsque j'exécute votre script, je reçois une erreur de trace. J'ai modifié la question pour l'inclure.
Joseph

Vous avez oublié de créer le dossier Test/Grids/avant d'exécuter le script.
Germán Carrillo

Désolé, j'ai oublié de le mentionner. J'ai créé le /Grids/dossier et le fichier grid.shp est créé. Cela fonctionne parfaitement! Quelque chose d'autre est le problème.
Joseph

Avez-vous apporté des modifications / ajustements au script? Je viens de le tester sur GNU / Linux sans problème. L'erreur que vous obtenez est que l'algorithme Clip ne peut pas accéder au chemin d'accès path_dir + "Grids\grid.shp", ce qui seraitC:\Users\your_username\Desktop\Test\Grids\grid.shp
Germán Carrillo

4

J'ai dû apporter des modifications mineures au script fourni par @gcarrillo pour inclure le chemin OSGEO4W64 (j'ai dû réinstaller QGIS via le programme d'installation OSGEO4W64 car j'ai utilisé le programme d'installation autonome initialement) et inclure des doubles barres obliques. Voici le script final et merci à tous pour leur aide:

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.