Terminating Python Scripts in QGIS Processing Framework

pyqgisqgis-2qgis-processing

I'm writing a Python script to use it in Processing framework. I need to cancel script execution if certain conditions are met (to save user's time). I tried to use sys.exit(arguments) command. The issue is that not only the script, but QGIS itself shuts down too. I also tried quit() but result is the same. How should I terminate script in Processing framework?

The following code is for reproduction purpose only. I don't need ad hoc solution for this particular case because I already have it. I need to know how to deal with this issue in general.

##Raster processing=group
##raster_1=raster
##raster_2=raster


from osgeo import gdal
import sys
from numpy import *
import ntpath
import re
import platform
from PyQt4 import QtGui


raster_1 = gdal.Open(raster_1)
raster_2 = gdal.Open(raster_2)

rasters_list = [raster_1, raster_2]

# create a message for the case when CRSs of rasters do not match
class WrongCRS(QtGui.QMessageBox):

  def __init__(self):
    super(WrongCRS, self).__init__()

    self.initUI()

  def initUI(self):

    self.warning(self, 'Oops!',
            "Rasters must have the same CRS!\n\nExecution cancelled!", QtGui.QMessageBox.Ok)

# check CRS
proj = None
for raster in rasters_list:
  new_proj = raster.GetProjection()
  if proj is None:
    proj = new_proj
  else:
    if proj != new_proj:
      WrongCRS()
      sys.exit('CRSs do not match!')
    else:
      continue

Best Answer

  • first thing, osgeo.gdal is for pure Python scripting:

    from osgeo import gdal  
    raster  = gdal.Open('your.tif')   
    raster.GetProjection()
    

Everything else is a problem of osgeo, and not of PyQGIS, since you use 2 QGIS existing layers:

 ##raster_1=raster  
 ##raster_2=raster

you don't need it. To process the layers, the correct code is:

raster_1 = processing.getobject(raster_1)   
raster_2 = processing.getobject(raster_2)

an the crs is given by:

new_proj = raster.crs()
  • second thing, you cannot load a raster in QGIS without projection (if not yet existing, it is chosen by QGIS, according to some criteria):

enter image description here

So your first condition if proj is None:, is unnecessary and your script become (you don't need a list with only two layers):

raster_1 = processing.getobject(raster_1)
raster_2 = processing.getobject(raster_2)
if raster_1.crs()==raster_2.crs():
     action
else:
     WrongCRS()

and the script terminate by himself.


in the last version of the processing module, it is now:

processing.getObjects()

For terminate the script, you can embed your script in a function and use sys.exitfunc() (I use the Python console to to see the results)

example:

import atexit
.....
def all_done():
    message = '- Rasters must have the same CRS!\n\nExecution cancelled!'
    print message   
atexit.register(all_done)
raster_1 = processing.getObject(raster_1)
raster_2 = processing.getObject(raster_2)
def main():
    if raster_1.crs() != raster_2.crs():
         sys.exitfunc()
    else:
          message = "ok"
          print message
          continue
main()

Result in the Python console:

enter image description here

Related Question