[GRASS-SVN] r37049 - grass/trunk/scripts/r.in.wms

svn_grass at osgeo.org svn_grass at osgeo.org
Fri May 8 09:41:23 EDT 2009


Author: martinl
Date: 2009-05-08 09:41:22 -0400 (Fri, 08 May 2009)
New Revision: 37049

Added:
   grass/trunk/scripts/r.in.wms/r.in.gdalwarp.py
   grass/trunk/scripts/r.in.wms/r.in.wms.py
   grass/trunk/scripts/r.in.wms/wms_download.py
   grass/trunk/scripts/r.in.wms/wms_request.py
Removed:
   grass/trunk/scripts/r.in.wms/r.in.wms
   grass/trunk/scripts/r.in.wms/wms.download
   grass/trunk/scripts/r.in.wms/wms.request
Modified:
   grass/trunk/scripts/r.in.wms/Makefile
   grass/trunk/scripts/r.in.wms/r.in.gdalwarp
Log:
r.in.wms pythonized (first stage) - deeper code reorganization needed


Modified: grass/trunk/scripts/r.in.wms/Makefile
===================================================================
--- grass/trunk/scripts/r.in.wms/Makefile	2009-05-08 07:54:06 UTC (rev 37048)
+++ grass/trunk/scripts/r.in.wms/Makefile	2009-05-08 13:41:22 UTC (rev 37049)
@@ -4,7 +4,7 @@
 
 include $(MODULE_TOPDIR)/include/Make/Script.make
 
-SRCFILES = r.in.gdalwarp wms.request wms.download
+SRCFILES = r.in.gdalwarp.py wms_request.py wms_download.py
 DSTFILES := $(patsubst %,$(ETC)/r.in.wms/%,$(SRCFILES))
 
 default: script

Modified: grass/trunk/scripts/r.in.wms/r.in.gdalwarp
===================================================================
--- grass/trunk/scripts/r.in.wms/r.in.gdalwarp	2009-05-08 07:54:06 UTC (rev 37048)
+++ grass/trunk/scripts/r.in.wms/r.in.gdalwarp	2009-05-08 13:41:22 UTC (rev 37049)
@@ -248,7 +248,9 @@
 	g.message -d message="channel list: [$CHANNEL_LIST]"
 
 	# Get a list of suffixes:
+	echo $CHANNEL_LIST
 	CHANNEL_SUFFIXES=`echo "$CHANNEL_LIST" | sed "s/^${MAP}/sfx=/"`
+	echo $CHANNEL_SUFFIXES
 	# test for single band data
 	if [ "$CHANNEL_SUFFIXES" = 'sfx=' ] ; then
 	   CHANNEL_SUFFIXES=""
@@ -256,11 +258,14 @@
 	g.message -d message="channel suffixes: [$CHANNEL_SUFFIXES]"
 
 	# Add to the list of all suffixes:
+	echo $SUFFIXES
 	SUFFIXES=`echo "$SUFFIXES
 $CHANNEL_SUFFIXES" | sort -u`
 
 	IFS="$defaultIFS"
+	echo $CHANNEL_SUFFIXES
 	for SUFFIX in $CHANNEL_SUFFIXES ; do
+	    echo 'x', $sfx
 		eval "$SUFFIX"
 
 		# skip if only one band ($sfx is empty)
@@ -343,6 +348,7 @@
 		  g.rename rast="${GIS_OPT_OUTPUT}_tile_0${sfx}","${GIS_OPT_OUTPUT}${sfx}"
 	    done
 	else  # single-band, single-tile
+	    echo 'x', $sfx
 	    #Rename tile 0 to be the output
 	    GRASS_VERBOSE=1 \
 	      g.rename rast="${GIS_OPT_OUTPUT}_tile_0${sfx}","${GIS_OPT_OUTPUT}${sfx}" --quiet
@@ -418,6 +424,7 @@
 	fi
 done
 
+echo $COLORS
 # Make a composite image if asked for and colors exist
 if [ $COLORS -eq 3 ] && [ $GIS_FLAG_C -eq 1 ] ; then
 	g.message "Building Color Image" 

Added: grass/trunk/scripts/r.in.wms/r.in.gdalwarp.py
===================================================================
--- grass/trunk/scripts/r.in.wms/r.in.gdalwarp.py	                        (rev 0)
+++ grass/trunk/scripts/r.in.wms/r.in.gdalwarp.py	2009-05-08 13:41:22 UTC (rev 37049)
@@ -0,0 +1,418 @@
+#!/usr/bin/env python
+
+############################################################################
+#
+# MODULE:       r.in.gdalwarp
+#
+# AUTHOR(S):    Cedric Shock, 2006
+#               Pythonized by Martin Landa <landa.martin gmail.com>, 2009
+#
+# PURPOSE:      To warp and import data
+#               (based on Bash script by Cedric Shock)
+#
+# COPYRIGHT:    (C) 2009 Martin Landa, and GRASS development team
+#
+#               This program is free software under the GNU General
+#               Public License (>=v2). Read the file COPYING that
+#               comes with GRASS for details.
+#
+#############################################################################
+
+#%module
+#% description: Warps and imports GDAL supported raster file complete with correct NULL values
+#% keywords: raster, rotate, reproject
+#%end
+#%flag
+#% key: p
+#% description: Don't reproject the data, just patch it
+#%end
+#%flag
+#% key: e
+#% description: Extend location extents based on new dataset
+#%end
+#%flag
+#% key: c
+#% description: Make color composite image if possible
+#%end
+#%flag
+#% key: k
+#% description: Keep band numbers instead of using band color names
+#%end
+#%option
+#% key: input
+#% type: string
+#% label: Raster file or files to be imported
+#% description: If multiple files are specified they will be patched together.
+#% multiple: yes
+#% required : yes
+#%end
+#%option
+#% key: output
+#% type: string
+#% description: Name for resultant raster map. Each band will be name output.bandname
+#% required : yes
+#%end
+#%option
+#% key: s_srs
+#% type: string
+#% description: Source projection in gdalwarp format
+#% required : yes
+#%end
+#%option
+#% key: method
+#% type: string
+#% description: Reprojection method to use
+#% options:nearest,bilinear,cubic,cubicspline
+#% answer:nearest
+#% required: yes
+#%end
+#%option
+#% key: warpoptions
+#% type: string
+#% description: Additional options for gdalwarp
+#% required : no
+#%end
+
+import os
+import sys
+import atexit
+
+import grass
+
+def cleanup():
+    if tmp:
+	grass.run_command('g.remove', rast = tmp, quiet = True)
+
+def warp_import(file, map, method,
+                suffixes, tiler, patches):
+    """Wrap raster file using gdalwarp before importing into GRASS"""
+    global tmp
+    warpfile = tmp + 'warped.geotiff'
+    tmpmapname = map + '_tmp'
+
+    t_srs = grass.read_command('g.proj',
+                               quiet = True,
+                               flags = 'wf')
+    if not t_srs:
+        grass.fatal('g.proj failed')
+    
+    grass.debug('gdalwarp -s_srs "%s" -t_srs "%s" "%s" "%s" %s %s' % \
+                    (options['s_srs'], t_srs, file,
+                     warpfile, options['warpoptions'], method))
+
+    grass.info("Warping input file '%s'..." % file)
+    ps = subprocess.Popen('gdalwarp',
+                          '-s_srs', options['s_srs'],
+                          '-t_srs', t_srs,
+                          file, warpfile, options['warpoptions'], method)
+    if ps.wait() != 0:
+        grass.fatal('gdalwarp failed')
+    
+    # import it into a temporary map
+    grass.info('Importing temporary raster map...')
+    if grass.run_command('r.in.gdal',
+                         quiet = True,
+                         flags = gdal_flags,
+                         input = warpfile,
+                         output = tmpmapname) != 0:
+        grass.fatal('r.in.gdal failed')
+    
+    os.remove(warpfile)
+
+    # get list of channels
+    pattern = tmpmapfile + '*'
+    grass.debug('Pattern: %s' % pattern)
+    mapset = grass.gisenv()['MAPSET']
+    channel_list = grass.mlist_grouped(type = 'rast', pattern = pattern, mapset = mapset)
+    grass.debug('Channel list: %s' % ','.join(channel_list))
+
+    if len(channel_list) < 2: # test for single band data
+        channel_suffixes = []
+    else:
+        channel_suffixes = channel_list # ???
+
+    grass.debug('Channel suffixes: %s', ','.join(channel_suffixes))
+
+    # add to the list of all suffixes
+    suffixes = suffixes + channel_suffixes
+    suffixes.sort()
+
+    # get last suffix
+    if len(channel_suffixes) > 0:
+        last_suffix = channel_suffixes[-1]
+    else:
+        last_suffix = ''
+
+    # find the alpha layer
+    if flags['k']:
+        alphalayer = tmpmapname + last_suffix
+    else:
+        alphalayer = tmpmapname + '.alpha'
+
+    # test to see if the alpha map exists
+    if not grass.find_file(element = 'cell', file = alphalayer)['name']:
+        alphalayer = ''
+        
+    # calculate the new maps:
+    for suffix in channel_suffixes:
+        grass.debug("alpha=%s MAPsfx=%s% tmpname=%s%s" % \
+                        (alphalayer, map, suffix, tmpmapname, suffix))
+        if alphalayer:
+            # Use alpha channel for nulls: problem: I've seen a map
+            # where alpha was 1-255; 1 being transparent. what to do?
+            # (Geosci Australia Gold layer, format=tiff)
+            if grass.run_command('r.mapcalc',
+                                 quiet = True,
+                                 expression = "%s%s = if(%s, %s%s, null())" % \
+                                     (map, sfx, alphalayer, tmpmapname, sfx)) != 0:
+                grass.fatal('r.mapcalc failed')
+        else:
+            if grass.run_command('g.copy',
+                                 quiet = True,
+                                 rast = "%s%s,%s%s" % \
+                                     (tmpmapname, suffix, map, suffix)) != 0:
+                grass.fatal('g.copy failed')
+        
+        # copy the color tables
+        if grass.run_command('r.colors',
+                             quiet = True,
+                             map = map + suffix,
+                             rast = tmpmapname + suffix) != 0:
+            grass.fatal('g.copy failed')
+
+        # make patch lists
+        suffix = suffix.replace('.', '_')
+        # this is a hack to make the patch lists empty:
+        if tiler == 0:
+            patches = []
+        patches = patches.append(map + suffix)
+    
+    # if no suffix, processing is simple (e.g. elevation has only 1
+    # band)
+    if len(channel_list) < 1:
+        # run r.mapcalc to crop to region
+        if grass.run_command('r.mapcalc',
+                             quiet = True,
+                             expression = "%s = %s" % \
+                                 (map, tmpmapname)) != 0:
+            grass.fatal('r.mapcalc failed')
+            
+        if grass.run_command('r.colors',
+                             quiet = True,
+                             map = map,
+                             rast = tmpmapname) != 0:
+            grass.fatal('r.colors failed')
+    
+    # remove the old channels
+    if grass.run_command('g.remove',
+                         quiet = True,
+                         rast = ','.channel_list) != 0:
+        grass.fatal('g.remove failed')
+    
+def nowarp_import(file, map, gdal_flags,
+                  suffixes, tiler, patches):
+    if grass.run_command('r.in.gdal',
+                         quiet = True,
+                         flags = 'o' + gdal_flags,
+                         input = file,
+                         output = map) != 0:
+        grass.fatal('r.in.gdal failed')
+
+    # get a list of channels:
+    pattern = map + '*'
+    grass.debug("pattern: %s" % ','.join(pattern))
+    mapset = grass.gisenv()['MAPSET']
+    channel_list = grass.mlist_grouped(type = 'rast', pattern = pattern, mapset = mapset)
+    grass.debug("channel list: %s" % ','.join(channel_list))
+
+    if len(channel_list) < 2:
+        # test for single band data
+        channel_suffixes = []
+    else:
+        channel_suffixes = channel_list # ???
+    
+    # add to the list of all suffixes:
+    suffixes = suffixes + channel_suffixes
+    suffixes.sort()
+    
+    for suffix in channel_suffixes:
+        # make patch lists
+        suffix = suffix.replace('.', '_')
+        # this is a hack to make the patch lists empty
+        if tiler == 0:
+            patches = []
+        patches = patches.append(map + suffix)
+    
+def main():
+    if not flags['p']:
+        # todo: check if gdalwarp is available
+        pass
+    
+    # flags for r.in.gdal
+    gdal_flags = ''
+    if flags['e']:
+        gdal_flags += 'e'
+    if flags['k']:
+        gdal_flags += 'k'
+    
+    # options for gdalwarp
+    method_opt = options['method']
+    if method_opt == 'nearest':
+        gdal_method = '-rn'
+    elif method_opt == 'bilinear':
+        gdal_method = '-rb'
+    elif method_opt == 'cubic':
+        gdal_method = '-rc'
+    elif method_opt == 'cubicspline':
+        gdal_method = '-rcs'
+
+    global tmp
+    tmp = grass.tempfile()
+
+    # list of all suffixes
+    suffixes = []
+    # we need a way to make sure patches are intialized correctly
+    tiler = 0
+    # list of maps
+    maplist = []
+    # list of maps to be patched
+    patches = []
+
+    # show progress infromation and grass.info() by default
+    os.environ['GRASS_VERBOSE'] = '1'
+    
+    # import tiles
+    for input in options['input'].split(','):
+        tmptilename = options['output'] + '_tile_' + str(tiler)
+        if not os.path.exists(input):
+            grass.warning("Missing input '%s'" % input)
+            continue
+        grass.info('Importing tile <%s>...' % input)
+        if flags['p']:
+            channel_suffixes = nowarp_import(input, tmptilename, gdal_flags,
+                                             suffixes, tiler, patches)
+        else:
+            warp_import(input, tmptilename, gdal_method,
+                        suffixes, tiler, patches)
+            
+        maplist.append(tmptilename)
+        tiler += 1
+
+    if tiler < 1:
+        grass.message("Nothing imported")
+        return 0
+    
+    # if there's more than one tile patch them together, otherwise
+    # just rename that tile.
+    if tiler == 1:
+        if len(channel_suffixes) > 0:
+            # multi-band
+            for suffix in channel_suffixes:
+                # rename tile 0 to be the output
+                ffile = options['output'] + '_tile_0' + suffix
+                tfile = options['output'] + suffix
+                if grass.run_command('g.rename',
+                                     quiet = True,
+                                     rast = ffile + ',' + tfile) != 0:
+                    grass.fatal('g.rename failed')
+        else: # single-band, single-tile
+            ffile = options['output'] + '_tile_0' # + sfx ?
+            tfile = options['output'] # + sfx ?
+            if grass.run_command('g.rename',
+                                 quiet = True,
+                                 rast = ffile + ',' + tfile) != 0:
+                grass.fatal('g.rename failed')
+    else:
+        # patch together each channel
+        grass.debug('suffixes: %s' % ','.join(suffixes))
+        if len(suffixes) > 0:
+            # multi-band data
+            for suffix in suffixes:
+                suffix = suffix.replace('.', '_')
+                # patch these together (using nulls only)
+		grass.message("Patching '%s' channel..." % suffix)
+		if grass.run_command('r.patch',
+                                     quiet = True,
+                                     input = patches, # ???
+                                     output = options['output'] + suffix) != 0:
+                    grass.fatal('r.patch failed')
+                    
+		# remove the temporary patches we made
+                if grass.run_command('g.remove',
+                                     quiet = True,
+                                     rast = patches) != 0:
+                    grass.fatal('g.remove failed')
+        else:
+            # single-band data
+	    grass.info("Patching tiles (this may take some time)...")
+	    grass.debug("patch list = %s" % ','.join(maplist))
+
+            # HACK: for 8bit PNG, GIF all the different tiles can have
+	    #   different color tables so patches output end up all freaky.
+	    #	r.mapcalc r#,g#,b# manual patching + r.composite?
+	    #	or d.out.file + r.in.png + r.region?
+	    # *** there is a GDAL utility to do this: gdal_merge.py
+	    #       http://www.gdal.org/gdal_merge.html
+            for color in ('r', 'g', 'b'):
+                maplist_color = []
+                for map in maplist:
+                    outmap = map + '_' + color
+                    maplist_color.append(outmap)
+                    if grass.run_command('r.mapcalc',
+                                         quiet = True,
+                                         expression = '%s = %s#%s' % (outmap, color, map)) != 0:
+                        grass.fatal('r.mapcalc failed')
+                    if grass.run_command('r.colors',
+                                         quiet = True,
+                                         map = outmap,
+                                         color = 'grey255') != 0:
+                        grass.fatal('r.colors failed')
+                    if grass.run_command('r.null',
+                                         quiet = True,
+                                         map = outmap,
+                                         setnull = 255) != 0:
+                        grass.fatal('r.null failed')
+                
+                if grass.run_command('r.patch',
+                                     input = ','.join(maplist_color),
+                                     output = outmap + '_all') != 0:
+                    grass.fatal('r.patch failed')
+                
+            if grass.run_command('r.composite',
+                                 quiet = True,
+                                 red = map + '_r_all',
+                                 green = map + '_g_all',
+                                 blue = map + '_b_all',
+                                 output = options['output']) != 0:
+                grass.fatal('r.composite failed')
+
+            if grass.run_command('g.mremove',
+                                 quiet = True,
+                                 flags = 'f',
+                                 rast = map + '*') != 0:
+                grass.fatal('g.remove failed')
+
+    # there's already a no suffix, can't make colors
+    # can only go up from here ;)
+    colors = 4
+    for suffix in suffixes:
+        if suffix in ('.red', '.green', '.blue'):
+            colors += 1
+
+    # make a composite image if asked for and colors exist
+    if colors == 3 or flags['c']:
+        grass.message("Building color image <%s>..." % options['output'])
+        if grass.run_command('r.composite',
+                             quiet = True,
+                             red = options['output'] + '.red',
+                             green = options['output'] + '.green',
+                             blue = options['output'] + '.blue',
+                             output = option['output']) != 0:
+            grass.fatal('r.composite failed')
+    
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    tmp = None
+    atexit.register(cleanup)
+
+    sys.exit(main())


Property changes on: grass/trunk/scripts/r.in.wms/r.in.gdalwarp.py
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + text/x-python
Name: svn:keywords
   + Author Date Id
Name: svn:eol-style
   + native

Deleted: grass/trunk/scripts/r.in.wms/r.in.wms
===================================================================
--- grass/trunk/scripts/r.in.wms/r.in.wms	2009-05-08 07:54:06 UTC (rev 37048)
+++ grass/trunk/scripts/r.in.wms/r.in.wms	2009-05-08 13:41:22 UTC (rev 37049)
@@ -1,596 +0,0 @@
-#!/bin/sh
-
-############################################################################
-#
-# MODULE:       r.in.wms for GRASS 6
-# AUTHOR(S):    Cedric Shock (cedricgrass AT shockfamily.net)
-# PURPOSE:      To import data from web mapping servers
-# COPYRIGHT:    (C) 2006 by Cedric Shock
-#
-#               This program is free software under the GNU General Public
-#               License (>=v2). Read the file COPYING that comes with GRASS
-#               for details.
-#
-#############################################################################
-
-#%Module
-#%  description: Downloads and imports data from WMS servers.
-#%  keywords: wms
-#%End
-#%flag
-#% key: l
-#% description: List available layers and exit
-#% guisection: Request
-#%end
-#%flag
-#% key: d
-#% description: Skip to downloading (to resume downloads faster)
-#% guisection: Download
-#%end
-#%flag
-#% key: o
-#% description: Don't request transparent data
-#% guisection: Request
-#%end
-#%flag
-#% key: c
-#% description: Clean existing data out of download directory
-#% guisection: Download
-#%end
-#%flag
-#% key: k
-#% description: Keep band numbers instead of using band color names
-#% guisection: Import
-#%end
-#%flag
-#% key: p
-#% description: Don't reproject the data, just patch it
-#% guisection: Import
-#%end
-#%flag
-#% key: g
-#% label: Use GET method instead of POST data method
-#% description: This may be needed to connect to servers which lack POST capability
-#% guisection: Request
-#%end
-#%option
-#% key: output
-#% type: string
-#% description: Name for output raster map
-#% gisprompt: new,cell,raster
-#% required : no
-#% guisection: Import
-#%end
-#%option
-#% key: mapserver
-#% type: string
-#% description: Mapserver to request data from
-#% required: yes
-#% guisection: Request
-#%end
-#%option
-#% key: layers
-#% type: string
-#% description: Layers to request from map server
-#% multiple: yes
-#% required: no
-#% guisection: Request
-#%end
-#%option
-#% key: styles
-#% type: string
-#% description: Styles to request from map server
-#% multiple: yes
-#% required: no
-#% guisection: Request
-#%end
-#%option
-#% key: srs
-#% type: string
-#% description: Source projection to request from server
-#% answer:EPSG:4326
-#% guisection: Request
-#%end
-#%option
-#% key: format
-#% type: string
-#% description: Image format requested from the server
-#% options: geotiff,tiff,jpeg,gif,png
-#% answer: geotiff
-#% required: yes
-#% guisection: Request
-#%end
-#%option
-#% key: wmsquery
-#% type:string
-#% description: Addition query options for server
-#% answer: version=1.1.1
-#% guisection: Request
-#%end
-#%option
-#% key: maxcols
-#% type: integer
-#% description: Maximum columns to request at a time
-#% answer: 1024
-#% required : yes
-#% guisection: Request
-#%end
-#%option
-#% key: maxrows
-#% type: integer
-#% description: Maximum rows to request at a time
-#% answer: 1024
-#% required : yes
-#% guisection: Request
-#%end
-#%option
-#% key: tileoptions
-#% type: string
-#% description: Additional options for r.tileset
-#% required : no
-#%end
-#%option
-#% key: region
-#% type: string
-#% description: Named region to request data for. Current region used if omitted
-#% required : no
-#% guisection: Request
-#%end
-#%option
-#% key: folder
-#% type: string
-#% description: Folder to save downloaded data to
-#% required : no
-#% guisection: Download
-#%end
-#%option
-#% key: wgetoptions
-#% type: string
-#% description: Additional options for wget
-#% answer: -c -t 5 -nv
-#% required : no
-#% guisection: Download
-#%end
-#%option
-#% key: curloptions
-#% type: string
-#% description: Additional options for curl
-#% answer: -C - --retry 5 -s -S
-#% required : no
-#% guisection: Download
-#%end
-#%option
-#% key: method
-#% type: string
-#% description: Reprojection method to use
-#% options:nearest,bilinear,cubic,cubicspline
-#% answer:nearest
-#% required: yes
-#% guisection: Import
-#%end
-#%option
-#% key: cap_file
-#% type: string
-#% label: Filename to save capabilities XML file to
-#% description: Requires list available layers flag
-#% required: no
-#% guisection: Request
-#%end
-#%option
-#% key: v
-#% type: integer
-#% description: Verbosity level
-#% answer: 1
-#%end
-
-if  [ -z "$GISBASE" ] ; then
-    echo "You must be in GRASS GIS to run this program."
-    exit 1
-fi
-
-# save command line
-if [ "$1" != "@ARGS_PARSED@" ] ; then
-    CMDLINE="`basename $0`"
-    for arg in "$@" ; do
-        CMDLINE="$CMDLINE \"$arg\""
-    done
-    export CMDLINE
-    exec g.parser "$0" "$@"
-fi
-
-#### setup temporary file
-TMP="`g.tempfile pid=$$`"
-if [ $? -ne 0 ] || [ -z "$TMP" ] ; then
-    g.message -e "Unable to create temporary files" 
-    exit 1
-fi
-
-# check if we have wget or curl
-if [ ! -x "`which wget`" ] ; then
-    if [ ! -x "`which curl`" ] ; then
-        g.message -e "Either 'wget' or 'curl' is required, please install one first" 
-        exit 1
-    else
-        g.message -v "Using CURL for downloading data."
-        USE_CURL=1
-    fi
-else
-    g.message -v "Using WGET for downloading data."
-    USE_WGET=1
-fi
-
-# check if we have bc -> used in wms.request and wms.download
-if [ ! -x "`which bc`" ] ; then
-    g.message -e "'bc' is required, please install it first"
-    exit 1
-fi
-
-# check if we have sed
-if [ ! -x "`which sed`" ] ; then
-    g.message -e "'sed' is required, please install it first" 
-    exit 1
-fi
-
-# check if we have gdalwarp -> used in r.in.gdalwarp
-if [ $GIS_FLAG_P -ne 1 ] ; then
-    if [ ! -x "`which gdalwarp`" ] ; then
-        g.message -e "'gdalwarp' is required, please install it first" 
-        exit 1
-    fi
-fi
-
-# turn verbose mode on if requested either way
-if [ "$GIS_OPT_V" -lt 2 ] ; then
-   if [ -n "$GRASS_VERBOSE" ] && [ "$GRASS_VERBOSE" -ge 2 ] ; then
-      GIS_OPT_V=2
-   fi
-else
-   g.message -w "The verbosity option is superseded. Use --verbose instead"
-   if [ -n "$GRASS_VERBOSE" ] && [ "$GRASS_VERBOSE" -lt 2 ] ; then
-      GRASS_VERBOSE=2
-   fi
-fi
-
-
-# Remember the intial field seperator
-defaultIFS="$IFS"
-
-# Remember the previous path
-prevPATH="$PATH"
-PATH="$PATH:${GISBASE}/etc/r.in.wms/"
-export PATH
-
-#####################
-# name:     message
-# purpose:  displays messages to the user
-# usage: message level text
-
-message () {
-	if [ $1 -lt $GIS_OPT_V ] ; then
-		shift
-		echo "$@" 1>&2
-	fi
-}
-
-#######################################################################
-# name:     exitprocedure
-# purpose:  removes all temporary files
-#
-exitprocedure()
-{
-	g.message -e 'User break!'
-	# is this bogus? won't PATH revert on exit anyway?
-	PATH="$prevPATH"
-	export PATH
-	\rm -f "${TMP}"*
-	exit 1
-}
-trap "exitprocedure" 2 3 15
-
-BC="bc"
-BCARGS="-l"
-
-#######################################################################
-# name:     addargument
-# purpose:  make arguments for a sub command
-#
-addargument() {
-	if [ -z "$3" ] ; then
-		message 1 "Skipping argument for $2"
- 	else
-		eval "$1=\"\$$1 '$2=$3'\""
-	fi
-}
-
-#######################################################################
-# name:     addflag
-# purpose:  make arguments for a sub command
-#
-addflag() {
-	if [ $3 -eq 1 ] ; then
-		eval "$1=\"\$$1 -$2\""
-	fi
-}
-
-######################
-# name: calculate
-# purpose: perform calculations
-# usage: varname "expr"
-
-calculate() {
-	message 3 "$2"
-	c_tmp=`echo "$2" | $BC $BCARGS`
-	eval $1=$c_tmp
-}
-
-
-######################
-# name: listLayers
-# purpose: list layers available from this server
-
-listLayers() {
-
-	CAPABILITIES_FILE="${TMP}capabilities.xml"
-
-	STRING="service=WMS&request=GetCapabilities&${GIS_OPT_WMSQUERY}";
-	g.message -d message="POST-data: [$STRING]"
-
-	### wget or curl the XML and grep the lines with layer names
-	g.message message="List of layers for server <$GIS_OPT_MAPSERVER>:"
-	g.message -v message=""
-
-	if [ "$GIS_FLAG_G" -eq 0 ] ; then
-	    if [ "$USE_WGET" ] ; then
-		wget $GIS_OPT_WGETOPTIONS --post-data="${STRING}" \
-		  "$GIS_OPT_MAPSERVER" -O "$CAPABILITIES_FILE";
-		message 1 "wget $GIS_OPT_WGETOPTIONS --post-data=\"${STRING}\" \"$GIS_OPT_MAPSERVER\" -O \"$CAPABILITIES_FILE\";"
-	    else
-		curl $GIS_OPT_CURLOPTIONS -o "$CAPABILITIES_FILE" \
-		  -d "${STRING}" "$GIS_OPT_MAPSERVER"
-		message 1 "curl $GIS_OPT_CURLOPTIONS -o \"$CAPABILITIES_FILE\" -d \"${STRING}\" \"$GIS_OPT_MAPSERVER\""
-	    fi
-	    g.message -v message=""
-
-	    if [ ! -e "$CAPABILITIES_FILE" ] ; then
-		g.message -e "Downloading XML file"
-		\rm "$TMP"
-		exit 1
-	    fi
-
-	    # work-around for brain-dead WMSs which want POST-data as part of the GET URL
-	    #   (allowed by OGC WMS def S6.3.4)
-	    if [ `wc -c < "$CAPABILITIES_FILE"` -eq 0 ] ; then
-		g.message -w "Downloaded XML file was empty -- trying another method"
-		GIS_FLAG_G=1
-	    fi
-	fi
-
-	if  [ "$GIS_FLAG_G" -eq 1 ] ; then
-	    g.message -v message=""
-	    if [ "$USE_WGET" ] ; then
-		wget $GIS_OPT_WGETOPTIONS "${GIS_OPT_MAPSERVER}?${STRING}" \
-		  -O "$CAPABILITIES_FILE";
-		message 1 "wget $GIS_OPT_WGETOPTIONS \"${GIS_OPT_MAPSERVER}?${STRING}\" -O \"$CAPABILITIES_FILE\";"
-	    else
-		curl $GIS_OPT_CURLOPTIONS -o "$CAPABILITIES_FILE" \
-		  "${GIS_OPT_MAPSERVER}?${STRING}"
-		message 1 "curl $GIS_OPT_CURLOPTIONS -o \"$CAPABILITIES_FILE\" \"${GIS_OPT_MAPSERVER}?${STRING}\""
-	    fi
-	    g.message -v message=""
-	fi
-
-	if [ ! -e "$CAPABILITIES_FILE" ] ; then
-	    g.message -e "Downloading XML file"
-	    \rm "$TMP"
-	    exit 1
-	fi
-
-	if [ `wc -c < "$CAPABILITIES_FILE"` -eq 0 ] ; then
-	     g.message -e "Downloaded XML file was empty"
-	     \rm -f "$CAPABILITIES_FILE" "$TMP"
-	     exit 1
-	fi
-
-	# use xml2 if we have it
-	if [ -x "`which xml2`" ] ; then
-		cat "$CAPABILITIES_FILE" | xml2 | \
-		  grep "Layer/SRS=\|Layer/Name=\|Layer/Title=\|Style/Name=\|Style/Title=\|Layer/Abstract=" | \
-		  sed -e "s/.*Layer\\/Name=/LAYER: /" \
-		      -e "s/.*Layer\\/SRS=/  SRS: /" \
-		      -e "s/.*Layer\\/Title=/  Title: /" \
-		      -e "s/.*Layer\\/Abstract=/  |/" \
-		      -e "s/.*Layer\\/Style\\/Name=/  STYLE: /" \
-		      -e "s/.*Layer\\/Style\\/Title=/    Style title: /" \
-		  > "${TMP}capabilities.txt"
-
-	else : # xml2 is not available
-		g.message -w "The 'xml2' program was not found. Proceeding with internal XML parsing which may not be as reliable."
-		sed -e "s/<Layer/\n<Layer/g" \
-		    -e "s/<Name>/\n<Name>/g" \
-		    -e "s/<Style>/\n<Style>/g" \
-		    -e "s/<Title>/\n<Title>/g" \
-		    "$CAPABILITIES_FILE" | \
-		    grep "Name\|Title\|Style\|Layer" | \
-		    sed -e "s/<Layer .*>/LAYER:/" \
-		      -e "s/<\/Layer.*>//" \
-		      -e "s/<Name>\s*\([^<]*\)/~\1~/g" \
-		      -e "s/<\/Name>\n\?//g" \
-		      -e "s/<Style>\n*\s*\(\w*\)/Style: \1/" \
-		      -e "s/<\/Style>//" \
-		      -e "s/<Title>\(.*\)<\/Title>/\t --\1 /" \
-		      -e "s/<\/Title>//" \
-		      -e "s/<\/*.*\/*\/*>//" \
-		    > "${TMP}capabilities.txt"
-	fi
-
-	if [ `wc -l < "${TMP}capabilities.txt"` -eq 0 ] ; then
-	    g.message message=""
-	    g.message -e "Parsing XML file"
-	    g.message message="------------------------"
-	    cat "$CAPABILITIES_FILE"
-	else
-	    cat "${TMP}capabilities.txt"
-	fi
-	g.message message=""
-
-	if [ -e "$CAPABILITIES_FILE" ] ; then
-	    \rm -f "${TMP}capabilities.txt" "$TMP"
-
-	    if [ -n "$GIS_OPT_CAP_FILE" ] ; then
-		mv "$CAPABILITIES_FILE" "$GIS_OPT_CAP_FILE"
-	    else
-		\rm -f "$CAPABILITIES_FILE"
-	    fi
-    
-        fi
-        exit 1;
-}
-
-
-#### Test for listing layers
-
-if [ $GIS_FLAG_L -eq 1 ] ; then
-	listLayers
-fi
-
-#### Exit if there is no map
-# It would be a good idea to test if the map already exists here too
-
-if [ -z "${GIS_OPT_OUTPUT}" ] ; then
-	g.message -e "No output map specified"
-	exit 1;
-fi
-
-REQUEST=""
-DOWNLOAD=""
-GDALWARP=""
-
-eval `g.gisenv`
-
-#Job number one: pick a folder
-if [ -z "${GIS_OPT_FOLDER}" ] ; then
-	GIS_OPT_FOLDER="${GISDBASE}/wms_download"
-fi
-
-PREFIX="${GIS_OPT_OUTPUT}"
-if [ -x "`which wget`" ] ; then
-    REQUESTFILE="${GIS_OPT_FOLDER}/${PREFIX}_${GIS_OPT_REGION}.wget"
-else
-    REQUESTFILE="${GIS_OPT_FOLDER}/${PREFIX}_${GIS_OPT_REGION}.curl"
-fi
-
-if [ ! -z "$GIS_OPT_REGION" ] ; then
-   eval `g.findfile element=windows file="$GIS_OPT_REGION"`
-   if [ ! "$file" ] ; then
-      g.message -e "Region file '$GIS_OPT_REGION' not found."
-      exit 1
-   fi
-fi
-
-# URL-proof spaces in layer names. (convert other chars to hex too?)
-#    HTTP reserved are: ";", "/", "?", ":", "@", "=", "#" and "&"
-LAYERS=`echo ${GIS_OPT_LAYERS} | sed -e 's/ /%20/g'`
-
-
-addflag REQUEST o ${GIS_FLAG_O}
-addflag REQUEST c ${GIS_FLAG_C}
-addflag REQUEST p ${GIS_FLAG_P}
-addargument REQUEST folder "${GIS_OPT_FOLDER}"
-addargument REQUEST prefix "${PREFIX}"
-addargument REQUEST region "${GIS_OPT_REGION}"
-addargument REQUEST mapserver "${GIS_OPT_MAPSERVER}"
-addargument REQUEST layers "${LAYERS}"
-addargument REQUEST styles "${GIS_OPT_STYLES}"
-addargument REQUEST srs "${GIS_OPT_SRS}"
-addargument REQUEST format "${GIS_OPT_FORMAT}"
-addargument REQUEST wmsquery "${GIS_OPT_WMSQUERY}"
-addargument REQUEST maxcols "${GIS_OPT_MAXCOLS}"
-addargument REQUEST maxrows "${GIS_OPT_MAXROWS}"
-addargument REQUEST tileoptions "${GIS_OPT_TILEOPTIONS}"
-
-if [ $GIS_FLAG_D -eq 0 ] ; then
-	message 1 "wms.request $REQUEST"
-	eval "wms.request $REQUEST"
-	if [ $? -ne 0 ] ; then
-	   g.message -e "wms.request failure" 
-	   exit 1
-	fi
-fi
-
-addflag DOWNLOAD g ${GIS_FLAG_G}
-addargument DOWNLOAD requestfile "${REQUESTFILE}"
-addargument DOWNLOAD wgetoptions "${GIS_OPT_WGETOPTIONS}"
-addargument DOWNLOAD curloptions "${GIS_OPT_CURLOPTIONS}"
-
-message 1 "wms.download $DOWNLOAD"
-eval "wms.download $DOWNLOAD"
-
-# Job 2: make list of files
-
-CONTENTS=`cat "${REQUESTFILE}"`
-
-FILES=""
-COUNT=0
-for line in $CONTENTS ; do
-	eval "$line"
-	if [ $COUNT -eq 0 ] ; then
-		FILES="$OUTPUT_FILE"
-	else
-		FILES="$FILES,$OUTPUT_FILE"
-	fi
-	COUNT=`expr $COUNT + 1`
-done
-
-addflag GDALWARP c 1
-addflag GDALWARP k ${GIS_FLAG_K}
-addflag GDALWARP p ${GIS_FLAG_P}
-addargument GDALWARP input "$FILES"
-addargument GDALWARP output "${GIS_OPT_OUTPUT}"
-addargument GDALWARP method "${GIS_OPT_METHOD}"
-addargument GDALWARP s_srs "${GIS_OPT_SRS}"
-
-# check for error like 'Service Exception Report'
-if [ `file -b "$FILES" | grep -c "^HTML\|^XML"` -eq 1 ] ; then
-  g.message "#################################"
-  cat "$FILES"
-  g.message message=""
-  \rm -f "${TMP}"*
-  exit 1
-fi
-
-message 1 "r.in.gdalwarp $GDALWARP"
-eval "r.in.gdalwarp $GDALWARP"
-if [ $? -ne 0 ] ; then
-   g.message -e message="r.in.gdalwarp failed"
-   exit 1
-fi
-
-r.support map="$GIS_OPT_OUTPUT" title="WMS Download" history="" \
-  source1=`echo "$GIS_OPT_MAPSERVER" | cut -c-70` \
-  source2=`echo "$GIS_OPT_MAPSERVER" | cut -c71-140`
-if [ $? -ne 0 ] ; then
-   g.message -e message="r.support failed"
-   exit 1
-fi
-
-LAY_LEN="echo "$GIS_OPT_LAYERS" | wc -c"
-
-r.support map="$GIS_OPT_OUTPUT" history="layers: $GIS_OPT_LAYERS"
-if [ -n "$GIS_OPT_STYLES" ] ; then
-   r.support map="$GIS_OPT_OUTPUT" history="styles: $GIS_OPT_STYLES"
-fi
-r.support map="$GIS_OPT_OUTPUT" history=""
-r.support map="$GIS_OPT_OUTPUT" history="Source projection: $GIS_OPT_SRS"
-if [ "$GIS_FLAG_P" -eq 1 ] ; then
-   r.support map="$GIS_OPT_OUTPUT" history="  (imported without reprojection)"
-fi
-r.support map="$GIS_OPT_OUTPUT" description="generated by r.in.wms" history=""
-r.support map="$GIS_OPT_OUTPUT" history="$CMDLINE"
-
-
-g.message -v message="Map <${GIS_OPT_OUTPUT}> written"
-
-# Clean up:
-\rm -f "${TMP}"*
-
-exit

Added: grass/trunk/scripts/r.in.wms/r.in.wms.py
===================================================================
--- grass/trunk/scripts/r.in.wms/r.in.wms.py	                        (rev 0)
+++ grass/trunk/scripts/r.in.wms/r.in.wms.py	2009-05-08 13:41:22 UTC (rev 37049)
@@ -0,0 +1,318 @@
+#!/usr/bin/env python
+
+############################################################################
+#
+# MODULE:       r.in.wms
+#
+# AUTHOR(S):    Cedric Shock, 2006
+#               Pythonized by Martin Landa <landa.martin gmail.com>, 2009
+#
+# PURPOSE:      To import data from web mapping servers
+#               (based on Bash script by Cedric Shock)
+#
+# COPYRIGHT:    (C) 2009 Martin Landa, and GRASS development team
+#
+#               This program is free software under the GNU General
+#               Public License (>=v2). Read the file COPYING that
+#               comes with GRASS for details.
+#
+#############################################################################
+
+#%module
+#%  description: Downloads and imports data from WMS servers.
+#%  keywords: raster, import, wms
+#%end
+#%flag
+#% key: l
+#% description: List available layers and exit
+#% guisection: Request
+#%end
+#%flag
+#% key: d
+#% description: Skip to downloading (to resume downloads faster)
+#% guisection: Download
+#%end
+#%flag
+#% key: o
+#% description: Don't request transparent data
+#% guisection: Request
+#%end
+#%flag
+#% key: c
+#% description: Clean existing data out of download directory
+#% guisection: Download
+#%end
+#%flag
+#% key: k
+#% description: Keep band numbers instead of using band color names
+#% guisection: Import
+#%end
+#%flag
+#% key: p
+#% description: Don't reproject the data, just patch it
+#% guisection: Import
+#%end
+#%flag
+#% key: g
+#% label: Use GET method instead of POST data method
+#% description: This may be needed to connect to servers which lack POST capability
+#% guisection: Request
+#%end
+#%option
+#% key: output
+#% type: string
+#% description: Name for output raster map
+#% gisprompt: new,cell,raster
+#% required : no
+#% guisection: Import
+#%end
+#%option
+#% key: mapserver
+#% type: string
+#% description: Mapserver to request data from
+#% required: yes
+#% guisection: Request
+#%end
+#%option
+#% key: layers
+#% type: string
+#% description: Layers to request from map server
+#% multiple: yes
+#% required: no
+#% guisection: Request
+#%end
+#%option
+#% key: styles
+#% type: string
+#% description: Styles to request from map server
+#% multiple: yes
+#% required: no
+#% guisection: Request
+#%end
+#%option
+#% key: srs
+#% type: string
+#% description: Source projection to request from server
+#% answer:EPSG:4326
+#% guisection: Request
+#%end
+#%option
+#% key: format
+#% type: string
+#% description: Image format requested from the server
+#% options: geotiff,tiff,jpeg,gif,png
+#% answer: geotiff
+#% required: yes
+#% guisection: Request
+#%end
+#%option
+#% key: wmsquery
+#% type:string
+#% description: Addition query options for server
+#% answer: version=1.1.1
+#% guisection: Request
+#%end
+#%option
+#% key: maxcols
+#% type: integer
+#% description: Maximum columns to request at a time
+#% answer: 1024
+#% required : yes
+#% guisection: Request
+#%end
+#%option
+#% key: maxrows
+#% type: integer
+#% description: Maximum rows to request at a time
+#% answer: 1024
+#% required : yes
+#% guisection: Request
+#%end
+#%option
+#% key: tileoptions
+#% type: string
+#% description: Additional options for r.tileset
+#% required : no
+#%end
+#%option
+#% key: region
+#% type: string
+#% description: Named region to request data for. Current region used if omitted
+#% required : no
+#% guisection: Request
+#%end
+#%option
+#% key: folder
+#% type: string
+#% description: Folder to save downloaded data to (default $GISDBASE/wms_download)
+#% required : no
+#% guisection: Download
+#%end
+#%option
+#% key: wgetoptions
+#% type: string
+#% description: Additional options for wget
+#% answer: -c -t 5 -nv
+#% required : no
+#% guisection: Download
+#%end
+#%option
+#% key: curloptions
+#% type: string
+#% description: Additional options for curl
+#% answer: -C - --retry 5 -s -S
+#% required : no
+#% guisection: Download
+#%end
+#%option
+#% key: method
+#% type: string
+#% description: Reprojection method to use
+#% options:nearest,bilinear,cubic,cubicspline
+#% answer:nearest
+#% required: yes
+#% guisection: Import
+#%end
+#%option
+#% key: cap_file
+#% type: string
+#% label: Filename to save capabilities XML file to
+#% description: Requires list available layers flag
+#% required: no
+#% guisection: Request
+#%end
+
+import os
+import sys
+import tempfile
+import urllib
+import xml.sax
+import xml.sax.handler
+HandlerBase=xml.sax.handler.ContentHandler
+from xml.sax import make_parser
+
+import grass
+
+import wms_request
+import wms_download
+
+class ProcessCapFile(HandlerBase):
+    """
+    A SAX handler for the capabilities file
+    """
+    def __init__(self):
+        self.inTag = {}
+        for tag in ('layer', 'name', 'style',
+                    'title', 'srs'):
+            self.inTag[tag] = False
+        self.value = ''
+        
+        self.layers = []
+        
+    def startElement(self, name, attrs):
+        if self.inTag.has_key(name.lower()):
+            self.inTag[name.lower()] = True
+        
+        if name.lower() == 'layer':
+            self.layers.append({})
+        
+    def endElement(self, name):
+        if self.inTag.has_key(name.lower()):
+            self.inTag[name.lower()] = False
+
+        for tag in ('name', 'title', 'srs'):
+            if name.lower() != tag:
+                continue
+            if self.inTag['style']:
+                if not self.layers[-1].has_key('style'):
+                    self.layers[-1]['style'] = {}
+                if not self.layers[-1]['style'].has_key(tag):
+                    self.layers[-1]['style'][tag] = []
+                self.layers[-1]['style'][tag].append(self.value)
+            elif self.inTag['layer']:
+                self.layers[-1][tag] = self.value
+            
+        if name.lower() in ('name', 'title', 'srs'):
+            self.value = ''
+        
+    def characters(self, ch):
+        if self.inTag['name'] or \
+                self.inTag['title'] or \
+                self.inTag['srs']:
+            self.value += ch
+    
+    def getLayers(self):
+        """Print list of layers"""
+        for ly in self.layers:
+            print "LAYER: " + ly['name']
+            if ly.has_key('title'):
+                print "  Title: " + ly['title']
+            if ly.has_key('srs'):
+                print "  SRS: " + ly['srs']
+            if ly.has_key('style'):
+                for idx in range(len(ly['style']['name'])):
+                    print "  STYLE: " + ly['style']['name'][idx]
+                    print "    Style title: " + ly['style']['title'][idx]
+        
+def list_layers():
+    """Get available layers from WMS server"""
+    qstring = "service=WMS&request=GetCapabilities&" + options['wmsquery']
+    grass.debug("POST-data: %s" % qstring)
+    
+    # download capabilities file
+    grass.verbose("List of layers for server <%s>:" % options['mapserver'])
+    cap_file = urllib.urlopen(options['mapserver'] + qstring)
+    if not cap_file:
+        grass.fatal("Unable to get capabilities of <%s>" % options['mapserver'])
+
+    # parse file with sax
+    cap_xml = ProcessCapFile()
+    try:
+        xml.sax.parse(cap_file, cap_xml)
+    except xml.sax.SAXParseException, err:
+        grass.fatal("Reading capabilities failed. "
+                    "Unable to parse XML document: %s" % err)
+
+    cap_xml.getLayers()
+    
+def main():
+    if flags['l']:
+        # list of available layers
+        list_layers()
+        return 0
+    elif not options['output']:
+        grass.fatal("No output map specified")
+
+    # set directory for download
+    if not options['folder']:
+        options['folder'] = os.path.join(grass.gisenv()['GISDBASE'], 'wms_download')
+    
+    # region settings
+    if options['region']:
+        if not grass.find_file(name = options['region'], element = 'windows')['name']:
+            grass.fatal("Region <%s> not found" % options['region'])
+    
+    if not flags['d']:
+        # request data first
+        request = wms_request.WMSRequest(flags, options)
+        request.GetTiles()
+        if not request:
+            grass.fatal("WMS request failed")
+    
+    # download data
+    download = wms_download.WMSDownload(flags, options)
+    download.GetTiles(request.GetRequests()) ## ??
+    
+    # list of files
+    files = []
+    for item in request.GetRequests():
+        files.append(item['output'])
+    files = ','.join(files)
+    
+    gdalwarp.GDALWarp(flags, options)
+    
+    return 0
+
+if __name__ == "__main__":
+    options, flags = grass.parser()
+    sys.exit(main())


Property changes on: grass/trunk/scripts/r.in.wms/r.in.wms.py
___________________________________________________________________
Name: svn:executable
   + *
Name: svn:mime-type
   + text/x-python
Name: svn:keywords
   + Author Date Id
Name: svn:eol-style
   + native

Deleted: grass/trunk/scripts/r.in.wms/wms.download
===================================================================
--- grass/trunk/scripts/r.in.wms/wms.download	2009-05-08 07:54:06 UTC (rev 37048)
+++ grass/trunk/scripts/r.in.wms/wms.download	2009-05-08 13:41:22 UTC (rev 37049)
@@ -1,216 +0,0 @@
-#!/bin/sh
-
-############################################################################
-#
-# MODULE:       wms.download for GRASS 6
-# AUTHOR(S):    Cedric Shock (cedric AT shockfamily.net)
-#               Based on r.in.onearth by Soeren Gebbert and Markus Neteler
-#               And on r.in.wms by Jachym Cepicky
-# PURPOSE:      Downloads data from servers
-# COPYRIGHT:    (C) 2005, 2006 by the GRASS Development Team
-#
-#               This program is free software under the GNU General Public
-#               License (>=v2). Read the file COPYING that comes with GRASS
-#               for details.
-#
-#############################################################################
-
-#%Module
-#%  description: Downloads data from servers.
-#%  keywords: wms
-#%End
-#%flag
-#% key: g
-#% label: Use GET method instead of POST data method
-#% description: This may be needed to connect to servers which lack POST capability
-#%end
-#%option
-#% key: requestfile
-#% type: string
-#% description: File that lists the tiles to download
-#% required : yes
-#%end
-#%option
-#% key: wgetoptions
-#% type: string
-#% description: Additional options for wget
-#% answer: -c -t 5
-#% required : no
-#%end
-#%option
-#% key: curloptions
-#% type: string
-#% description: Additional options for curl
-#% answer: -C - --retry 5
-#% required : no
-#%end
-#%option
-# FIXME: Remove before GRASS 7 is released
-#% key: v
-#% type: integer
-#% description: Verbosity level
-#% answer: 1
-#%end
-
-if  [ -z "$GISBASE" ] ; then
-    echo "You must be in GRASS GIS to run this program." 1>&2
- exit 1
-fi
-
-if [ "$1" != "@ARGS_PARSED@" ] ; then
-  exec g.parser "$0" "$@"
-fi
-
-g.message -d "[wms.download]"
-
-#### setup temporary file
-TMP="`g.tempfile pid=$$`"
-if [ $? -ne 0 ] || [ -z "$TMP" ] ; then
-    g.message -e "Unable to create temporary files"
-    exit 1
-fi
-
-# check if we have wget or curl
-if [ ! -x "`which wget`" ] ; then
-    if [ ! -x "`which curl`" ] ; then
-        g.message -e "one of wget or curl is required, please install either first" 
-        exit 1
-    else
-        USE_CURL=1
-    fi
-else
-    USE_WGET=1
-fi
-
-# Remember the intial field seperator
-defaultIFS=$IFS
-
-#######################################################################
-# name:     exitprocedure
-# purpose:  removes all temporary files
-#
-exitprocedure()
-{
-	g.message -e 'User break!'
-	rm -f "${TMP}"*
-	exit 1
-}
-trap "exitprocedure" 2 3 15
-
-BC="bc"
-BCARGS="-l"
-
-#####################
-# name: calculate
-# purpose: perform calculations
-# usage: varname "expr"
-
-calculate() {
-	g.message message="$2"
-	c_tmp=`echo "$2" | $BC $BCARGS`
-	eval $1=$c_tmp
-}
-
-################################################################
-# Download the tiles!!
-GetTiles() {
-  g.message "Downloading tiles"
-
-  # init POST-data vs. GET URL method variable
-  if [ "$GIS_FLAG_G" -eq 0 ] ; then
-     POST_DATA_OK=1
-  else
-     POST_DATA_OK=0
-  fi
-
-  CONTENTS=`cat "${REQUESTFILE}"`
-
-  NUMBER_OF_TILES=0
-  for line in $CONTENTS ; do
-	g.message -d message="wget command: [$line]" debug=2
-	eval "$line"
-
-	emptyness=`file "$OUTPUT_FILE" | grep empty$`
-
-	if [ -f "$OUTPUT_FILE" ] && [ -z "$emptyness" ] ; then
-	   g.message "Tile already downloaded"
-	else
-	   GetData
-	   if [ $? -ne 0 ] ; then
-              NUMBER_OF_TILES=`expr $NUMBER_OF_TILES + 1`
-           fi
-	fi
-  done
-
-  if [ $NUMBER_OF_TILES -ne 0 ] ; then
-    g.message -w "$NUMBER_OF_TILES failed to download"
-    return 1
-  else
-    g.message "All tiles downloaded successfully"
-    return 0
-  fi
-}
-
-##################################
-#Get the data from the WMS server
-GetData() {
-   g.message "Downloading data"
-   g.message -v message="Requesting Data from <${SERVER}>:"
-   g.message -v message="$STRING"
-
-   if [ "$POST_DATA_OK" -eq 1 ] ; then
-      #download the File from the Server
-      if [ "$USE_WGET" ] ; then
-         wget ${WGET_OPTIONS} --post-data="${STRING}" "${SERVER}" -O "${OUTPUT_FILE}"
-      else
-         curl ${CURL_OPTIONS} -o "${OUTPUT_FILE}" -d "${STRING}" "${SERVER}"
-      fi
-      if [ $? -ne 0 ] ; then
-         g.message -e "Failed while downloading the data"
-         return 1
-      fi
-      if [ ! -f "$OUTPUT_FILE" ] ; then 
-         g.message -e "Not able to download the data"
-         return 1
-      fi
-
-       # work-around for brain-dead ArcIMS servers which want POST-data as part of the GET URL
-       #   (this is technically allowed by OGC WMS def v1.3.0 Sec6.3.4)
-      if [ `wc -c < "$OUTPUT_FILE"` -eq 0 ] ; then
-         g.message -w "Downloaded image file was empty -- trying another method"
-         POST_DATA_OK=0
-      fi
-   fi  # no else!
-
-   if [ "$POST_DATA_OK" -eq 0 ] ; then
-      g.message -v message=""
-      if [ "$USE_WGET" ] ; then
-	 wget ${WGET_OPTIONS} "${SERVER}?${STRING}" -O "${OUTPUT_FILE}"
-      else
-	 curl ${CURL_OPTIONS} -o "${OUTPUT_FILE}" "${SERVER}?${STRING}"
-      fi
-      if [ $? -ne 0 ] ; then
-         g.message -e "Failed while downloading the data"
-         return 1
-      fi
-      if [ ! -f "$OUTPUT_FILE" ] || [ `wc -c < "$OUTPUT_FILE"` -eq 0 ] ; then 
-         g.message -e "Not able to download the data"
-         return 1
-      fi
-   fi
-
-   return 0
-}
-
-# Initialize variables:
-#wget has many options
-WGET_OPTIONS="${GIS_OPT_WGETOPTIONS}"
-CURL_OPTIONS="${GIS_OPT_CURLOPTIONS}"
-REQUESTFILE="${GIS_OPT_REQUESTFILE}"
-
-#Get all the data
-GetTiles
-
-# Clean up:
-rm -f "${TMP}"*
-

Deleted: grass/trunk/scripts/r.in.wms/wms.request
===================================================================
--- grass/trunk/scripts/r.in.wms/wms.request	2009-05-08 07:54:06 UTC (rev 37048)
+++ grass/trunk/scripts/r.in.wms/wms.request	2009-05-08 13:41:22 UTC (rev 37049)
@@ -1,318 +0,0 @@
-#!/bin/sh
-
-############################################################################
-#
-# MODULE:       wms.request for GRASS 6
-# AUTHOR(S):    Cedric Shock (cedric AT shockfamily.net)
-#               Based on r.in.onearth by Soeren Gebbert and Markus Neteler
-#               And on r.in.wms by Jachym Cepicky
-# PURPOSE:      Builds requests for downloading data from web mapping servers
-# COPYRIGHT:    (C) 2005, 2006 by the GRASS Development Team
-#
-#               This program is free software under the GNU General Public
-#               License (>=v2). Read the file COPYING that comes with GRASS
-#               for details.
-#
-#############################################################################
-
-#%Module
-#%  description: Builds download requests for WMS servers.
-#%  keywords: wms
-#%End
-#%flag
-#% key: o
-#% description: Don't request transparent data
-#%end
-#%flag
-#% key: c
-#% description: Clean out existing data
-#%end
-#%flag
-#% key: t
-#% description: Use 
-#%end
-#%flag
-#% key: p
-#% description: This projection is the srs projection.
-#%end
-#%option
-#% key: folder
-#% type: string
-#% description: Folder in which to save downloaded files
-#% required : yes
-#%end
-#%option
-#% key: prefix
-#% type: string
-#% description: Prefix file names with this
-#% required : yes
-#%end
-#%option
-#% key: region
-#% type: string
-#% description: Named region that defines the tileset.
-#% required : no
-#%end
-#%option
-#% key: mapserver
-#% type: string
-#% description: Mapserver to request data from
-#% required: yes
-#%end
-#%option
-#% key: layers
-#% type: string
-#% description: Layers to request from map server
-#% multiple: yes
-#% required: yes
-#%end
-#%option
-#% key: styles
-#% type: string
-#% description: Styles to request from map server
-#% multiple: yes
-#% required: no
-#%end
-#%option
-#% key: srs
-#% type: string
-#% description: Source projection to request from server
-#% answer:EPSG:4326
-#%end
-#%option
-#% key: format
-#% type: string
-#% description: Image format requested from the server
-#% options: geotiff,tiff,jpeg,gif,png
-#% answer: geotiff
-#% required: no
-#%end
-#%option
-#% key: maxcols
-#% type: integer
-#% description: Maximum columns to request at a time. 
-#% answer: 1024
-#% required : no
-#%end
-#%option
-#% key: maxrows
-#% type: integer
-#% description: Maximum rows to request at a time
-#% answer: 1024
-#% required : no
-#%end
-#%option
-#% key: tileoptions
-#% type: string
-#% description: Additional options for r.tileset
-#% required : no
-#%end
-#%option
-#% key: wmsquery
-#% type:string
-#% description: Addition query options for server
-#% answer: version=1.1.1
-#%end
-# FIXME: Remove before GRASS 7 is released
-#%option
-#% key: v
-#% type: integer
-#% description: Verbosity level
-#% answer: 1
-#%end
-
-if  [ -z "$GISBASE" ] ; then
-    echo "You must be in GRASS GIS to run this program." 1>&2
-    exit 1
-fi
-
-if [ "$1" != "@ARGS_PARSED@" ] ; then
-  exec g.parser "$0" "$@"
-fi
-
-g.message -d "[wms.request]"
-
-SED="sed"
-GREP="grep"
-# check if we have sed
-if [ ! -x "`which $SED`" ] ; then
-    g.message "$SED is required, please install it first"
-    exit 1
-fi
-
-# check if we have grep
-if [ ! -x "`which $GREP`" ] ; then
-    g.message "$GREP is required, please install it first"
-    exit 1
-fi
-
-# Remember the intial field seperator
-defaultIFS="$IFS"
-
-
-####################################
-# name:     message
-# purpose:  displays messages to the user
-# usage: message level text
-
-message () {
-	if [ $1 -lt $GIS_OPT_V ] ; then
-		shift
-		echo "$@"  
-	fi
-}
-
-
-BC="bc"
-BCARGS="-l"
-
-####################################
-# name: calculate
-# purpose: perform calculations
-# usage: varname "expr"
-
-calculate() {
-	message 3 "$2"
-	c_tmp=`echo "$2" | $BC $BCARGS`
-	eval $1=$c_tmp
-}
-
-####################################
-# Calculate the number of tiles!!
-# Download and them
-GetTiles() {
-  g.message "Calculating tiles"
-
-  #################################################
-  # ############## TILE SETTINGS ################ #
-  #################################################
-  MAXCOLS=${GIS_OPT_MAXCOLS} #The maximum cols of the biggest tile 
-  MAXROWS=${GIS_OPT_MAXROWS} #The maximum rows of the biggest tile 
-
-
-  #Calculate the number of tiles and set up the arrays
-  message 1 "r.tileset -g sourceproj=\"$PROJ4_SRS\" sourcescale=\"$SRS_SCALE\" overlap=2 maxcols=${MAXCOLS} maxrows=${MAXROWS} $TILESET_OPTIONS"
-  TILES=`eval "GRASS_VERBOSE=1 r.tileset -g sourceproj=\"$PROJ4_SRS\" sourcescale=\"$SRS_SCALE\" overlap=2 maxcols=${MAXCOLS} maxrows=${MAXROWS} $TILESET_OPTIONS"`
-  if [ $? -ne 0 ] ; then
-     g.message -e "r.tileset failure"
-     exit 1
-  fi
-
-  NUMBER_OF_TILES=0 #The number of the tiles 
-  #Calculate the number of tiles
-  for i in $TILES ; do
-	NUMBER_OF_TILES=`expr $NUMBER_OF_TILES + 1`
-  done
-
-  g.message "Requesting ${NUMBER_OF_TILES} tiles."
-  
-  NUMBER_OF_TILES=0 #The number of the tiles 
-
-  mkdir -p "${GIS_OPT_FOLDER}"
-
-  FOLDERPLUS="${GIS_OPT_FOLDER}/${GIS_OPT_PREFIX}_${GIS_OPT_REGION}"
-
-  if [ $GIS_FLAG_C -eq 1 ] ; then
-    g.message -v message="Removing files <${FOLDERPLUS}*>"
-    rm -f "$FOLDERPLUS"*
-  fi
-
-  if [ -x "`which wget`" ] ; then
-    REQUESTFILE="${FOLDERPLUS}.wget"
-  else
-    REQUESTFILE="${FOLDERPLUS}.curl"
-  fi
-
-  #reset the requestfile
-  echo > "${REQUESTFILE}"
-
-  echo "$PROJ4_SRS" > "${FOLDERPLUS}.proj4"
-
-  for i in $TILES ; do
-	eval "$i"
-	SIZE="bbox=$w,$s,$e,$n&width=$cols&height=$rows"
-	message 1 "$SIZE"
-	IMAGEFILE="${FOLDERPLUS}_${NUMBER_OF_TILES}"
-	OUTPUT_FILE="${IMAGEFILE}${FILE_EXTENT}"
-	# We could add world files here to help out gdalwarp.
-	# And here it is:
-	# Displacement from top left cell to the one to the right of it and to the one below it:
-	calculate xres "($e - $w) / $cols"
-	calculate nyres "($s - $n) / $rows"
-	# Center of top left cell:
-	calculate top_left_cell_center_x "$w + $xres / 2"
-	calculate top_left_cell_center_y "$n + $nyres / 2"
-	#Write the world file:
-	echo "$xres" > "${IMAGEFILE}${WORLDFILE}"
-	echo "0.0" >> "${IMAGEFILE}${WORLDFILE}"
-	echo "0.0" >> "${IMAGEFILE}${WORLDFILE}"
-	echo "$nyres" >> "${IMAGEFILE}${WORLDFILE}"
-	echo "$top_left_cell_center_x" >> "${IMAGEFILE}${WORLDFILE}"
-	echo "$top_left_cell_center_y" >> "${IMAGEFILE}${WORLDFILE}"
-	#Make the requestt for data:
-	STRING="request=GetMap&layers=${GIS_OPT_LAYERS}&styles=${GIS_OPT_STYLES}&srs=${SRS}&${SIZE}&format=${FORMAT}&${TRANSPARENCY}&${WMS_QUERY}"
-	echo "OUTPUT_FILE=\"${OUTPUT_FILE}\";SERVER=\"${SERVER}\";STRING=\"${STRING}\"" >> "${REQUESTFILE}"
-
-	NUMBER_OF_TILES=`expr $NUMBER_OF_TILES + 1`
-  done
-}
-
-
-# Initialize variables:
-
-SERVER="${GIS_OPT_MAPSERVER}"
-SRS="${GIS_OPT_SRS}"
-SRS_lower=`echo $SRS | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"`
-
-
-# If the user asserts that this projection is the same as the source
-# use this projection as the source to get a trivial tiling from r.tileset
-if [ $GIS_FLAG_P -eq 1 ] ; then
-	PROJ4_SRS=`g.proj -j`
-	eval `g.proj -p | $GREP meters | $SED "s/\\s*:\\s*/=/"`
-	SRS_SCALE=$meters;
-else
-	PROJ4_SRS="+init=$SRS_lower"
-	SRS_SCALE=1
-fi
-
-WMS_QUERY="${GIS_OPT_WMSQUERY}"
-
-if [ -z "$GIS_OPT_REGION" ] ; then
-	TILESET_OPTIONS="$GIS_OPT_TILEOPTIONS"
-else
-	TILESET_OPTIONS="region=$GIS_OPT_REGION $GIS_OPT_TILEOPTIONS"
-fi
-
-if [ $GIS_FLAG_O -eq 1 ] ; then
-	TRANSPARENCY="transparent=FALSE"
-else
-	TRANSPARENCY="transparent=TRUE"
-fi
-
-case "${GIS_OPT_FORMAT}" in
-    "geotiff") FORMAT="image/geotiff"
-               WORLDFILE=".tfw"
-               FILE_EXTENT=".geotiff"
-               ;;
-    "tiff") FORMAT="image/tiff"
-               WORLDFILE=".tfw"
-               FILE_EXTENT=".tiff"
-               ;;
-    "png") FORMAT="image/png"
-               WORLDFILE=".pgw"
-               FILE_EXTENT=".png"
-               ;;
-    "jpeg") FORMAT="image/jpeg"
-               WORLDFILE=".jgw"
-               FILE_EXTENT=".jpeg"
-               ;;
-    "gif") FORMAT="image/gif"
-               WORLDFILE=".gfw"
-               FILE_EXTENT=".gif"
-               ;;
-esac
-
-GetTiles
-
-exit

Added: grass/trunk/scripts/r.in.wms/wms_download.py
===================================================================
--- grass/trunk/scripts/r.in.wms/wms_download.py	                        (rev 0)
+++ grass/trunk/scripts/r.in.wms/wms_download.py	2009-05-08 13:41:22 UTC (rev 37049)
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+
+############################################################################
+#
+# MODULE:       r.in.wms
+#
+# AUTHOR(S):    Cedric Shock, 2006
+#               Pythonized by Martin Landa <landa.martin gmail.com>, 2009
+#
+# PURPOSE:      To import data from web mapping servers
+#               (based on Bash script by Cedric Shock)
+#
+# COPYRIGHT:    (C) 2009 Martin Landa, and GRASS development team
+#
+#               This program is free software under the GNU General
+#               Public License (>=v2). Read the file COPYING that
+#               comes with GRASS for details.
+#
+#############################################################################
+
+import os
+import urllib
+
+import grass
+
+class WMSDownload:
+    def __init__(self, flags, options):
+        self.flags   = flags
+        self.options = options
+        
+    def GetTiles(self, requests):
+        grass.message("Downloading tiles...")
+        
+        i = 0
+        for item in requests:
+            if os.path.exists(item['output']) and \
+                    os.path.getsize(item['output']) > 0:
+                grass.message("Tile already downloaded")
+            else:
+                self.GetData(i, item['server'] + item['string'], item['output'])
+            i += 1
+        
+    def GetData(self, idx, url, output):
+        """Download data"""
+        grass.message("Downloading data (tile %d)..." % idx)
+        grass.verbose("Requesting data: %s" % self.options['mapserver'])
+        grass.verbose(url)
+
+        if not self.flags['g']: # -> post
+            try:
+                urllib.urlretrieve(url, output, data="POST")
+            except IOError:
+                grass.fatal("Failed while downloading the data")
+            
+            if not os.path.exists(output):
+                grass.fatal("Failed while downloading the data")
+
+            # work-around for brain-dead ArcIMS servers which want POST-data as part of the GET URL
+            #   (this is technically allowed by OGC WMS def v1.3.0 Sec6.3.4)
+            if os.path.getsize(output) == 0:
+                grass.warning("Downloaded image file is empty -- trying another method")
+                self.flags['g'] = True
+        
+        if self.flags['g']: # -> get
+            try:
+                urllib.urlretrieve(url, output, data="GET")
+            except IOError:
+                grass.fatal("Failed while downloading the data")
+            
+            if not os.path.exists(output) or os.path.getsize(output) == 0:
+                grass.fatal("Failed while downloading the data")
+        


Property changes on: grass/trunk/scripts/r.in.wms/wms_download.py
___________________________________________________________________
Name: svn:mime-type
   + text/x-python
Name: svn:keywords
   + Author Date Id
Name: svn:eol-style
   + native

Added: grass/trunk/scripts/r.in.wms/wms_request.py
===================================================================
--- grass/trunk/scripts/r.in.wms/wms_request.py	                        (rev 0)
+++ grass/trunk/scripts/r.in.wms/wms_request.py	2009-05-08 13:41:22 UTC (rev 37049)
@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+
+############################################################################
+#
+# MODULE:       r.in.wms
+#
+# AUTHOR(S):    Cedric Shock, 2006
+#               Pythonized by Martin Landa <landa.martin gmail.com>, 2009
+#
+# PURPOSE:      To import data from web mapping servers
+#               (based on Bash script by Cedric Shock)
+#
+# COPYRIGHT:    (C) 2009 Martin Landa, and GRASS development team
+#
+#               This program is free software under the GNU General
+#               Public License (>=v2). Read the file COPYING that
+#               comes with GRASS for details.
+#
+#############################################################################
+
+import os
+import glob
+import grass
+
+class WMSRequest:
+    def __init__(self, flags, options):
+        self.flags   = flags
+        self.options = options
+
+        self.__set_options()
+        
+    def __set_options(self):
+        # If the user asserts that this projection is the same as the
+        # source use this projection as the source to get a trivial
+        # tiling from r.tileset
+        if self.flags['p']:
+            self.proj_srs = grass.read_command('g.proj', flags='j')
+            self.srs_scale = int(grass.parse_key_val(proj_srs['+to_meter']))
+        else:
+            self.proj_srs = '+init=%s' % self.options['srs'].lower()
+            self.srs_scale = 1
+
+        # options for r.tileset
+        self.tileset_options = grass.parse_key_val(self.options['tileoptions'])
+        if self.options['region']:
+            self.tileset_options['region'] = self.options['region']
+        
+        # set transparency
+        if self.flags['o']:
+            self.transparency = "transparent=FALSE"
+        else:
+            self.transparency = "transparent=FALSE"
+
+        # image format
+        format_opt = self.options['format']
+        if format_opt == "geotiff":
+            self.format      = "image/geotiff"
+            self.worldfile   = ".tfw"
+            self.file_extent = ".geotiff"
+        elif format_opt == "tiff":
+            self.format      = "image/tiff"
+            self.worldfile   = ".tfw"
+            self.file_extent = ".tiff"
+        elif format_opt == "png":
+            self.format      = "image/png"
+            self.worldfile   = ".pgw"
+            self.file_extent = ".png"
+        elif format_opt == "jpeg":
+            self.format      = "image/jpeg"
+            self.worldfile   = ".jgw"
+            self.file_extent = ".jpeg"
+        elif format_opt == "gif":
+            self.format      = "image/gif"
+            self.worldfile   = ".gfw"
+            self.file_extent = ".gif"
+        else:
+            grass.fatal("Uknown image format '%s'" % format_opt)
+
+        # create download directory
+        if not os.path.exists(self.options['folder']):
+            os.mkdir(self.options['folder'])
+        
+        # clean files
+        self._tdir = os.path.join(self.options['folder'], self.options['output'],
+                            self.options['region'])
+
+        self.request_file = os.path.join(self._tdir, 'request')
+
+    def GetRequestFile(self):
+        return self.request_file
+    
+    def GetRequests(self):
+        ret = []
+        rf = open(self.request_file)
+        try:
+            for line in rf.readlines():
+                ret.append(grass.parse_key_val(line, vsep = ';'))
+        finally:
+            rf.close()
+
+        return ret
+
+    def GetTiles(self):
+        grass.message("Calculating tiles...")
+        tiles = grass.read_command('r.tileset',
+                                quiet = True,
+                                flags = 'g',
+                                sourceproj = self.proj_srs,
+                                sourcescale = self.srs_scale,
+                                overlap = 2,
+                                maxcols = int(self.options['maxcols']),
+                                maxrows = int(self.options['maxrows']),
+                                **self.tileset_options)
+        if not tiles:
+            grass.fatal("r.tileset failed")
+        tiles = tiles.splitlines()
+        grass.message("Requesting %d tiles" % len(tiles))
+        
+        if self.flags['c']:
+            rmfiles = os.path.join(self._tdir, '*')
+            grass.verbose("Removing files '%s'" % rmfiles)
+            for file in glob.glob(rmfiles):
+                if os.path.isdir(file):
+                    os.rmdir(file)
+                else:
+                    os.remove(file)
+
+        rf = open(self.request_file, 'w')
+        i = 0
+        for tile in tiles:
+            outputfile = os.path.join(self._tdir, str(i) + self.file_extent)
+            worldfile = os.path.join(self._tdir, str(i) + self.worldfile)
+            dtile = grass.parse_key_val(tile, vsep=';')
+            n = float(dtile['n'])
+            s = float(dtile['s'])
+            e = float(dtile['e'])
+            w = float(dtile['w'])
+            nr = int(dtile['rows'])
+            nc = int(dtile['cols'])
+
+            size = "bbox=%f,%f,%f,%f&width=%d&height=%d" % \
+                (w, s, e, n, nr, nc)
+            xres = (e - w) / nc
+            yres = (s - n) / nr
+            # center of top left cell
+            top_left_cell_center_x = w + xres / 2
+            top_left_cell_center_y = n + yres / 2
+
+            # write the world file
+            wf = open(worldfile, 'w')
+            try:
+                wf.write("%f\n0.0\n0.0\n%f\n%f\n%f\n" % \
+                             (xres, yres, top_left_cell_center_x, top_left_cell_center_y))
+            finally:
+                wf.close()
+
+            # request for data
+            string = "request=GetMap&layers=%s&srs=%s&%s&format=%s&%s&%s" % \
+                (self.options['layers'], self.options['srs'],
+                 size, self.format, self.transparency, self.options['wmsquery'])
+            if self.options['styles']:
+                string += "&styles=%s" % self.options['styles']
+            rf.write('output=%s;server=%s;string=%s\n' % \
+                         (outputfile, self.options['mapserver'], string))
+            i += 1
+        
+        rf.close()


Property changes on: grass/trunk/scripts/r.in.wms/wms_request.py
___________________________________________________________________
Name: svn:mime-type
   + text/x-python
Name: svn:keywords
   + Author Date Id
Name: svn:eol-style
   + native



More information about the grass-commit mailing list