QGIS 2.16: processing.runalg gagal ketika dijalankan di luar QGIS dalam aplikasi khusus

8

Saya sedang mengembangkan paket RQGIS. Untuk menjalankan QGIS dari dalam R, saya memanggil QGIS melalui baris perintah. Ini bekerja dengan sempurna dengan QGIS 2.14. Namun, menjalankan kode yang sama dengan QGIS 2.16 menghasilkan kesalahan. Inilah yang saya lakukan:

Pertama, saya mengatur semua jalur yang diperlukan di command prompt:

@echo off
SET OSGEO4W_ROOT=D:\osgeo4w_qgis16
call "%OSGEO4W_ROOT%"\bin\o4w_env.bat
@echo off
path %PATH%;%OSGEO4W_ROOT%\apps\qgis\bin
set PYTHONPATH=%PYTHONPATH%;%OSGEO4W_ROOT%\apps\qgis\python;
set QGIS_PREFIX_PATH=%OSGEO4W_ROOT%\apps\qgis
rem open python     
python.exe

Selanjutnya, saya menjalankan baris berikut dengan Python:

import os
import sys
from qgis.core import *
import qgis.utils
from osgeo import ogr
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.gui import *
QgsApplication.setPrefixPath('D:\osgeo4w_qgis16\apps\qgis', True)
app = QgsApplication([], True)
QgsApplication.initQgis()
sys.path.append(r'D:\osgeo4w_qgis16\apps\qgis\python\plugins')
from processing.core.Processing import Processing
Processing.initialize()
import processing
processing.alglist()
processing.alghelp("grass7:v.voronoi")

Ini bekerja. Namun, memanggil processing.runalg ...

from processing.tests.TestData import points
result = processing.runalg('grass7:v.voronoi', points(), False, False, '270778.60198,270855.745301,4458921.97814,4458983.8488', -1, 0.0001, 0, None,)

... menghasilkan pesan kesalahan ini:

Error in sys.excepthook:
Traceback (most recent call last):
  File "D:\osgeo4w_qgis16\apps\qgis\python\qgis\utils.py", line 196, in qgis_excepthook
    showException(type, value, tb, None, messagebar=True)
  File "D:\osgeo4w_qgis16\apps\qgis\python\qgis\utils.py", line 107, in showException
    open_stack_dialog(type, value, tb, msg)
  File "D:\osgeo4w_qgis16\apps\qgis\python\qgis\utils.py", line 142, in open_stack_dialog
    iface.messageBar().popWidget()
AttributeError: 'NoneType' object has no attribute 'messageBar'

Original exception was:
Traceback (most recent call last):
  File "<stdin>", line 10, in <module>
  File "D:\osgeo4w_qgis16\apps\qgis\python\plugins\processing\tools\general.py", line 75, in runalg
    alg = Processing.runAlgorithm(algOrName, None, *args, **kwargs)
  File "D:\osgeo4w_qgis16\apps\qgis\python\plugins\processing\core\Processing.py", line 304, in runAlgorithm
    ret = runalg(alg, progress)
  File "D:\osgeo4w_qgis16\apps\qgis\python\plugins\processing\gui\AlgorithmExecutor.py", line 52, in runalg
    progress.error(e.msg)
AttributeError: 'NoneType' object has no attribute 'error'
Jannes
sumber

Jawaban:

5

Kesalahan Pemrosesan telah diperbaiki baru-baru ini, lihat https://github.com/qgis/QGIS/commit/df2ca2e60798315d816966f25aa024b93835f776

Victor Olaya
sumber
1
Victor, meskipun Anda mengatakan masalah itu sudah diperbaiki, masih tetap hidup. Baru-baru ini, QGIS 2.18 dirilis. Tetapi masih harus diganti secara manual alg.execute(progress)dengan alg.execute(progress or SilentProgress())di AlgorithmExecutor.py untuk menggunakan QGIS dalam aplikasi khusus. Masalahnya menjadi lebih buruk karena sekarang tidak ada pesan kesalahan yang terjadi. Alih-alih, bahkan ada pesan sukses (misalnya, saat berjalan saga:catchmentarearecursive), hanya folder output yang ditentukan yang tetap kosong. Saya akan sangat menghargai jika Anda dapat memperbaiki masalah itu. Atau apakah saya melewatkan sesuatu?
Jannes
5

Barry, terima kasih atas saran Anda. Tampaknya, tim inti QGIS mengubah kode. Dalam QGIS 2.14 runalgdidefinisikan sebagai berikut:

def runalg(alg, progress=None):
  """Executes a given algorithm, showing its progress in the
  progress object passed along.

  Return true if everything went OK, false if the algorithm
  could not be completed.
  """

  if progress is None:
      progress = SilentProgress()
  try:
      alg.execute(progress)
      return True
  except GeoAlgorithmExecutionException as e:
      ProcessingLog.addToLog(sys.exc_info()[0], ProcessingLog.LOG_ERROR)
      progress.error(e.msg)
      return False

Jadi, jika kemajuan sama dengan None(yang merupakan kasus dalam kode contoh saya), SilentProgressuruslah. Sebaliknya, dalam QGIS 2.16 pernyataan if yang sesuai telah dihapus (lihat jawaban Barry di atas), yang mengarah pada kegagalan runalg. Salah satu solusinya adalah mengedit skrip AlgorithmExecutor.py secara manual dengan menambahkan lagi baris yang hilang. Dalam hal ini, seseorang harus menambahkan baris impor lain ke awal skrip ( from processing.core.SilentProgress import SilentProgress).

Saya juga akan bertanya kepada tim inti QGIS apakah ada alasan khusus untuk menghilangkan garis-garis ini. Dengan sedikit keberuntungan, mereka akan menambahkannya lagi ...

Jannes
sumber
menambahkan 2 baris di atas dan pernyataan impor ke skrip AlgorithmExecutor.py bekerja untuk saya! Saya baru saja mengupgrade ke 2.16 minggu lalu dan menutup ini juga. Terima kasih!
rickD
Saya baru saja memutakhirkan 2.8.2 ke 2.16.3 dan mengalami masalah yang sama dengan beberapa skrip python eksternal yang saya jalankan. Membuat perubahan di atas memperbaiki masalah untuk saya. Terima kasih Jannes dan Spacedman.
BStone
4

Ini sedikit kesalahan asli yang terakhir:

  File "D:\osgeo4w_qgis16\apps\qgis\python\plugins\processing\gui\AlgorithmExecutor.py", line 52, in runalg
    progress.error(e.msg)
AttributeError: 'NoneType' object has no attribute 'error'

mengatakan bahwa progressadalah None, sehingga progress.errorpanggilan gagal. Ini kemudian memicu bagian pertama dari kesalahan yang ditampilkan karena penangan kesalahan QGIS mencoba untuk menulis pesan ke objek iface yang juga tidak ada.

Bit relevan dari kode python Pemrosesan yang menghasilkan kesalahan asli adalah:

def runalg(alg, progress=None):
    """Executes a given algorithm, showing its progress in the
    progress object passed along.

    Return true if everything went OK, false if the algorithm
    could not be completed.
    """
    try:
        alg.execute(progress)
        return True
    except GeoAlgorithmExecutionException as e:
        ProcessingLog.addToLog(sys.exc_info()[0], ProcessingLog.LOG_ERROR)
        progress.error(e.msg)  ## this line ##
        return False

Jadi untuk beberapa alasan, algoritma telah menaikkan GeoAlgorithmExecutionException dan progresstidak ada. Saya tidak tahu dari mana progressseharusnya berasal - mungkin skrip python Anda harus membuat sesuatu untuk diteruskan. Saya tidak tahu itu meningkatkan kesalahan GeoAlg juga, atau yang mana dari dua masalah yang Anda benar-benar perlu perbaiki ...

Spacedman
sumber