[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