Skip to content

Commit 38232a0

Browse files
committedDec 21, 2012
GRASS Direct test script initial work
1 parent 05d79f5 commit 38232a0

File tree

2 files changed

+167
-3
lines changed

2 files changed

+167
-3
lines changed
 

‎src/plugins/grass/qgis_grass_test.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
***************************************************************************
6+
GRASS Direct test - to be run in GRASS shell
7+
8+
- collects list of raster layers
9+
- exports GRASS layers on low resolution to temporary GeoTIFFs
10+
- runs GRASS modules in standard and direct mode and compares results
11+
- writes out report
12+
***************************************************************************
13+
"""
14+
__author__ = 'Radim Blazek'
15+
__date__ = 'December 2012'
16+
__copyright__ = '(C) 2012, Radim Blazek'
17+
__revision__ = '$Format:%H$'
18+
19+
import os, sys, glob, subprocess, time, re
20+
21+
class Test:
22+
def __init__(self):
23+
if not os.environ.has_key("GISBASE") or not os.environ.has_key("GISRC"):
24+
print "This script must be run in GRASS shell."
25+
sys.exit ( 1 )
26+
27+
if not os.environ.has_key("QGIS_PREFIX_PATH"):
28+
print "QGIS_PREFIX_PATH environment variable not set."
29+
sys.exit ( 1 )
30+
31+
self.size = 10
32+
self.reportStr = ""
33+
pass
34+
35+
# add message to HTML report
36+
def report( self, msg ):
37+
self.reportStr += msg + "\n"
38+
39+
def writeReport( self ):
40+
print self.reportStr
41+
42+
def test(self):
43+
print "GRASS Direct test"
44+
45+
46+
47+
tmp_dir = os.path.abspath( "qgis-grass-test-%s" % time.strftime('%y%m%d-%H%M%S') )
48+
tmp_dir = os.path.abspath( "qgis-grass-test-debug" ) # debug
49+
print "Output will be written to %s" % tmp_dir
50+
51+
files_dir = "%s/tif" % tmp_dir
52+
#os.makedirs( files_dir )
53+
54+
# get list of raster layers
55+
print "Getting list of rasters ..."
56+
rasters = self.srun( ["g.mlist", "type=rast"] ).splitlines()
57+
max_rasters = 1
58+
print "%s rasters found, using first %s" % ( len( rasters), max_rasters )
59+
rasters = rasters[0:1]
60+
61+
print "Exporting rasters"
62+
for raster in rasters:
63+
print raster
64+
output = "%s/%s.tif" % ( files_dir, raster )
65+
self.srun( ["g.region", "rast=%s" % raster, "cols=%s" % self.size, "rows=%s" % self.size ] )
66+
self.srun( ["r.out.gdal", "input=%s" % raster, "output=%s" % output] )
67+
68+
# run modules
69+
count = 0
70+
for module in self.modules():
71+
for raster in rasters:
72+
module = re.sub(" *", " ", module )
73+
module_name = module.split(" ")[0]
74+
# --- native ---
75+
self.srun( ["g.region", "rast=%s" % raster, "cols=%s" % self.size, "rows=%s" % self.size ] )
76+
output = "qgistest1"
77+
# clean old
78+
self.srun( ["g.remove", "-f", "rast=%s" % output ] )
79+
# substitute rasters
80+
native_args = module.replace("R1",raster).replace("RO1",output).split(" ");
81+
(code, out, err) = self.run( native_args )
82+
if code != 0:
83+
self.report( "Native failed: %s" % " ".join(native_args) )
84+
# export
85+
native_output_file = "%s/%s-%s-native.tif" % ( files_dir, module_name, raster )
86+
self.srun( ["r.out.gdal", "input=%s" % output, "output=%s" % native_output_file] )
87+
self.srun( ["g.remove", "-f", "rast=%s" % output ] )
88+
89+
# --- direct ---
90+
direct_input_file = "%s/%s.tif" % ( files_dir, raster )
91+
direct_output_file = "%s/%s-%s-direct.tif" % ( files_dir, module_name, raster )
92+
93+
# substitute rasters
94+
direct_args = module.replace("R1",direct_input_file).replace("RO1",direct_output_file).split(" ");
95+
env = os.environ
96+
97+
# CRS
98+
proj = self.srun( ["g.proj", "-j"] )
99+
longlat = True if proj.find("+proj=longlat") != -1 else False
100+
proj = proj.splitlines()
101+
proj = " ".join ( proj )
102+
print proj
103+
env['QGIS_GRASS_CRS'] = proj
104+
105+
# set GRASS region as environment variable
106+
reg = self.srun( ["g.region", "-g"] )
107+
reg_dict = dict(item.split("=") for item in reg.splitlines())
108+
reg_var= { 'n': 'north', 's': 'south', 'e': 'east', 'w':'west', 'nsres': 'n-s resol', 'ewres': 'e-w resol' }
109+
if longlat:
110+
region = "proj:3;zone:-1" # longlat
111+
else:
112+
region = "proj:99;zone:-1" # other projection
113+
for k,v in reg_dict.iteritems():
114+
if k == 'cells': continue
115+
kn = k
116+
if reg_var.has_key( k ) : kn = reg_var[k]
117+
region += ";%s:%s" % ( kn, v )
118+
print region
119+
env['GRASS_REGION'] = region
120+
121+
# add path to fake GRASS gis library
122+
env['LD_LIBRARY_PATH'] = "%s/lib/qgis/plugins/:%s" % (env['QGIS_PREFIX_PATH'], env['LD_LIBRARY_PATH'] )
123+
(code, out, err) = self.run( direct_args, env )
124+
print "code = %s" % code
125+
if code != 0:
126+
self.report( "Direct failed: %s\n%s\n%s" % (" ".join(direct_args), out, err) )
127+
# TODO: compare native x direct output
128+
129+
def run( self, args, env=None, input = None, exit_on_error = False ):
130+
cmd = " ".join(args)
131+
print cmd
132+
p = subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, env=env)
133+
com = p.communicate( input )
134+
p.wait()
135+
136+
if p.returncode != 0 and exit_on_error:
137+
msg = "Failed:\n" + str(com[0]) + "\n" + str(com[1])
138+
raise Exception( msg )
139+
140+
return (p.returncode, com[0], com[1] ) # return stdout
141+
142+
# simple run
143+
def srun( self, args ):
144+
return self.run(args, None, None, True)[1]
145+
146+
def modules(self ):
147+
# R1 - input raster 1
148+
# RO1 - output raster 1
149+
modules = [
150+
"r.slope.aspect elevation=R1 aspect=RO1"
151+
]
152+
return modules
153+
154+
if __name__ == '__main__':
155+
test = Test()
156+
test.test()
157+
test.writeReport()

‎src/providers/grass/qgsgrassgislib.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,14 @@ int GRASS_LIB_EXPORT QgsGrassGisLib::errorRoutine( const char *msg, int fatal )
127127
Q_UNUSED( fatal );
128128
QgsDebugMsg( QString( "error_routine (fatal = %1): %2" ).arg( fatal ).arg( msg ) );
129129
// qFatal does core dump, useful for backtrace
130-
qFatal( "Fatal error: %s", msg );
130+
if ( fatal )
131+
{
132+
qFatal( "Fatal: %s", msg );
133+
}
134+
else
135+
{
136+
qWarning( "Warning: %s", msg );
137+
}
131138
return 1;
132139
}
133140

@@ -312,7 +319,7 @@ int GRASS_LIB_EXPORT G_set_error_routine( int ( *error_routine )( const char *,
312319
typedef int G_warning_type( const char *, ... );
313320
int GRASS_LIB_EXPORT G_warning( const char * msg, ... )
314321
{
315-
//QgsDebugMsg( "Entered" );
322+
QgsDebugMsg( "Entered" );
316323
G_warning_type* fn = ( G_warning_type* ) cast_to_fptr( QgsGrassGisLib::instance()->resolve( "G_warning" ) );
317324
va_list ap;
318325
va_start( ap, msg );
@@ -1067,7 +1074,7 @@ double QgsGrassGisLib::G_database_units_to_meters_factor( void )
10671074
case QGis::Feet:
10681075
return .3048;
10691076
case QGis::Degrees:
1070-
return 0.; // should not be used
1077+
return 1.;
10711078
default:
10721079
return 0.;
10731080
}

0 commit comments

Comments
 (0)
Please sign in to comment.