运行OSGeo4w Shell脚本时qgis.core的导入错误


17

我一直很努力,与此相伴,要运行脚本OSGeo4w壳牌,QGIS之外。但是我收到以下错误:

ImportError:没有名为qgis.core的模块

我还阅读了以下帖子,并尝试导入各种模块,但无济于事:

这是一个简单的脚本,它创建一个网格并将一个多边形shapefile剪切到其上。

注意:该脚本已经过测试,可以在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

按照答案和@gcarrillo发布的脚本,我终于可以成功导入qgis.core.模块了。@gcarrillo提供的脚本运行,但是我收到一个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'

1
您是否正确设置了PYTHONPATH?我建议使用与qgis图标指向的qgis.bat中设置的ENV变量相同的脚本运行脚本。
路易吉·皮雷利

谢谢@LuigiPirelli,我会去报告一下。
约瑟夫

感谢您的@LuigiPirelli的建议,但问题仍然存在(除非我添加了错误的环境变量!)
Joseph

1
对我来说,Windows PATH应该使用“ set”设置,例如:set path =%OSGEO4W_ROOT%\ apps \ qgis \ bin;%OSGEO4W_ROOT%\ apps \ grass \ grass-6.4.3 \ lib;%PATH%
Stefan

Answers:


17

最终找到了在PyQGIS独立脚本中运行处理算法的正确方法。

此答案基于以下问题的答案:编写独立的PyQGIS脚本时导入qgis.core的问题,以及错误:找不到算法的错误,而错误:算法则基于Qgis-dev邮件列表的讨论

我建议您在编写独立的PyQGIS脚本以在OSGeo4W Shell中启用QGIS库,遵循导入qgis.core问题中给出的工作流程。一旦您的QGIS库正常工作,我们就可以继续进行问题的第二部分:在独立的PyQGIS脚本中运行处理算法。

我已经稍微修改了您的原始脚本,并在Windows 7和GNU / Linux上对其进行了测试。我使用的处理版本为2.2.0-2,建议您使用此版本,这是撰写答案时的最新版本。

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

请注意,我已经从for循环中删除了网格的创建,因为您实际上不需要新的网格来执行每个剪辑。

这应该可以解决问题!


美丽!我会接受此答案,因为它的可读性和紧凑性更高。再次非常感谢您的伙伴!
约瑟夫

只是注意到此脚本Processing在桌面上创建了一个文件夹,类似于该/qgis.2文件夹中包含的文件夹。这应该发生吗?
约瑟夫

它还创建从中读取shapefile的文件夹,并添加一个空的“ qgis”数据库文件。这很烦人,因为我正在修改的脚本从多个文件夹中获取shapefile,这意味着这些新文件/文件夹也正在弹出。与您的其他答案相比,我仍然更喜欢此答案。
约瑟夫

对@Joseph,不了解这些文件夹的创建,由于我不了解的任何原因,处理框架都会创建它们。我同意您的看法,这是正确的答案,它避免了您执行其他步骤,并且实际上利用了框架。感谢您的悬赏!
赫尔曼·卡里略

2
这非常有帮助。QGIS的最大弱点是允许初学者编写简单的脚本。就像拔牙。
达米安

7

此答案基于以下问题的答案:编写独立的PyQGIS脚本时导入qgis.core有问题,以及如何使用Python访问`processing`?

我建议您在编写独立的PyQGIS脚本以在OSGeo4W Shell中启用QGIS库,遵循导入qgis.core问题中给出的工作流程。一旦您的QGIS库正常工作,我们就可以继续进行问题的第二部分:在独立的PyQGIS脚本中运行处理算法。

我如何使用Python访问`processing`?,我将为您提供解决方法,直到我能够按名称(例如processing.runalg('provider:algorithm_name'))运行算法。我使用的处理版本为2.2.0-2,建议您使用此版本。

我们可以使用QGIS Python控制台找出算法脚本在处理插件文件夹中的位置。例如,要知道qgis:creategrid从哪里导入,请在QGIS Python控制台中编写:

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

您应该获得:

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

这足以让我们注意到模块路径(processing.algs.qgis.mmqgisx.MMQGISXAlgorithms)和算法类(mmqgisx_grid_algorithm)。您将在以下脚本中使用此信息。

我已经稍微修改了脚本并在Windows 7上对其进行了测试。您可能需要调整路径才能在自己的环境中运行脚本。

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

这应该可以解决问题!

如您所见,我已经创建了一个Test / Grids文件夹,以便您存储单个网格Shapefile,而不是在每个for循环中创建一个临时文件,这似乎不是必需的。


非常感谢@gcarrillo,我将对此进行测试并报告。
约瑟夫

再次感谢您的帮助!我可以成功导入模块!但是,当我运行您的脚本时,会收到一个Traceback错误。我已编辑问题以包括此内容。
约瑟夫(Joseph)

您忘记了Test/Grids/在运行脚本之前创建文件夹。
赫尔曼·卡里略

对不起,我忘了提。我确实创建了/Grids/文件夹,并创建了grid.shp文件。很好用!还有其他问题。
约瑟夫

您是否对脚本进行了任何更改/调整?我只是在GNU / Linux上测试了它而没有问题。你得到的错误是因为剪辑算法无法访问的路径path_dir + "Grids\grid.shp",这将是C:\Users\your_username\Desktop\Test\Grids\grid.shp
赫尔曼·卡里略

4

我必须对@gcarrillo提供的脚本进行微小更改,以包含OSGEO4W64路径(我最初使用独立安装程序时必须通过OSGEO4W64安装程序重新安装QGIS)并包含双斜杠。这是最终的脚本,非常感谢大家的帮助:

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.