From 38232a02351a3225114607f9b75eeff86192f863 Mon Sep 17 00:00:00 2001 From: Radim Blazek Date: Fri, 21 Dec 2012 17:33:29 +0100 Subject: [PATCH] GRASS Direct test script initial work --- src/plugins/grass/qgis_grass_test.py | 157 +++++++++++++++++++++++++ src/providers/grass/qgsgrassgislib.cpp | 13 +- 2 files changed, 167 insertions(+), 3 deletions(-) create mode 100755 src/plugins/grass/qgis_grass_test.py diff --git a/src/plugins/grass/qgis_grass_test.py b/src/plugins/grass/qgis_grass_test.py new file mode 100755 index 00000000000..3c41ca79c54 --- /dev/null +++ b/src/plugins/grass/qgis_grass_test.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +*************************************************************************** + GRASS Direct test - to be run in GRASS shell + + - collects list of raster layers + - exports GRASS layers on low resolution to temporary GeoTIFFs + - runs GRASS modules in standard and direct mode and compares results + - writes out report +*************************************************************************** +""" +__author__ = 'Radim Blazek' +__date__ = 'December 2012' +__copyright__ = '(C) 2012, Radim Blazek' +__revision__ = '$Format:%H$' + +import os, sys, glob, subprocess, time, re + +class Test: + def __init__(self): + if not os.environ.has_key("GISBASE") or not os.environ.has_key("GISRC"): + print "This script must be run in GRASS shell." + sys.exit ( 1 ) + + if not os.environ.has_key("QGIS_PREFIX_PATH"): + print "QGIS_PREFIX_PATH environment variable not set." + sys.exit ( 1 ) + + self.size = 10 + self.reportStr = "" + pass + + # add message to HTML report + def report( self, msg ): + self.reportStr += msg + "\n" + + def writeReport( self ): + print self.reportStr + + def test(self): + print "GRASS Direct test" + + + + tmp_dir = os.path.abspath( "qgis-grass-test-%s" % time.strftime('%y%m%d-%H%M%S') ) + tmp_dir = os.path.abspath( "qgis-grass-test-debug" ) # debug + print "Output will be written to %s" % tmp_dir + + files_dir = "%s/tif" % tmp_dir + #os.makedirs( files_dir ) + + # get list of raster layers + print "Getting list of rasters ..." + rasters = self.srun( ["g.mlist", "type=rast"] ).splitlines() + max_rasters = 1 + print "%s rasters found, using first %s" % ( len( rasters), max_rasters ) + rasters = rasters[0:1] + + print "Exporting rasters" + for raster in rasters: + print raster + output = "%s/%s.tif" % ( files_dir, raster ) + self.srun( ["g.region", "rast=%s" % raster, "cols=%s" % self.size, "rows=%s" % self.size ] ) + self.srun( ["r.out.gdal", "input=%s" % raster, "output=%s" % output] ) + + # run modules + count = 0 + for module in self.modules(): + for raster in rasters: + module = re.sub(" *", " ", module ) + module_name = module.split(" ")[0] + # --- native --- + self.srun( ["g.region", "rast=%s" % raster, "cols=%s" % self.size, "rows=%s" % self.size ] ) + output = "qgistest1" + # clean old + self.srun( ["g.remove", "-f", "rast=%s" % output ] ) + # substitute rasters + native_args = module.replace("R1",raster).replace("RO1",output).split(" "); + (code, out, err) = self.run( native_args ) + if code != 0: + self.report( "Native failed: %s" % " ".join(native_args) ) + # export + native_output_file = "%s/%s-%s-native.tif" % ( files_dir, module_name, raster ) + self.srun( ["r.out.gdal", "input=%s" % output, "output=%s" % native_output_file] ) + self.srun( ["g.remove", "-f", "rast=%s" % output ] ) + + # --- direct --- + direct_input_file = "%s/%s.tif" % ( files_dir, raster ) + direct_output_file = "%s/%s-%s-direct.tif" % ( files_dir, module_name, raster ) + + # substitute rasters + direct_args = module.replace("R1",direct_input_file).replace("RO1",direct_output_file).split(" "); + env = os.environ + + # CRS + proj = self.srun( ["g.proj", "-j"] ) + longlat = True if proj.find("+proj=longlat") != -1 else False + proj = proj.splitlines() + proj = " ".join ( proj ) + print proj + env['QGIS_GRASS_CRS'] = proj + + # set GRASS region as environment variable + reg = self.srun( ["g.region", "-g"] ) + reg_dict = dict(item.split("=") for item in reg.splitlines()) + reg_var= { 'n': 'north', 's': 'south', 'e': 'east', 'w':'west', 'nsres': 'n-s resol', 'ewres': 'e-w resol' } + if longlat: + region = "proj:3;zone:-1" # longlat + else: + region = "proj:99;zone:-1" # other projection + for k,v in reg_dict.iteritems(): + if k == 'cells': continue + kn = k + if reg_var.has_key( k ) : kn = reg_var[k] + region += ";%s:%s" % ( kn, v ) + print region + env['GRASS_REGION'] = region + + # add path to fake GRASS gis library + env['LD_LIBRARY_PATH'] = "%s/lib/qgis/plugins/:%s" % (env['QGIS_PREFIX_PATH'], env['LD_LIBRARY_PATH'] ) + (code, out, err) = self.run( direct_args, env ) + print "code = %s" % code + if code != 0: + self.report( "Direct failed: %s\n%s\n%s" % (" ".join(direct_args), out, err) ) + # TODO: compare native x direct output + + def run( self, args, env=None, input = None, exit_on_error = False ): + cmd = " ".join(args) + print cmd + p = subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, env=env) + com = p.communicate( input ) + p.wait() + + if p.returncode != 0 and exit_on_error: + msg = "Failed:\n" + str(com[0]) + "\n" + str(com[1]) + raise Exception( msg ) + + return (p.returncode, com[0], com[1] ) # return stdout + + # simple run + def srun( self, args ): + return self.run(args, None, None, True)[1] + + def modules(self ): + # R1 - input raster 1 + # RO1 - output raster 1 + modules = [ + "r.slope.aspect elevation=R1 aspect=RO1" + ] + return modules + +if __name__ == '__main__': + test = Test() + test.test() + test.writeReport() diff --git a/src/providers/grass/qgsgrassgislib.cpp b/src/providers/grass/qgsgrassgislib.cpp index d6e77992fc4..960c3a28170 100644 --- a/src/providers/grass/qgsgrassgislib.cpp +++ b/src/providers/grass/qgsgrassgislib.cpp @@ -127,7 +127,14 @@ int GRASS_LIB_EXPORT QgsGrassGisLib::errorRoutine( const char *msg, int fatal ) Q_UNUSED( fatal ); QgsDebugMsg( QString( "error_routine (fatal = %1): %2" ).arg( fatal ).arg( msg ) ); // qFatal does core dump, useful for backtrace - qFatal( "Fatal error: %s", msg ); + if ( fatal ) + { + qFatal( "Fatal: %s", msg ); + } + else + { + qWarning( "Warning: %s", msg ); + } return 1; } @@ -312,7 +319,7 @@ int GRASS_LIB_EXPORT G_set_error_routine( int ( *error_routine )( const char *, typedef int G_warning_type( const char *, ... ); int GRASS_LIB_EXPORT G_warning( const char * msg, ... ) { - //QgsDebugMsg( "Entered" ); + QgsDebugMsg( "Entered" ); G_warning_type* fn = ( G_warning_type* ) cast_to_fptr( QgsGrassGisLib::instance()->resolve( "G_warning" ) ); va_list ap; va_start( ap, msg ); @@ -1067,7 +1074,7 @@ double QgsGrassGisLib::G_database_units_to_meters_factor( void ) case QGis::Feet: return .3048; case QGis::Degrees: - return 0.; // should not be used + return 1.; default: return 0.; }