#!/usr/bin/env python # Copyright (c) 2002,2003,2011 by Intevation GmbH # Authors: # Jan-Oliver Wagner # Andre Heinecke # # This program is free software under the GPL (>=v2) # Read the file COPYING for details. version__ = "$Revision: 1.28 $" # $Source: /home/bricks/source/greater/cvs/greaterrepository/greater-pre-processing/greater-pre-processing.py,v $ # $Id: greater-pre-processing.py,v 1.28 2005-07-18 16:22:28 frank Exp $ import os, sys import os.path import subprocess import support _dir = os.path.join(sys.path[0], os.pardir) for reldir in ("Python", "GREAT-ER-DB", "GREAT-ERModel", "sciparam", "Lib", os.path.join("GREAT-ERModel", "Lib"), "Thuban"): fullname = os.path.join(_dir, reldir) if os.path.isdir(fullname): sys.path.append(fullname) # add ./bin to path to allow easier packaging os.environ["PATH"] = os.path.join(sys.path[0], "bin") + \ ";" + os.environ["PATH"] import wxPython.wx as wx from wxPython.wizard import wxWizard, wxWizardPageSimple, \ wxWizardPageSimple_Chain, EVT_WIZARD_PAGE_CHANGING, \ EVT_WIZARD_PAGE_CHANGED catchment = {} version_str = 'greater-pre-processing 1.2.0' usage_str = 'greater-pre-processing [check|help|run|run-without-cleanup|clean]' greater_pre_proc_path = '"%s"' % os.path.abspath(os.path.dirname(sys.argv[0])) # Static definition of what file contians which objects for the # Upload OUTPUT_FILES="""\ #PATH,NAME,OBJ_TYPE,OBJ_SUB_TYPE # # CATCHBOUND # ./catchbound.dbf,rivernet,CATCHMENT,CATCHBOUND ./catchbound.shp,rivernet,CATCHMENT,CATCHBOUND ./catchbound.shx,rivernet,CATCHMENT,CATCHBOUND # # RIVERNET # ./rivernet.dbf,rivernet,CATCHMENT,RIVERNET ./rivernet.shp,rivernet,CATCHMENT,RIVERNET ./rivernet.shx,rivernet,CATCHMENT,RIVERNET # # DISCHARGES # ./discharges.dbf,rivernet,CATCHMENT,DISCHARGES ./discharges.shp,rivernet,CATCHMENT,DISCHARGES ./discharges.shx,rivernet,CATCHMENT,DISCHARGES # # DISCH_RIVER # ./disch_river.dbf,rivernet,CATCHMENT,DISCHRIVER ./disch_river.shp,rivernet,CATCHMENT,DISCHRIVER ./disch_river.shx,rivernet,CATCHMENT,DISCHRIVER""" def cygwin_path_join(*args): """Convert a Windows path with \ to a cygwin path with /""" if os.name == 'nt': return os.path.join(*args).replace('\\', '/') return os.path.join(*args) def cygwin_call(command, suppress_output=False, extra_env={}, inputdata=None, logfile=None, **kw): """Run command as a subprocess in a cygwin shell on windws and wait until it is finished. The command should be given as a list of strings. But a single string is also accepted """ if os.name == 'nt': # On windows we prepend sh.exe -c to the commandline if isinstance(command, str): cygwin_command = ["sh.exe", "-c"] cygwin_command.append(command) command = cygwin_command else: command = ["sh.exe", "-c"] + command extra_env["CYGWIN"] = "nodosfilewarning" if inputdata is not None: kw["stdin"] = subprocess.PIPE if logfile: kw["stdout"] = kw["stderr"] = open(logfile, "w") elif suppress_output: kw["stdout"] = open(os.devnull, "w") kw["stderr"] = open(os.devnull, "w") env = kw.pop("env", None) if extra_env: if env is None: env = os.environ.copy() env.update(extra_env) try: process = subprocess.Popen(command, env=env, **kw) process.wait() except: import traceback traceback.print_exc() return -1 return 0 def catchment_desc(catchment_file = "catchment.desc"): """Check for file "catchment.desc" and if found check also for correct syntax and completeness. Else, print appropriate error messages. """ try: catchment_desc = open(catchment_file, 'r').readlines() except: raise IOError("Error: Could not find or open file 'catchment.desc'" "This file is required for pre-processing the catchment.") return 1 print "Found 'catchment.desc':" for line in catchment_desc: line = line.rstrip() if len(line) == 0 or line[0] == '#': continue fields = line.split('=') catchment[fields[0]] = fields[1] for k in [ 'ID', 'NAME', 'DESCRIPTION', 'IN-VERSION', 'OUT-VERSION' ]: if not catchment.has_key(k): raise ValueError("Error in catchment.desc: missing %s" % k) return 2 for c in catchment['ID']: if not((c >= 'a' and c <= 'z') or (c >= 'A' and c <= 'Z') or \ (c >= '0' and c <= '9')): raise ValueError(' Error: character "' + c + \ '" not allowed in CATCHEMENTID (only a-zA-Z0-9)') return 3 print ' ID =', catchment['ID'] print ' Name =', catchment['NAME'] print ' Description =', catchment['DESCRIPTION'] print ' Format version src =', catchment['IN-VERSION'] print ' Format version result =', catchment['OUT-VERSION'] print "description complete." def do_check(catch_dir = "."): # check for files .drn, .rna, .dsd, .cbp, .bgd and if found # check also for correct syntax and completeness. # provide appropriate error messages print "Running check ..." if catchment['IN-VERSION'] != '1.0': raise ValueError(' Error: Format version ' + catchment['IN-VERSION'] + \ ' can not be processed \n' ' This check is for version 1.0') return 99 # .drn: digital river network fname = catchment['ID']+'.drn' try: catchment_drn = open(os.path.join(catch_dir, fname), 'r').readlines() except: raise ValueError(" Error: Could not find or open file '" + fname + "'" "\nThis file is required for pre-processing the catchment.") return 1 else: print ' Found ' + fname + ' (digital river network):' # coarse syntax check drn_count = 0 line_count = 0 drn_stretch_ids = [] for line in catchment_drn: line_count = line_count + 1 line = line.rstrip() if len(line) == 0 or line[0] == '#': continue fields = line.split(',') if len(fields) == 1: try: id = int(fields[0]) except: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n StretchID ' + fields[0] + ' not an integer.') return 2 drn_count = drn_count + 1 drn_stretch_ids.append(id) if len(fields) == 2: try: float(fields[0]) float(fields[1]) except: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n coordinates (' + fields[0] + ',' + fields[1] + ') not a float tupel.') return 3 if len(fields) > 2: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n incorrect number of fields (is ' + str(len(fields)) + ', should be 1 (StretchID) or 2 (coords)).') return 4 print ' Total number of stretches: ' + str(drn_count) print ' Syntax OK' # .cbp: catchment boundary polygon fname = catchment['ID']+'.cbp' try: catchment_cbp = open(os.path.join(catch_dir, fname), 'r').readlines() except: raise ValueError("Error: Could not find or open file '" + fname + "'" "\nThis file is required for pre-processing the catchment.") return 1 else: print ' Found ' + fname + ' (catchment boundary polygon):' # coarse syntax check cbp_count = 0 line_count = 0 cbp_first_coord = [] cbp_last_coord = [] for line in catchment_cbp: line_count = line_count + 1 line = line.rstrip() if len(line) == 0 or line[0] == '#': continue fields = line.split(',') if len(fields) == 2: try: float(fields[0]) float(fields[1]) except: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n coordinates (' + fields[0] + ',' + fields[1] + ') not a float tupel.') return 3 cbp_count = cbp_count + 1 if cbp_count == 1: cbp_first_coord = fields cbp_last_coord = fields if len(fields) != 2: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n incorrect number of fields (is ' + str(len(fields)) + \ ', should be or 2 (coordinate pair)).') return 4 if cbp_first_coord != cbp_last_coord: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n first and last coordinate pair must be equal (polygon must be closed).' ' ' + str(cbp_first_coord) + ' != ' + str(cbp_last_coord)) return 5 print ' Total number of boundary coords: ' + str(cbp_count) print ' Syntax OK' # .rna: river network attributes fname = catchment['ID']+'.rna' try: catchment_rna = open(os.path.join(catch_dir, fname), 'r').readlines() except: raise ValueError("Error: Could not find or open file '" + fname + "'" "\nThis file is required for pre-processing the catchment.") return 1 else: print ' Found ' + fname + ' (river network attributes):' # coarse syntax check rna_count = 0 line_count = 0 rna_stretch_ids = [] for line in catchment_rna: line_count = line_count + 1 line = line.rstrip() if len(line) == 0 or line[0] == '#': continue fields = line.split(',') if len(fields) == 9: try: id = int(fields[0]) float(fields[1]) float(fields[2]) if fields[3] != '': float(fields[3]) if fields[4] != '': float(fields[4]) float(fields[5]) if fields[6] != '': float(fields[6]) if fields[7] != '': float(fields[7]) except: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n incorrect data type (should be int,float,float,float,float,float,float,float,string.') return 3 rna_count = rna_count + 1 rna_stretch_ids.append(id) if len(fields) != 9: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n incorrect number of fields (is ' + str(len(fields)) + ', should be 9).') return 4 print ' Total number of stretches: ' + str(rna_count) print ' Syntax OK' # .dsd: discharge site data fname = catchment['ID']+'.dsd' try: catchment_dsd = open(os.path.join(catch_dir, fname), 'r').readlines() except: raise ValueError("Error: Could not find or open file '" + fname + "'" "\nThis file is required for pre-processing the catchment.") return 1 else: print ' Found ' + fname + ' (discharge site data):' # coarse syntax check dsd_count = 0 line_count = 0 for line in catchment_dsd: line_count = line_count + 1 line = line.rstrip() if len(line) == 0 or line[0] == '#': continue fields = line.split(',') if len(fields) == 9: try: int(fields[0]) float(fields[1]) float(fields[2]) int(fields[3]) float(fields[4]) float(fields[5]) int(fields[7]) except: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n incorrect data type (should be int,float,float,int,float,float,string,int,string).') return 3 dsd_count = dsd_count + 1 if len(fields) != 9: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n incorrect number of fields (is ' + str(len(fields)) + ', should be 9).') return 4 if fields[6] not in [ 'PS', 'AS', 'TF', 'AS/TF' ]: raise ValueError( ' Syntax error at line ' + str(line_count) + ':' "\n Type is '" + fields[6] + "' but must be either 'PS', 'AS', 'TF' or 'AS/TF'.") return 6 print ' Total number of discharge sites: ' + str(dsd_count) print ' Syntax OK' # .bgd: background data fname = catchment['ID']+'.bgd' try: catchment_bgd = open(os.path.join(catch_dir, fname), 'r').readlines() except: raise ValueError("Error: Could not find or open file '" + fname + "'" "\nThis file is required for pre-processing the catchment.") return 1 else: print ' Found ' + fname + ' (background data):' # coarse syntax check bgd_count = 0 line_count = 0 for line in catchment_bgd: line_count = line_count + 1 line = line.rstrip() if len(line) == 0 or line[0] == '#': continue fields = line.split(',') if len(fields) == 5: bgd_count = bgd_count + 1 if len(fields) != 5: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n incorrect number of fields (is ' + str(len(fields)) + ', should be 5).') return 4 if fields[2] not in [ '', 'point', 'polygon', 'line', 'shape', 'image', 'grid' ]: raise ValueError(' Syntax error at line ' + str(line_count) + ':' "\n Type is '" + fields[2] + "' but must be one of 'point', 'polygon', 'line', 'shape', 'image', 'grid' or left empty.") return 6 if fields[4] not in [ 'yes', 'no' ]: raise ValueError(' Syntax error at line ' + str(line_count) + ':' "\n Ctch_fl is '" + fields[4] + "' but must be either 'yes' or 'no'.") return 6 print ' Total number of background elements : ' + str(bgd_count) print ' Syntax OK' # .lks: lakes fname = catchment['ID']+'.lks' try: catchment_lks = open(os.path.join(catch_dir, fname), 'r').readlines() except: raise ValueError("Error: Could not find or open file '" + fname + "'" "\nThis file is required for pre-processing the catchment.") return 1 else: print ' Found ' + fname + ' (lakes):' # coarse syntax check lks_count = 0 line_count = 0 for line in catchment_lks: line_count = line_count + 1 line = line.rstrip() if len(line) == 0 or line[0] == '#': continue try: int(line) except: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n entry (' + line + ') not an integer.') return 3 lks_count = lks_count + 1 print ' Total number of lakes: ' + str(lks_count) print ' Syntax OK' # .pic: pictures fname = catchment['ID']+'.pic' try: catchment_pic = open(os.path.join(catch_dir, fname), 'r').readlines() except: raise ValueError("Error: Could not find or open file '" + fname + "'" "\nThis file is required for pre-processing the catchment.") return 1 else: print ' Found ' + fname + ' (pictures):' # coarse syntax check pic_count = 0 line_count = 0 for line in catchment_pic: line_count = line_count + 1 line = line.rstrip() if len(line) == 0 or line[0] == '#': continue fields = line.split(',') if len(fields) == 5: try: int(fields[0]) float(fields[1]) float(fields[2]) except: raise ValueError(' Syntax error at line ' + str(line_count) + ':' '\n incorrect data type (should be int,float,float,string,string).') return 3 pic_count = pic_count + 1 if len(fields) != 5: raise ValueError( ' Syntax error at line ' + str(line_count) + ':' '\n incorrect number of fields (is ' + str(len(fields)) + ', should be 5).') return 4 print ' Total number of pictures: ' + str(pic_count) print ' Syntax OK' error_count = 0 for id in rna_stretch_ids: if id in drn_stretch_ids: continue raise ValueError('Semantic Error: StretchID %d occurs in .rna file, but does not '\ 'appear in .drn file' % id) error_count += 1 for id in drn_stretch_ids: if id in rna_stretch_ids: continue raise ValueError('Semantic Error: StretchID %d occurs in .drn file, but does not '\ 'appear in .rna file' % id) error_count += 1 if error_count > 0: return 5 print 'Check on syntax successfully complete' return 0 def do_run(): yield(1) if catchment['OUT-VERSION'] != '1.0' and catchment['OUT-VERSION'] != '2.0': raise ValueError(' Error: Format version ' + catchment['OUT-VERSION'] + \ ' can not be created' '\n Supported versions are 1.0 and 2.0') # execute the pre-processing if do_check() != 0: print 'Not executing pre-processing due to error' yield(5) print 'Running pre-processing ...' print ' Removing tmp-files and old log-file (' +catchment['ID'] + '.log ...' cmds = [ 'rm -f *.tmp ' + catchment['ID'] + '.log' ] # for cmd in cmds: # if cygwin_call(cmd) != 0: # raise OSError(' Error executing ' + cmd) print ' done.' yield(7) print ' Creating discharges.shp ...' cmds = [ 'gawk -f ' + cygwin_path_join(greater_pre_proc_path, 'awk', 'dsd2gen.awk') + ' < ' + catchment['ID'] + \ '.dsd > discharges.gen.tmp',\ 'gen2shp discharges points < discharges.gen.tmp'] for cmd in cmds: if cygwin_call(cmd) != 0: raise OSError(' Error executing ' + cmd) print ' done.' yield(10) print ' Creating rivernet.shp ...' cmds = [ 'gawk -v LOG=' + catchment['ID'] + '.log -f ' + \ cygwin_path_join(greater_pre_proc_path, 'awk','drn2gen.awk') +' < ' + \ catchment['ID'] + '.drn > rivernet.gen.tmp',\ 'gen2shp rivernet lines < rivernet.gen.tmp'] for cmd in cmds: if cygwin_call(cmd) != 0: raise OSError(' Error executing ' + cmd) print ' done.' yield(15) print ' Creating disch_river.shp ...' cmds = [ 'gawk -f ' + cygwin_path_join(greater_pre_proc_path, 'awk', 'drn_dsd2gen.awk') + " " + catchment['ID'] + '.drn ' + \ catchment['ID'] + '.dsd > disch_river.gen.tmp',\ 'gen2shp disch_river lines < disch_river.gen.tmp'] for cmd in cmds: if cygwin_call(cmd) != 0: raise OSError(' Error executing ' + cmd) print ' done.' yield(20) print ' Creating catchbound.shp ...' cmds = [ 'sed -e "s/D/E/g" < ' + catchment['ID'] + \ '.cbp | gawk -f ' + cygwin_path_join(greater_pre_proc_path, 'awk', 'cbp2gen.awk') + ' > catchbound.gen.tmp',\ 'gen2shp catchbound polygons < catchbound.gen.tmp',\ 'echo "#catchbound,Name" > catchbound.att.tmp',\ 'echo "1,' + catchment['NAME'] + '" >> catchbound.att.tmp',\ 'txt2dbf -d , -I11 -C100 catchbound.att.tmp catchbound.dbf',\ ] for cmd in cmds: if cygwin_call(cmd) != 0: raise OSError(' Error executing ' + cmd) print ' done.' yield(30) print ' Creating attribute files rivclass.dbf, wwtp.dbf, disch.dbf ' \ 'and river.dbf ...' cmds = [ 'LC_ALL=C gawk -f ' + cygwin_path_join(greater_pre_proc_path, 'awk', 'topology.awk') +" "+ catchment['ID'] + '.drn', \ 'LC_COLLATE=C sort -k1b,1 to_id.tmp > to_id2.tmp', \ 'LC_COLLATE=C sort -k1b,1 from_id.tmp > from_id2.tmp', \ r'''join to_id2.tmp from_id2.tmp | cut -d " " -f 2,3 | sort -n | sed -e "s/ /,/" > f_t.tmp''', r'''gawk --source='BEGIN { FS="," } { printf("%s,%s\n", $2, $1) }' f_t.tmp | sort -n > t_f.tmp''', 'echo from-tos > f_ts.tmp', 'gawk -f ' + greater_pre_proc_path + \ '/awk/joinup.awk f_t.tmp >> f_ts.tmp', 'echo to-froms > t_fs.tmp', 'gawk -f ' + cygwin_path_join(greater_pre_proc_path, 'awk', 'joinup.awk') + ' t_f.tmp >> t_fs.tmp', 'sed -e "s/$/,/" < ' + catchment['ID'] + '.dsd > ' + \ catchment['ID'] + '.dsd.tmp', 'gawk -v LOG=' + catchment['ID'] + '.log -v OUTVERSION='+ \ catchment['OUT-VERSION'] + ' -f ' + \ cygwin_path_join(greater_pre_proc_path, 'awk', 'generateAttTables.awk') + " " +\ catchment['ID'] + '.rna ' + catchment['ID'] + '.dsd.tmp ' + \ catchment['ID'] + '.lks f_ts.tmp t_fs.tmp' ] if catchment['OUT-VERSION'] == '1.0': cmds.append('txt2dbf -d , -I10 -I2 -I1 -I10 -I10 -I5 -R12.5 -R12.5 ' '-R12.5 -R12.5 -R20.10 -R12.5 -R12.5 -C60 river.att ' 'river.dbf 2>> ' + catchment['ID'] + '.log') elif catchment['OUT-VERSION'] == '2.0': # add down1,down2 to river.att if os.name == "nt": executable_path = sys.executable.replace("\\", "/") else: executable_path = sys.executable cmds.append('"%s" %s > river2.att' % ( executable_path, cygwin_path_join(greater_pre_proc_path, 'add-downsegments.py')) ) # two additional -I10 for down1, down2 cmds.append('txt2dbf -d , -I10 -I2 -I1 -I10 -I10 -I10 -I10 -I5 -R12.5 ' '-R12.5 -R12.5 -R12.5 -R20.10 -R12.5 -R12.5 -C60 ' 'river2.att river.dbf 2>> ' + catchment['ID'] + '.log') cmds.append('txt2dbf -d , -I4 -I1 -I1 -R10.5 -R10.5 -R10.5 -R10.5 -R10.5 ' '-R10.5 -R10.5 -R10.5 -R10.5 -R10.5 -R10.5 -R10.5 -R10.5 ' '-R10.5 -R10.5 -R10.5 -R10.5 -R10.5 -v rivclass.att ' 'rivclass.dbf 2>> ' + catchment['ID'] + '.log') cmds.append('txt2dbf -d , -I4 -I1 -I1 -I1 -R10.5 -R10.5 -R10.5 -R10.5 ' + \ '-R10.5 -R10.5 -R10.5 -R10.5 -I10 -R10.5 -R10.5 -R10.5 ' + \ '-R10.5 -R10.5 -R10.5 -R10.5 -I1 -R10.5 -R10.5 -R10.5 ' + \ '-R10.5 -R10.5 -C40 wwtp.att wwtp.dbf 2>> ' + \ catchment['ID'] + '.log') cmds.append('txt2dbf -d , -I10 -I10 -I10 -I10 -R20.10 -R20.10 -R20.10 ' + \ '-R20.10 -R20.10 ' + \ '-R10.5 -I10 -R10.5 -C40 disch.att ' + \ 'disch.dbf 2>> ' + catchment['ID'] + '.log') cmdno = 0 for cmd in cmds: if cygwin_call(cmd) != 0: raise OSError(' Error executing ' + cmd) yield int(round(30+ 40 * float(cmdno) / len(cmds))) cmdno += 1 print ' done.' if catchment['OUT-VERSION'] == '2.0': print ' Checking for circles in the river network topology ...' river_att = open('river2.att', 'r').readlines() table = [] for line in river_att: if len(line) == 0 or line[0] == '#': continue attributes = line.split(',') table.append([ int(attributes[0]), int(attributes[1]), int(attributes[3]), int(attributes[4]), int(attributes[5]), int(attributes[6]) ]) result = support.check_for_circle(table) if isinstance(result, list): raise ValueError( " Error: Circle detected: %s" % result) elif result is None: raise ValueError( " Error: Circle detection routine failed") else: print ' [ Check for circles only available for OUT-VERSION >= 2.0 ]' yield(75) print ' Creating pics.shp ...' cmds = [ 'gawk -f ' + cygwin_path_join(greater_pre_proc_path, 'awk', 'pic2gen.awk') + ' < ' + catchment['ID'] + '.pic > pic.gen.tmp',\ 'gawk -f ' + cygwin_path_join(greater_pre_proc_path, 'awk', 'pic2att.awk') +' < ' + catchment['ID'] + '.pic > pic.att.tmp', \ 'gen2shp pics points < pic.gen.tmp', 'dbf2txt pics.dbf | sed -e "s/\t//g" > pics.txt.tmp', 'paste -d , pics.txt.tmp pic.att.tmp > pics.txt2.tmp', 'rm -f pics.dbf', 'txt2dbf -d , -I11 -I4 -C20 -C100 pics.txt2.tmp pics.dbf ' + \ '2>> ' + catchment['ID'] + '.log'] for cmd in cmds: if cygwin_call(cmd) != 0: raise OSError( ' Error executing ' + cmd) print ' done.' yield(80) if catchment['OUT-VERSION'] == '1.0': print ' Creating backgroundlst.dbf ...' cmds = [ 'txt2dbf -v -d , -C30 -C25 -C20 -C25 -C8 ' + \ catchment['ID'] + '.bgd backgroundlst.dbf 2>> ' + \ catchment['ID'] + '.log'] for cmd in cmds: if cygwin_call(cmd) != 0: raise OSError(' Error executing ' + cmd) print ' done.' yield(90) print ' Creating Thuban session file (' + catchment['ID'] + '.session) ...' cmds = [ 'cp ' + cygwin_path_join(greater_pre_proc_path, "catchment.thuban") + ' .'] for cmd in cmds: if cygwin_call(cmd) != 0: raise OSError( ' Error executing ' + cmd) print ' done.' yield(95) print ' Cleaning up ...' cmds = [ 'rm -f *.tmp' ] for cmd in cmds: if cygwin_call(cmd) != 0: raise OSError( ' Error executing ' + cmd) print ' done.' print 'Pre-processing successfully finished' yield(100) def do_clean(): print 'Cleaning up ...' cmds = [ 'rm -f *.tmp ' + catchment['ID'] + '.log', 'rm -f catchbound.* discharges.* rivernet.* catchment.thuban', 'rm -f disch_river.* disch.att disch.dbf backgroundlst.dbf', 'rm -f rivclass.att rivclass.dbf', 'rm -f river.att river.dbf river2.att wwtp.att wwtp.dbf pics.*' ] for cmd in cmds: if cygwin_call(cmd) != 0: print ' Error executing ' + cmd return 2 print 'done.' def usage(): # This is the old console version usage print usage_str print ' help print this text' print ' check test for completeness and correct syntax of source files' print ' run execute catchment pre-processing' print ' run-without-cleanup execute catchment pre-processing not removing' print ' temporary files' print ' clean remove all temporary and all results files' # Texts intro = """\ This wizard will guide you through the preprocessing of catchment data files for the GREAT-ER Software. This converts catchments from Format 1.0 to Format 2.0 For more information about preprocessing please refer to the GREAT-ER-Preprocessing Manual. """ synok = """\ All files where found and the syntax appears to be correct. Press Finish to start the preprocessing.""" # # GUI # def makePageTitle(wizPg, title): """Create the page title on the wizard page wizPg. This function was taken directly from the wxPython demo. """ sizer = wx.wxBoxSizer(wx.wxVERTICAL) wizPg.SetSizer(sizer) title = wx.wxStaticText(wizPg, -1, title) title.SetFont(wx.wxFont(18, wx.wxSWISS, wx.wxNORMAL, wx.wxBOLD)) sizer.AddWindow(title, 0, wx.wxALIGN_CENTRE|wx.wxALL, 5) sizer.AddWindow(wx.wxStaticLine(wizPg, -1), 0, wx.wxEXPAND|wx.wxALL, 5) return sizer class TitledPage(wxWizardPageSimple): """Base class for wizard pages with a title. Taken directly from the wxPython demo. """ def __init__(self, parent, title): wxWizardPageSimple.__init__(self, parent) self.sizer = makePageTitle(self, title) class SimpleTextPage(TitledPage): """A simple page with a title and some static text""" def __init__(self, parent, title, text): TitledPage.__init__(self, parent, title) self.text = wx.wxStaticText(self, -1, text) self.sizer.Add(self.text) def has_cfile(cdir): """ Returns true if the directory cdir contains a catchment.desc""" return os.path.isfile(os.path.join(cdir), "catchment.desc") class CatchmentPage(TitledPage): """Wizard page for the catchment parameters""" def __init__(self, parent): TitledPage.__init__(self, parent, "Catchment Configuration") if not hasattr(self, "catchment_dir"): dialog = wx.wxDirDialog( None, "Please select the catchment directory.", name="Select catchment") if dialog.ShowModal() == wx.wxID_OK: self.catchment_dir = dialog.GetPath() else: wx.wxMessageBox("You have to select a directory.", "Error!", wx.wxICON_ERROR|wx.wxOK) sys.exit(1) default_id=None default_name=None default_description=None grid = wx.wxFlexGridSizer(5, 2, 0, 0) if not os.path.isfile(os.path.join(self.catchment_dir, "catchment.desc")): grid.Add(wx.wxStaticText(self, -1, "File catchment.desc"), 0, wx.wxEXPAND|wx.wxALL, 5) grid.Add(wx.wxStaticText(self, -1, "not found."), 0, wx.wxEXPAND|wx.wxALL, 5) else: grid.Add(wx.wxStaticText(self, -1, "File catchment.desc"), 0, wx.wxEXPAND|wx.wxALL, 5) grid.Add(wx.wxStaticText(self, -1, "found."), 1, wx.wxEXPAND|wx.wxALL, 5) try: catchment = {} with open(os.path.join(self.catchment_dir, "catchment.desc"), "r") as fptr: for line in fptr: line = line.rstrip() if len(line) == 0 or line[0] == '#': continue fields = line.split('=') catchment[fields[0]] = fields[1] print catchment default_id = catchment["ID"] default_name = catchment["NAME"] default_description = catchment["DESCRIPTION"] except: pass self.sizer.Add(grid, 0, wx.wxEXPAND|wx.wxALL,5) grid.Add(wx.wxStaticText(self, -1, "Selected Directory:"), 0, wx.wxEXPAND|wx.wxALL, 5) grid.Add(wx.wxStaticText(self, -1, self.catchment_dir), 1, wx.wxEXPAND|wx.wxALL, 5) for varname, title, flags in [("text_ID", "Catchment ID", 0), ("text_NAME", "Catchment Name", 0), ("text_DESCRIPTION", "Description", 0)]: text = wx.wxStaticText(self, -1, title) grid.Add(text, 0, wx.wxEXPAND|wx.wxALL, 5) ctrl = wx.wxTextCtrl(self, -1, style=flags, size=wx.wxSize(150,wx.wxDefaultSize.GetHeight())) grid.Add(ctrl, 1, wx.wxEXPAND|wx.wxALL, 5) setattr(self, varname, ctrl) if default_id: self.text_ID.WriteText(default_id) if default_name: self.text_NAME.WriteText(default_name) if default_description: self.text_DESCRIPTION.WriteText(default_description) class PreProcessingApp(wx.wxApp): """Greater PreProcessingApplication Class""" def OnInit(self): """Read create the wizard as the main window """ wx.wxInitAllImageHandlers() bitmap_filename = os.path.join( os.path.abspath(os.path.dirname(sys.argv[0])), "river_aire.png") try: bitmap = wx.wxImage(bitmap_filename).ConvertToBitmap() except: bitmap = wx.wxNullBitmap wizard = self.wizard = wxWizard(wx.NULL, -1, "GREAT-ER Preprocessing", bitmap) intro_page = SimpleTextPage(wizard, "Welcome", intro) self.intro_page = intro_page wizard.FitToPage(intro_page) self.catchment_page = CatchmentPage(wizard) self.convert_page = SimpleTextPage(wizard, "Syntax check completed.", synok) wxWizardPageSimple_Chain(intro_page, self.catchment_page) wxWizardPageSimple_Chain(self.catchment_page, self.convert_page) EVT_WIZARD_PAGE_CHANGED(self, wizard.GetId(), self.OnPageChanged) EVT_WIZARD_PAGE_CHANGING(self, wizard.GetId(), self.OnPageChanging) return True def OnPageChanged(self, event): """Handler for the wizard's PAGE_CHANGED events. If the new page has an Activate method. Call it. """ meth = getattr(event.GetPage(), "Activate", None) if meth is not None: meth() def OnPageChanging(self, event): """Handler for the wizard's PAGE_CHANGING event. If the old page is the catchment_page and direction is forward (next), save the catchment and check the values of the config by calling check_config. If the upload is not successful, cancel the event so that page is not changed. """ if (event.GetPage() is self.catchment_page and event.GetDirection() == True): desc_file = write_desc(self.catchment_page) try: catchment_desc(desc_file) do_check(self.catchment_page.catchment_dir) except: catchment_error = str(sys.exc_info()[1]) wx.wxMessageBox(catchment_error, "Error!", wx.wxICON_ERROR|wx.wxOK) event.Veto() elif (event.GetPage() is self.convert_page and event.GetDirection() == True): if not self.DoProcess(): event.Veto() else: wx.wxMessageBox("The catchment was successfully processed.\n" "You can upload it now by using GREAT-ER Upload.", "Finished.", wx.wxOK | wx.wxICON_INFORMATION) def DoProcess(self): """Do the preprocessing.""" dialog = wx.wxProgressDialog("Preprocessing Catchment", "Preprocessing Catchment", 100, self.wizard, wx.wxPD_CAN_ABORT | wx.wxPD_AUTO_HIDE | wx.wxPD_ELAPSED_TIME | wx.wxPD_ESTIMATED_TIME | wx.wxPD_REMAINING_TIME) try: try: oldcwd = os.getcwd() os.chdir(self.catchment_page.catchment_dir) print "Changing to working direcotory : ", self.catchment_page.catchment_dir for progress in do_run(): if not dialog.Update(progress): os.chdir(oldcwd) return False write_upload_desc(self.catchment_page) return True except: wx.wxMessageBox("An error occurred:\n%s" % str(sys.exc_info()[1]), "Error preprocessing Catchment.\n" "Please make sure that you can write files in the catchment directory.") finally: os.chdir(oldcwd) dialog.Destroy() def RunWizard(self): """Run the wizard. The return value is the return value of the wizard's RunWizard method. """ return self.wizard.RunWizard(self.intro_page) def write_upload_desc(catchment_page): """ Tages a CatchmentPage and writes the description for uploading into the catchments.desc """ cdir = catchment_page.catchment_dir upfile = os.path.join(cdir, "upload.list") with open(upfile, "w") as fptr: fptr.write(OUTPUT_FILES) def write_desc(catchment_page): """ Tages a CatchmentPage and writes the description into the catchment.desc Returns the Filename of the description file as absolute path """ cdir = catchment_page.catchment_dir cfile = os.path.join(cdir, "catchment.desc") with open(cfile, "w") as fptr: fptr.write("ID=%s\n" % catchment_page.text_ID.GetValue()) fptr.write("NAME=%s\n" % catchment_page.text_NAME.GetValue()) fptr.write("DESCRIPTION=%s\n" % catchment_page.text_DESCRIPTION.GetValue()) fptr.write("IN-VERSION=%s\n" % "1.0") fptr.write("OUT-VERSION=%s\n" % "2.0") fptr.write("GISFILELIST=./upload.list\n") fptr.write("STRETCH_TAB=./river2.att\n") fptr.write("DISCH_TAB=./disch.att\n") return cfile if __name__ == '__main__': # Run the wizard. If the wizard is cancelled, exit with status 1. app = PreProcessingApp(0) success = app.RunWizard() if not success: sys.exit(1) # Old console version main #if __name__ == '__main__': # import sys # # print version_str # print # # if catchment_desc(): # print '\nusage:', usage_str # sys.exit(1) # # print # # if os.environ.has_key('GREATER_PRE_PROC') == 0: # greater_pre_proc_path = os.path.abspath(os.path.dirname(sys.argv[0])) # if not os.path.exists(os.path.join( # greater_pre_proc_path,'awk','joinup.awk')): # print 'Error: environment variable GREATER_PRE_PROC not set' # sys.exit(2) # else: # greater_pre_proc_path = os.environ['GREATER_PRE_PROC'] # # # if len(sys.argv) == 2: # if sys.argv[1] == 'check': # do_check() # if sys.argv[1] == 'run': # do_run() # if sys.argv[1] == 'run-without-cleanup': # do_run() # if sys.argv[1] == 'clean': # do_clean() # if sys.argv[1] == 'help': # usage() # else: # print 'usage:', usage_str