[GRASS-SVN] r52470 - grass/trunk/scripts/r.in.wms
svn_grass at osgeo.org
svn_grass at osgeo.org
Sat Jul 28 02:19:22 PDT 2012
Author: martinl
Date: 2012-07-28 02:19:22 -0700 (Sat, 28 Jul 2012)
New Revision: 52470
Added:
grass/trunk/scripts/r.in.wms/wms_base.py
grass/trunk/scripts/r.in.wms/wms_drv.py
grass/trunk/scripts/r.in.wms/wms_gdal_drv.py
Removed:
grass/trunk/scripts/r.in.wms/gdalwarp.py
grass/trunk/scripts/r.in.wms/r.in.gdalwarp.py
grass/trunk/scripts/r.in.wms/wms_download.py
grass/trunk/scripts/r.in.wms/wms_gdal.py
grass/trunk/scripts/r.in.wms/wms_parse.py
grass/trunk/scripts/r.in.wms/wms_request.py
Modified:
grass/trunk/scripts/r.in.wms/Makefile
grass/trunk/scripts/r.in.wms/r.in.wms.html
grass/trunk/scripts/r.in.wms/r.in.wms.py
Log:
r.in.wms replaced by new version from grass-addons (r.in.wms2)
Module `r.in.wms2` has been written by Stepan Turek (bachelor project)
Modified: grass/trunk/scripts/r.in.wms/Makefile
===================================================================
--- grass/trunk/scripts/r.in.wms/Makefile 2012-07-28 09:08:59 UTC (rev 52469)
+++ grass/trunk/scripts/r.in.wms/Makefile 2012-07-28 09:19:22 UTC (rev 52470)
@@ -1,16 +1,18 @@
MODULE_TOPDIR = ../..
-PGM=r.in.wms
+PGM = r.in.wms
+MODULES = wms_base wms_drv wms_gdal_drv
+PYFILES := $(patsubst %,$(ETC)/%.py,$(MODULES))
+PYCFILES := $(patsubst %,$(ETC)/%.pyc,$(MODULES))
+
include $(MODULE_TOPDIR)/include/Make/Script.make
+include $(MODULE_TOPDIR)/include/Make/Python.make
-SRCFILES = wms_parse.py wms_request.py wms_download.py gdalwarp.py r.in.gdalwarp.py wms_gdal.py
-DSTFILES := $(patsubst %,$(ETC)/r.in.wms/%,$(SRCFILES))
+default: script $(PYFILES) $(PYCFILES)
-default: script $(DSTFILES)
+$(ETCDIR):
+ $(MKDIR) $@
-$(ETC)/r.in.wms/%: % | $(ETC)/r.in.wms
- $(INSTALL) $< $@
-
-$(ETC)/r.in.wms:
- $(MKDIR) $@
+$(ETC)/%: % | $(ETC)
+ $(INSTALL_DATA) $< $@
Deleted: grass/trunk/scripts/r.in.wms/gdalwarp.py
===================================================================
--- grass/trunk/scripts/r.in.wms/gdalwarp.py 2012-07-28 09:08:59 UTC (rev 52469)
+++ grass/trunk/scripts/r.in.wms/gdalwarp.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -1,353 +0,0 @@
-############################################################################
-#
-# MODULE: r.in.wms / wms_gdalwarp.py
-#
-# AUTHOR(S): Cedric Shock, 2006
-# Update for GRASS 7 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.
-#
-#############################################################################
-
-#
-# This file needs major rewrite...
-#
-
-import os
-import subprocess
-
-from grass.script import core as grass
-
-class GDALWarp:
- def __init__(self, flags, options):
- self.flags = flags
- self.options = options
-
- self.tmp = grass.tempfile()
-
- self.suffixes = []
- self.patches = []
- self.maplist = []
- self.tiler = 0
-
- if not flags['p']:
- # todo: check if gdalwarp is available
- pass
-
- # flags for r.in.gdal
- self.gdal_flags = ''
- if flags['e']:
- self.gdal_flags += 'e'
- if flags['k']:
- self.gdal_flags += 'k'
-
- def run(self):
- # import tiles
- tiler = 0
- for input in self.options['input'].split(','):
- tmptilename = self.options['output'] + '_tile_' + str(tiler)
- if not os.path.exists(input):
- grass.warning(_("Missing input '%s'") % input)
- continue
- grass.info(_("Importing tile '%s'...") % os.path.basename(input))
- if self.flags['p']:
- self.nowarp_import(input, tmptilename)
- else:
- self.warp_import(input, tmptilename)
-
- self.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(self.channel_suffixes) > 0:
- # multi-band
- for suffix in self.channel_suffixes:
- # rename tile 0 to be the output
- ffile = self.options['output'] + '_tile_0' + suffix
- tfile = self.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 = self.options['output'] + '_tile_0' # + sfx ?
- tfile = self.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 = self.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 = self.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 = 0
- for suffix in self.suffixes:
- if suffix in ('.red', '.green', '.blue'):
- colors += 1
-
- # make a composite image if asked for and colors exist
- if colors == 3 and self.flags['c']:
- grass.message(_("Building color image <%s>...") % self.options['output'])
- if grass.run_command('r.composite',
- quiet = True,
- red = self.options['output'] + '.red',
- green = self.options['output'] + '.green',
- blue = self.options['output'] + '.blue',
- output = self.options['output']) != 0:
- grass.fatal(_('r.composite failed'))
-
- return 0
-
- def warp_import(self, file, map):
- """Wrap raster file using gdalwarp and import wrapped file
- into GRASS"""
- warpfile = self.tmp + 'warped.geotiff'
- tmpmapname = map + '_tmp'
-
- t_srs = grass.read_command('g.proj',
- quiet = True,
- flags = 'jf').rstrip('\n')
- if not t_srs:
- grass.fatal(_('g.proj failed'))
-
- grass.debug("gdalwarp -s_srs '%s' -t_srs '%s' -r %s %s %s %s" % \
- (self.options['srs'], t_srs,
- self.options['method'], self.options['warpoptions'],
- file, warpfile))
- grass.verbose("Warping input file '%s'..." % os.path.basename(file))
- if self.options['warpoptions']:
- ps = subprocess.Popen(['gdalwarp',
- '-s_srs', '%s' % self.options['srs'],
- '-t_srs', '%s' % t_srs,
- '-r', self.options['method'],
- self.options['warpoptions'],
- file, warpfile])
- else:
- ps = subprocess.Popen(['gdalwarp',
- '-s_srs', '%s' % self.options['srs'],
- '-t_srs', '%s' % t_srs,
- '-r', self.options['method'],
- file, warpfile])
-
- ps.wait()
- if ps.returncode != 0 or \
- not os.path.exists(warpfile):
- grass.fatal(_('gdalwarp failed'))
-
- # import it into a temporary map
- grass.info(_('Importing raster map...'))
- if grass.run_command('r.in.gdal',
- quiet = True, overwrite = True,
- flags = self.gdal_flags,
- input = warpfile,
- output = tmpmapname) != 0:
- grass.fatal(_('r.in.gdal failed'))
-
- os.remove(warpfile)
-
- # get list of channels
- pattern = tmpmapname + '*'
- grass.debug('Pattern: %s' % pattern)
- mapset = grass.gisenv()['MAPSET']
- channel_list = grass.mlist_grouped(type = 'rast', pattern = pattern)[mapset]
- grass.debug('Channel list: %s' % ','.join(channel_list))
-
- if len(channel_list) < 2: # test for single band data
- self.channel_suffixes = []
- else:
- self.channel_suffixes = channel_list # ???
-
- grass.debug('Channel suffixes: %s' % ','.join(self.channel_suffixes))
-
- # add to the list of all suffixes
- self.suffixes = self.suffixes + self.channel_suffixes
- self.suffixes.sort()
-
- # get last suffix
- if len(self.channel_suffixes) > 0:
- last_suffix = self.channel_suffixes[-1]
- else:
- last_suffix = ''
-
- # find the alpha layer
- if self.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', name = alphalayer)['name']:
- alphalayer = ''
-
- # calculate the new maps:
- for suffix in self.channel_suffixes:
- grass.debug("alpha=%s MAPsfx=%s%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 self.tiler == 0:
- self.patches = []
- self.patches = self.patches.append(map + suffix)
-
- # if no suffix, processing is simple (e.g. elevation has only 1
- # band)
- if len(channel_list) < 2:
- # 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 = ','.join(channel_list)) != 0:
- grass.fatal(_('g.remove failed'))
-
- def nowarp_import(self, file, map):
- """Import raster file into GRASS"""
- if grass.run_command('r.in.gdal',
- quiet = True, overwrite = True,
- flags = 'o' + self.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
- self.channel_suffixes = []
- else:
- self.channel_suffixes = channel_list # ???
-
- # add to the list of all suffixes:
- self.suffixes = self.suffixes + channel.suffixes
- self.suffixes.sort()
-
- for suffix in self.channel_suffixes:
- # make patch lists
- suffix = suffix.replace('.', '_')
- # this is a hack to make the patch lists empty
- if self.tiler == 0:
- self.patches = []
- self.patches = self.patches.append(map + suffix)
-
-
Deleted: grass/trunk/scripts/r.in.wms/r.in.gdalwarp.py
===================================================================
--- grass/trunk/scripts/r.in.wms/r.in.gdalwarp.py 2012-07-28 09:08:59 UTC (rev 52469)
+++ grass/trunk/scripts/r.in.wms/r.in.gdalwarp.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -1,101 +0,0 @@
-#!/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
-#% keywords: rotate
-#% keywords: 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 G_OPT_F_INPUT
-#% label: Name of raster file or files to be imported
-#% description: If multiple files are specified they will be patched together.
-#% multiple: yes
-#%end
-#%option
-#% key: output
-#% type: string
-#% label: Prefix for resultant raster maps.
-#% description: 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:near,bilinear,cubic,cubicspline
-#% answer:near
-#% required: yes
-#%end
-#%option
-#% key: warpoptions
-#% type: string
-#% description: Additional options for gdalwarp
-#% required : no
-#%end
-
-import os
-import sys
-import atexit
-
-from grass.script import core as grass
-
-path = os.path.join(os.getenv('GISBASE'), 'etc', 'r.in.wms')
-sys.path.append(path)
-import gdalwarp
-
-def cleanup():
- if tmp:
- grass.run_command('g.remove', rast = tmp, quiet = True)
-
-def main():
- # show progress infromation and grass.info() by default
- os.environ['GRASS_VERBOSE'] = '1'
-
- return gdalwarp.GDALWarp(flags, options).run()
-
-if __name__ == "__main__":
- options, flags = grass.parser()
- tmp = None
- atexit.register(cleanup)
-
- sys.exit(main())
Modified: grass/trunk/scripts/r.in.wms/r.in.wms.html
===================================================================
--- grass/trunk/scripts/r.in.wms/r.in.wms.html 2012-07-28 09:08:59 UTC (rev 52469)
+++ grass/trunk/scripts/r.in.wms/r.in.wms.html 2012-07-28 09:19:22 UTC (rev 52470)
@@ -1,7 +1,7 @@
<h2>DESCRIPTION</h2>
-<em>r.in.wms</em> handles all of downloading and importing raster data
-from an <a href="http://www.opengeospatial.org/standards/wms">OGC
+<em>r.in.wms2</em> handles all of downloading and importing raster
+data from an <a href="http://www.opengeospatial.org/standards/wms">OGC
WMS</a> web mapping server. It need only be told the desired data to
collect (bounds and resolution) via a region, the server to get the
data from, and the layer or layers to get. It downloads the data in
@@ -9,8 +9,10 @@
<h2>NOTES</h2>
+<!--
By default data is downloaded to <tt>$GISDBASE/wms_download</tt>. This can be changed
by setting the <b>folder</b> option when using <em>r.in.wms</em>.
+-->
<p>To understand the data you are getting it is necessary to look at the
capabilities of the WMS server. This should be available via a capabilities
@@ -18,120 +20,57 @@
<a href="http://wms.jpl.nasa.gov/wms.cgi?request=GetCapabilities">example
capabilities request to NASA's OnEarth server</a>.
-<p><!--
-Some brain-dead servers will only talk to certain web browsers. You can
-fool these by adding <tt>- -user-agent=MSIE5.5</tt> to <b>wgetoptions</b>
-or for curl adding <tt>-A "MSIE5.5"</tt> to <b>curloptions</b>.
--->
-Other brain-dead servers will not accept queries in the form of POST data.
-If you get an error try using the <b>-g</b> flag to force <em>r.in.wms</em>
-to send an atomic GET request instead.
-
<h2>EXAMPLES</h2>
<h3>General Get Capabilities Request</h3>
-A capabilities request like
-<a href="http://wms.jpl.nasa.gov/wms.cgi?request=GetCapabilities">http://wms.jpl.nasa.gov/wms.cgi?request=GetCapabilities</a>
-is where you should start. It tells you what data is offered, the projections
-it is in, where to find meta data, resolutions, scales, and bounds for
-data, etc.
-
-E.g. lists the layers available from the NASA OnEarth server.
-
<div class="code"><pre>
-r.in.wms mapserver=http://wms.jpl.nasa.gov/wms.cgi -l
+r.in.wms2 -c mapserver=http://wms.cuzk.cz/wms.asp
</pre></div>
-<h3>US NED Elevation from OnEarth server download (metric units)</h3>
+<h3>CUZK download</h3>
-Set the resolution to 30 (assuming you're in metric units):
-<div class="code"><pre>
-g.region res=30 -ap
-r.in.wms -o output=elevation_meters mapserver=http://wms.jpl.nasa.gov/wms.cgi \
- layers=us_ned styles=real
-</pre></div>
-Downloads real number meter elevation from OnEarth to cover the current
-region. Uses <b>-o</b> for opaque to get smaller download.
+World extend data:
-<h3>US NED Elevation from OnEarth server download (feet units)</h3>
-
-Set the resolution to 90 (assuming you're in feet units) a save this
-region with a name; this makes resuming downloads possible or rather
-easier:
-
<div class="code"><pre>
-g.region res=90 -ap
-g.region save=panhandle-90ft
-
-r.in.wms -o output=elevation_feet mapserver=http://wms.jpl.nasa.gov/wms.cgi \
- layers=us_ned styles=feet_real region=panhandle-90ft
+r.in.wms2 mapserver=http://iceds.ge.ucl.ac.uk/cgi-bin/icedswms layers=bluemarble,landsat_1_01 styles=default,default output=landsat srs=4326 format=png
</pre></div>
+* Server supports only WMS 1.1.1 <br>
-Downloads real number feet elevation from OnEarth to cover the current
-region. Uses <b>-o</b> for opaque to get smaller download. Using a named
-region lets us resume later easily.
-
<div class="code"><pre>
-r.in.wms -d output=elevation_feet mapserver=http://wms.jpl.nasa.gov/wms.cgi \
- layers=us_ned styles=feet_real -o region=panhandle-90ft method=cubic
+r.in.wms2 mapserver=http://132.156.97.59/cgi-bin/worldmin_en-ca_ows layers=GSC:WORLD_PrecambrianDomains output=pokus srs=4326 format=jpeg
</pre></div>
+* Server supports only WMS 1.1.1
+<br>
+<br>
-Use flag <b>-d</b> to skip ahead to downloading. This could be used to try
-downloading again (if some files failed last time) or to import the data
-differently. Since downloaded files are remembered those already received
-successfully are not re-requested. In this case we are reimporting the
-data using the cubic interpolation method instead of nearest neighbor.
+Data in extend of Czech Republic:
-<h3>LANDSAT from OnEarth server download</h3>
-
-Set the resolution to 30 meters for LANDSAT:
<div class="code"><pre>
-g.region res=30 -ap
-r.in.wms layers=global_mosaic mapserver=http://wms.jpl.nasa.gov/wms.cgi \
- output=wms_global_mosaic
+r.in.wms2 output=kn mapserver=http://wms.cuzk.cz/wms.asp layers=prehledka_kraju-linie srs=4326 format=png
</pre></div>
-Downloads LANDSAT color scene.
-<h3>DRG from Terraserver server download</h3>
-
-Set the resolution to 1.2 meters for DRGs. Their native resolution is
-2.4 meters, so this is some pretty hefty oversampling:
-
-<div class="code"><pre>
-g.region res=1.2 -ap
-g.region save=drg-resolution
-
-r.in.wms output=terraserver-drg mapserver=http://terraserver.microsoft.com/ogcmap6.ashx \
- layers=DRG region=drg-resolution format=jpeg srs=EPSG:26910
-</pre></div>
-
-Downloads digital raster graphics from Microsoft TerraServer. Note that
-srs will need to be changed to a projection that is appropriate for your
-region.
-
<h2>TODO</h2>
<ul>
- <li>Use optionally <a href="http://gdal.osgeo.org/frmt_wms.html">GDAL WMS driver</a></li>
+ <li>Implement Tiled WMS</li>
</ul>
<h2>SEE ALSO</h2>
<em>
-<a href="r.tileset.html">r.tileset</a>,
-<a href="r.in.gdal.html">r.in.gdal</a>,
-<a href="r.patch.html">r.patch</a>,
-<a href="r.colors.html">r.colors</a>,
-<a href="r.composite.html">r.composite</a><br><br>
-<a href="v.in.wfs.html">v.in.wfs</a>
+ <a href="r.in.gdal.html">r.in.gdal</a>,
+ <a href="r.patch.html">r.patch</a>,
+ <a href="r.colors.html">r.colors</a>,
+ <a href="r.composite.html">r.composite</a>,
+ <a href="v.in.wfs.html">v.in.wfs</a>
</em>
<h2>AUTHORS</h2>
-Soeren Gebbert, Jachym Cepicky, and Cedric Shock<br>
-Updated for GRASS 7 by Martin Landa, CTU in Prague, Czech Republic (05/2009)
+Stepan Turek, Czech Technical University in Prague, Czech Republic (bachelor's final project 2012, mentor: Martin Landa)
-<p><i>Last changed: $Date$</i>
+<p>
+<i>Last changed: $Date$</i>
Modified: grass/trunk/scripts/r.in.wms/r.in.wms.py
===================================================================
--- grass/trunk/scripts/r.in.wms/r.in.wms.py 2012-07-28 09:08:59 UTC (rev 52469)
+++ grass/trunk/scripts/r.in.wms/r.in.wms.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -1,282 +1,161 @@
#!/usr/bin/env python
+"""
+MODULE: r.in.wms2
-############################################################################
-#
-# MODULE: r.in.wms
-#
-# AUTHOR(S): Cedric Shock, 2006
-# Upgraded for GRASS 7 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.
-#
-#############################################################################
+AUTHOR(S): Stepan Turek <stepan.turek AT seznam.cz>
+PURPOSE: Downloads and imports data from WMS server.
+
+COPYRIGHT: (C) 2012 Stepan Turek, and 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 and imports data from WMS servers.
-#% keywords: raster
-#% keywords: import
-#% keywords: wms
+#% description: Downloads and imports data from WMS servers.
+#% keywords: raster
+#% keywords: import
+#% 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
-#%flag
-#% key: a
-#% description: Use GDAL WMS driver
-#% guisection: Request
-#%end
-#%option G_OPT_R_OUTPUT
-#% required : no
-#% guisection: Import
-#%end
+
#%option
#% key: mapserver
#% type: string
-#% description: Mapserver to request data from
+#% description:URL of WMS server
#% required: yes
-#% guisection: Request
#%end
+
#%option
#% key: layers
#% type: string
#% description: Layers to request from map server
#% multiple: yes
-#% required: no
-#% guisection: Request
+#% required: yes
#%end
-#%option
-#% key: styles
-#% type: string
-#% description: Styles to request from map server
-#% multiple: yes
-#% required: no
-#% guisection: Request
+
+#%option G_OPT_R_OUTPUT
+#% description: Name for output raster map
#%end
+
#%option
#% key: srs
+#% type: integer
+#% description: EPSG number of source projection for request
+#% guisection: Request properties
+#%end
+
+#%option
+#% key: region
#% type: string
-#% description: Source projection to request from server
-#% answer:EPSG:4326
-#% guisection: Request
+#% description: Named region to request data for. Current region used if omitted
+#% guisection: Request properties
#%end
+
#%option
+#% key: wms_version
+#% type:string
+#% description:WMS standard
+#% options:1.1.1,1.3.0
+#% answer:1.1.1
+#% guisection: Request properties
+#%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
+#% guisection: Request properties
#%end
+
#%option
-#% key: wmsquery
-#% type:string
-#% description: Addition query options for server
-#% answer: version=1.1.1
-#% guisection: Request
+#% key: method
+#% type: string
+#% description: Reprojection method to use
+#% options:near,bilinear,cubic,cubicspline
+#% answer:near
+#% guisection: Request properties
#%end
+
#%option
#% key: maxcols
-#% type: integer
+#% type:integer
#% description: Maximum columns to request at a time
-#% answer: 1024
-#% required : yes
-#% guisection: Request
+#% answer:400
+#% guisection: Request properties
#%end
+
#%option
#% key: maxrows
#% type: integer
#% description: Maximum rows to request at a time
-#% answer: 1024
-#% required : yes
-#% guisection: Request
+#% answer: 300
+#% guisection: Request properties
#%end
+
#%option
-#% key: tileoptions
-#% type: string
-#% description: Additional options for r.tileset
-#% required : no
+#% key: urlparams
+#% type:string
+#% description: Addition query parameters for server (only with 'd' flag)
+#% guisection: Request properties
#%end
+
#%option
-#% key: region
+#% key: styles
#% type: string
-#% description: Named region to request data for. Current region used if omitted
-#% required : no
-#% guisection: Request
+#% description: Styles to request from map server
+#% multiple: yes
+#% guisection: Map style
#%end
+
#%option
-#% key: folder
+#% key: bgcolor
#% type: string
-#% description: Folder to save downloaded data to (default $GISDBASE/wms_download)
-#% required : no
-#% guisection: Download
+#% description: Color of map background (only with 'd' flag)
+#% guisection: Map style
#%end
-#%option
-#% key: method
-#% type: string
-#% description: Reprojection method to use
-#% options:near,bilinear,cubic,cubicspline
-#% answer:near
-#% required: yes
-#% guisection: Import
+
+#%flag
+#% key: o
+#% description: Don't request transparent data
+#% guisection: Map style
#%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
+
+#%flag
+#% key: c
+#% description: Get capabilities
+#% guisection: Request properties
+#% suppress_required: yes
#%end
+#%flag
+#% key: d
+#% description: Do not use GDAL WMS driver
+#%end
+
import os
import sys
-import tempfile
-import urllib
-import xml.sax
+sys.path.insert(1, os.path.join(os.path.dirname(sys.path[0]), 'etc', 'r.in.wms2'))
import grass.script as grass
-wmsPath = os.path.join(os.getenv('GISBASE'), 'etc', 'r.in.wms')
-sys.path.append(wmsPath)
-try:
- import wms_parse
- import wms_request
- import wms_download
- import gdalwarp
- import wms_gdal
-except ImportError:
- pass
-
-def list_layers():
- """Get list of 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'])
- url = options['mapserver'] + '?' + qstring
- try:
- if options['cap_file']:
- cap_file, headers = urllib.urlretrieve(url, options['cap_file'])
- else:
- cap_file = urllib.urlopen(url, options['mapserver'] + '?' + qstring)
- except IOError:
- grass.fatal(_("Unable to get capabilities of '%s'") % options['mapserver'])
-
- # check DOCTYPE first
- if options['cap_file']:
- if headers['content-type'] != 'application/vnd.ogc.wms_xml':
- grass.fatal(_("Unable to get capabilities: %s") % url)
+def main():
+ if flags['d']:
+ grass.debug("Using own driver")
+ from wms_drv import WMSDrv
+ wms = WMSDrv()
else:
- if cap_file.info()['content-type'] != 'application/vnd.ogc.wms_xml':
- grass.fatal(_("Unable to get capabilities: %s") % url)
-
- # parse file with sax
- cap_xml = wms_parse.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)
+ grass.debug("Using GDAL WMS driver")
+ from wms_gdal_drv import WMSGdalDrv
+ wms = WMSGdalDrv()
- 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"))
-
- if options['cap_file'] and not flags['l']:
- grass.warning(_("Option <cap_file> ignored. It requires '-l' flag."))
-
- # 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'])
-
- request = wms_request.WMSRequest(flags, options)
- if not flags['d']:
- # request data first
- request.GetTiles()
- if not request:
- grass.fatal(_("WMS request failed"))
-
- if flags['a']:
- # use GDAL WMS driver
- ### TODO: use GDAL Python bindings instead
- if not wms_gdal.checkGdalWms():
- grass.fatal(_("GDAL WMS driver is not available"))
-
- # create local service description XML file
- gdalWms = wms_gdal.GdalWms(options, request)
- options['input'] = gdalWms.GetFile()
+ if flags['c']:
+ wms.GetCapabilities(options)
else:
- # download data
- download = wms_download.WMSDownload(flags, options)
- download.GetTiles(request.GetRequests())
+ wms.GetMap(options, flags)
- # list of files
- files = []
- for item in request.GetRequests():
- files.append(item['output'])
- files = ','.join(files)
- options['input'] = files
-
- # add flags for r.in.gdalwarp
- flags['e'] = False
- flags['c'] = True
- options['warpoptions'] = ''
-
- return gdalwarp.GDALWarp(flags, options).run()
-
return 0
if __name__ == "__main__":
Added: grass/trunk/scripts/r.in.wms/wms_base.py
===================================================================
--- grass/trunk/scripts/r.in.wms/wms_base.py (rev 0)
+++ grass/trunk/scripts/r.in.wms/wms_base.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -0,0 +1,396 @@
+import os
+from math import ceil
+
+import xml.etree.ElementTree as etree
+from urllib2 import urlopen, HTTPError, URLError
+
+import grass.script as grass
+
+class WMSBase:
+ def __init__(self):
+ # these variables are information for destructor
+ self.temp_files_to_cleanup = []
+ self.cleanup_mask = False
+ self.cleanup_layers = False
+
+ self.bbox = None
+ self.temp_map = None
+
+ def __del__(self):
+ # removes temporary mask, used for import transparent or warped temp_map
+ if self.cleanup_mask:
+ # clear temporary mask, which was set by module
+ if grass.run_command('r.mask',
+ quiet = True,
+ flags = 'r') != 0:
+ grass.fatal(_('%s failed') % 'r.mask')
+
+ # restore original mask, if exists
+ if grass.find_file(self.o_output + self.original_mask_suffix, element = 'cell', mapset = '.' )['name']:
+ if grass.run_command('g.copy',
+ quiet = True,
+ rast = self.o_output + self.original_mask_suffix + ',MASK') != 0:
+ grass.fatal(_('%s failed') % 'g.copy')
+
+ # tries to remove temporary files, all files should be
+ # removoved before, implemented just in case of unexpected
+ # stop of module
+ for temp_file in self.temp_files_to_cleanup:
+ grass.try_remove(temp_file)
+
+ # remove temporary created rasters
+ if self.cleanup_layers:
+ maps = []
+ for suffix in ('.red', '.green', '.blue', '.alpha', self.original_mask_suffix):
+ rast = self.o_output + suffix
+ if grass.find_file(rast, element = 'cell', mapset = '.')['file']:
+ maps.append(rast)
+
+ if maps:
+ grass.run_command('g.remove',
+ quiet = True,
+ flags = 'f',
+ rast = ','.join(maps))
+
+ # deletes enviromental variable which overrides region
+ if 'GRASS_REGION' in os.environ.keys():
+ os.environ.pop('GRASS_REGION')
+
+ def _debug(self, fn, msg):
+ grass.debug("%s.%s: %s" %
+ (self.__class__.__name__, fn, msg))
+
+ def _initializeParameters(self, options, flags):
+ self._debug("_initialize_parameters", "started")
+
+ # inicialization of module parameters (options, flags)
+ self.flags = flags
+ if self.flags['o']:
+ self.transparent = 'FALSE'
+ else:
+ self.transparent = 'TRUE'
+
+ self.o_mapserver_url = options['mapserver'].strip() + "?"
+ self.o_layers = options['layers'].strip()
+ self.o_styles = options['styles'].strip()
+ self.o_output = options['output']
+ self.o_method = options['method']
+
+ self.o_bgcolor = options['bgcolor'].strip()
+ if self.o_bgcolor != "" and not flags["d"]:
+ grass.warning(_("Parameter bgcolor ignored, use -d flag"))
+
+ self.o_urlparams = options['urlparams'].strip()
+ if self.o_urlparams != "" and not flags["d"]:
+ grass.warning(_("Parameter urlparams ignored, use -d flag"))
+
+ self.o_wms_version = options['wms_version']
+ if self.o_wms_version == "1.3.0":
+ self.projection_name = "CRS"
+ else:
+ self.projection_name = "SRS"
+
+ self.o_format = options['format']
+ if self.o_format == "geotiff":
+ self.mime_format = "image/geotiff"
+ elif self.o_format == "tiff":
+ self.mime_format = "image/tiff"
+ elif self.o_format == "png":
+ self.mime_format = "image/png"
+ elif self.o_format == "jpeg":
+ self.mime_format = "image/jpeg"
+ if flags['o']:
+ grass.warning(_("JPEG format does not support transparency"))
+ elif self.o_format == "gif":
+ self.mime_format = "image/gif"
+ else:
+ self.mime_format = self.o_format
+
+ self.o_srs = int(options['srs'])
+ if self.o_srs <= 0:
+ grass.fatal(_("Invalid EPSG code %d") % self.o_srs)
+
+ # read projection info
+ self.proj_location = grass.read_command('g.proj',
+ flags ='jf').rstrip('\n')
+
+ self.proj_srs = grass.read_command('g.proj',
+ flags = 'jf',
+ epsg = str(self.o_srs) ).rstrip('\n')
+
+ if not self.proj_srs or not self.proj_location:
+ grass.fatal(_("Unable to get projection info"))
+
+ # set region
+ self.o_region = options['region']
+ if self.o_region:
+ if not grass.find_file(name = self.o_region, element = 'windows', mapset = '.' )['name']:
+ grass.fatal(_("Region <%s> not found") % self.o_region)
+
+ if self.o_region:
+ s = grass.read_command('g.region',
+ quiet = True,
+ flags = 'ug',
+ region = self.o_region)
+ self.region = grass.parse_key_val(s, val_type = float)
+ else:
+ self.region = grass.region()
+
+ min_tile_size = 100
+ self.o_maxcols = int(options['maxcols'])
+ if self.o_maxcols <= min_tile_size:
+ grass.fatal(_("Maxcols must be greater than 100"))
+
+ self.o_maxrows = int(options['maxrows'])
+ if self.o_maxrows <= min_tile_size:
+ grass.fatal(_("Maxrows must be greater than 100"))
+
+ # setting optimal tile size according to maxcols and maxrows constraint and region cols and rows
+ self.tile_cols = int(self.region['cols'] / ceil(self.region['cols'] / float(self.o_maxcols)))
+ self.tile_rows = int(self.region['rows'] / ceil(self.region['rows'] / float(self.o_maxrows)))
+
+ # suffix for existing mask (during overriding will be saved
+ # into raster named:self.o_output + this suffix)
+ self.original_mask_suffix = "_temp_MASK"
+
+ # check names of temporary rasters, which module may create
+ maps = []
+ for suffix in ('.red', '.green', '.blue', '.alpha', self.original_mask_suffix ):
+ rast = self.o_output + suffix
+ if grass.find_file(rast, element = 'cell', mapset = '.')['file']:
+ maps.append(rast)
+
+ if len(maps) != 0:
+ grass.fatal(_("Please change output name, or change names of these rasters: %s, "
+ "module needs to create this temporary maps during runing") % ",".join(maps))
+
+ # default format for GDAL library
+ self.gdal_drv_format = "GTiff"
+
+ self._debug("_initialize_parameters", "finished")
+
+ def GetMap(self, options, flags):
+ """!Download data from WMS server and import data
+ (using GDAL library) into GRASS as a raster map."""
+
+ self._initializeParameters(options, flags)
+
+ self.bbox = self._computeBbox()
+
+ self.temp_map = self._download()
+
+ self._createOutputMap()
+
+ def GetCapabilities(self, options):
+ """!Get capabilities from WMS server
+ """
+ # download capabilities file
+ cap_url = options['mapserver'] + "?service=WMS&request=GetCapabilities&version=" + options['wms_version']
+ try:
+ cap = urlopen(cap_url)
+ except IOError:
+ grass.fatal(_("Unable to get capabilities from '%s'") % options['mapserver'])
+
+ cap_lines = cap.readlines()
+ for line in cap_lines:
+ print line
+
+ def _computeBbox(self):
+ """!Get region extent for WMS query (bbox)
+ """
+ self._debug("_computeBbox", "started")
+
+ bbox_region_items = {'maxy' : 'n', 'miny' : 's', 'maxx' : 'e', 'minx' : 'w'}
+ bbox = {}
+
+ if self.proj_srs == self.proj_location: # TODO: do it better
+ for bbox_item, region_item in bbox_region_items.iteritems():
+ bbox[bbox_item] = self.region[region_item]
+
+ # if location projection and wms query projection are
+ # different, corner points of region are transformed into wms
+ # projection and then bbox is created from extreme coordinates
+ # of the transformed points
+ else:
+ for bbox_item, region_item in bbox_region_items.iteritems():
+ bbox[bbox_item] = None
+
+ temp_region = self._tempfile()
+
+ try:
+ temp_region_opened = open(temp_region, 'w')
+ temp_region_opened.write("%f %f\n%f %f\n%f %f\n%f %f\n" %\
+ (self.region['e'], self.region['n'],\
+ self.region['w'], self.region['n'],\
+ self.region['w'], self.region['s'],\
+ self.region['e'], self.region['s'] ))
+ except IOError:
+ grass.fatal(_("Unable to write data into tempfile"))
+ finally:
+ temp_region_opened.close()
+
+ points = grass.read_command('m.proj', flags = 'd',
+ proj_output = self.proj_srs,
+ proj_input = self.proj_location,
+ input = temp_region) # TODO: stdin
+ grass.try_remove(temp_region)
+ if not points:
+ grass.fatal(_("Unable to determine region, %s failed") % 'm.proj')
+
+ points = points.splitlines()
+ if len(points) != 4:
+ grass.fatal(_("Region defintion: 4 points required"))
+
+ for point in points:
+ point = map(float, point.split("|"))
+ if not bbox['maxy']:
+ bbox['maxy'] = point[1]
+ bbox['miny'] = point[1]
+ bbox['maxx'] = point[0]
+ bbox['minx'] = point[0]
+ continue
+
+ if bbox['maxy'] < point[1]:
+ bbox['maxy'] = point[1]
+ elif bbox['miny'] > point[1]:
+ bbox['miny'] = point[1]
+
+ if bbox['maxx'] < point[0]:
+ bbox['maxx'] = point[0]
+ elif bbox['minx'] > point[0]:
+ bbox['minx'] = point[0]
+
+ self._debug("_computeBbox", "finished -> %s" % bbox)
+
+ # Ordering of coordinates axis of geographic coordinate
+ # systems in WMS 1.3.0 is fliped. If self.flip_coords is
+ # True, coords in bbox need to be flipped in WMS query.
+
+ self.flip_coords = False
+ hasLongLat = self.proj_srs.find("+proj=longlat")
+ hasLatLong = self.proj_srs.find("+proj=latlong")
+
+ if (hasLongLat != -1 or hasLatLong != -1) and self.o_wms_version == "1.3.0":
+ self.flip_coords = True
+
+ return bbox
+
+ def _createOutputMap(self):
+ """!Import downloaded data into GRASS, reproject data if needed
+ using gdalwarp
+ """
+ # reprojection of raster
+ if self.proj_srs != self.proj_location: # TODO: do it better
+ grass.message(_("Reprojecting raster..."))
+ temp_warpmap = self._tempfile()
+
+ if int(os.getenv('GRASS_VERBOSE', '2')) <= 2:
+ nuldev = file(os.devnull, 'w+')
+ else:
+ nuldev = None
+
+ # RGB rasters - alpha layer is added for cropping edges of projected raster
+ if self.temp_map_bands_num == 3:
+ ps = grass.Popen(['gdalwarp',
+ '-s_srs', '%s' % self.proj_srs,
+ '-t_srs', '%s' % self.proj_location,
+ '-r', self.o_method, '-dstalpha',
+ self.temp_map, temp_warpmap], stdout = nuldev)
+ # RGBA rasters
+ else:
+ ps = grass.Popen(['gdalwarp',
+ '-s_srs', '%s' % self.proj_srs,
+ '-t_srs', '%s' % self.proj_location,
+ '-r', self.o_method,
+ self.temp_map, temp_warpmap], stdout = nuldev)
+ ps.wait()
+
+ if nuldev:
+ nuldev.close()
+
+ if ps.returncode != 0:
+ grass.fatal(_('%s failed') % 'gdalwarp')
+ # raster projection is same as projection of location
+ else:
+ temp_warpmap = self.temp_map
+
+ grass.message(_("Importing raster map into GRASS..."))
+ # importing temp_map into GRASS
+ if grass.run_command('r.in.gdal',
+ quiet = True,
+ input = temp_warpmap,
+ output = self.o_output) != 0:
+ grass.fatal(_('%s failed') % 'r.in.gdal')
+
+ # information for destructor to cleanup temp_layers, created
+ # with r.in.gdal
+ self.cleanup_layers = True
+
+ # setting region for full extend of imported raster
+ os.environ['GRASS_REGION'] = grass.region_env(rast = self.o_output + '.red')
+
+ # mask created from alpha layer, which describes real extend
+ # of warped layer (may not be a rectangle), also mask contains
+ # transparent parts of raster
+ if grass.find_file( self.o_output + '.alpha', element = 'cell', mapset = '.' )['name']:
+ # saving current mask (if exists) into temp raster
+ if grass.find_file('MASK', element = 'cell', mapset = '.' )['name']:
+ if grass.run_command('g.copy',
+ quiet = True,
+ rast = 'MASK,' + self.o_output + self.original_mask_suffix) != 0:
+ grass.fatal(_('%s failed') % 'g.copy')
+
+ # info for destructor
+ self.cleanup_mask = True
+ if grass.run_command('r.mask',
+ quiet = True,
+ overwrite = True,
+ maskcats = "0",
+ flags = 'i',
+ input = self.o_output + '.alpha') != 0:
+ grass.fatal(_('%s failed') % 'r.mask')
+
+ if grass.run_command('r.composite',
+ quiet = True,
+ red = self.o_output + '.red',
+ green = self.o_output + '.green',
+ blue = self.o_output + '.blue',
+ output = self.o_output ) != 0:
+ grass.fatal(_('%s failed') % 'r.composite')
+
+ grass.try_remove(temp_warpmap)
+ grass.try_remove(self.temp_map)
+
+ def _flipBbox(self, bbox):
+ """
+ flips items in dictionary
+ value flips between this keys:
+ maxy -> maxx
+ maxx -> maxy
+ miny -> minx
+ minx -> miny
+ @return copy of bbox with fliped cordinates
+ """
+ temp_bbox = dict(bbox)
+ new_bbox = {}
+ new_bbox['maxy'] = temp_bbox['maxx']
+ new_bbox['miny'] = temp_bbox['minx']
+ new_bbox['maxx'] = temp_bbox['maxy']
+ new_bbox['minx'] = temp_bbox['miny']
+
+ return new_bbox
+
+ def _tempfile(self):
+ """!Create temp_file and append list self.temp_files_to_cleanup
+ with path of file
+
+ @return string path to temp_file
+ """
+ temp_file = grass.tempfile()
+ if temp_file is None:
+ grass.fatal(_("Unable to create temporary files"))
+
+ # list of created tempfiles for destructor
+ self.temp_files_to_cleanup.append(temp_file)
+
+ return temp_file
Property changes on: grass/trunk/scripts/r.in.wms/wms_base.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Deleted: grass/trunk/scripts/r.in.wms/wms_download.py
===================================================================
--- grass/trunk/scripts/r.in.wms/wms_download.py 2012-07-28 09:08:59 UTC (rev 52469)
+++ grass/trunk/scripts/r.in.wms/wms_download.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -1,69 +0,0 @@
-############################################################################
-#
-# MODULE: r.in.wms / wms_download.py
-#
-# AUTHOR(S): Cedric Shock, 2006
-# Updated for GRASS 7 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
-
-from grass.script import core as 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.verbose("Tile already downloaded")
- else:
- self.GetData(i, item['server'], item['string'], item['output'])
- i += 1
-
- def GetData(self, idx, server, query, output):
- """Download data"""
- grass.message(_("Downloading data (tile %d)...") % idx)
- grass.verbose("Requesting data: %s" % self.options['mapserver'])
-
- if not self.flags['g']: # -> post
- try:
- urllib.urlretrieve(server, output, data = query)
- 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(server + '?' + query, output, data = None)
- 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"))
-
Added: grass/trunk/scripts/r.in.wms/wms_drv.py
===================================================================
--- grass/trunk/scripts/r.in.wms/wms_drv.py (rev 0)
+++ grass/trunk/scripts/r.in.wms/wms_drv.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -0,0 +1,222 @@
+try:
+ from osgeo import gdal
+ from osgeo import gdalconst
+except:
+ grass.fatal(_("Unable to load GDAL python bindings"))
+
+from urllib2 import urlopen
+
+import numpy as Numeric
+Numeric.arrayrange = Numeric.arange
+
+import grass.script as grass
+
+from wms_base import WMSBase
+
+class WMSDrv(WMSBase):
+ def _download(self):
+ """!Downloads data from WMS server using own driver
+
+ @return temp_map with stored downloaded data
+ """
+ grass.message(_("Downloading data from WMS server..."))
+
+
+ proj = self.projection_name + "=EPSG:"+ str(self.o_srs)
+ url = self.o_mapserver_url + "REQUEST=GetMap&VERSION=%s&LAYERS=%s&WIDTH=%s&HEIGHT=%s&STYLES=%s&BGCOLOR=%s&TRANSPARENT=%s" %\
+ (self.o_wms_version, self.o_layers, self.tile_cols, self.tile_rows, self.o_styles, self.o_bgcolor, self.transparent)
+ url += "&" +proj+ "&" + "FORMAT=" + self.mime_format
+
+ if self.o_urlparams != "":
+ url +="&" + self.o_urlparams
+
+ cols = int(self.region['cols'])
+ rows = int(self.region['rows'])
+
+ # computes parameters of tiles
+ num_tiles_x = cols / self.tile_cols
+ last_tile_x_size = cols % self.tile_cols
+ tile_x_length = float(self.tile_cols) / float(cols ) * (self.bbox['maxx'] - self.bbox['minx'])
+
+ last_tile_x = False
+ if last_tile_x_size != 0:
+ last_tile_x = True
+ num_tiles_x = num_tiles_x + 1
+
+ num_tiles_y = rows / self.tile_rows
+ last_tile_y_size = rows % self.tile_rows
+ tile_y_length = float(self.tile_rows) / float(rows) * (self.bbox['maxy'] - self.bbox['miny'])
+
+ last_tile_y = False
+ if last_tile_y_size != 0:
+ last_tile_y = True
+ num_tiles_y = num_tiles_y + 1
+
+ # each tile is downloaded and written into temp_map
+ tile_bbox = dict(self.bbox)
+ tile_bbox['maxx'] = self.bbox['minx'] + tile_x_length
+
+ tile_to_temp_map_size_x = self.tile_cols
+ for i_x in range(num_tiles_x):
+ # set bbox for tile i_x,i_y (E, W)
+ if i_x != 0:
+ tile_bbox['maxx'] += tile_x_length
+ tile_bbox['minx'] += tile_x_length
+
+ if i_x == num_tiles_x - 1 and last_tile_x:
+ tile_to_temp_map_size_x = last_tile_x_size
+
+ tile_bbox['maxy'] = self.bbox['maxy']
+ tile_bbox['miny'] = self.bbox['maxy'] - tile_y_length
+ tile_to_temp_map_size_y = self.tile_rows
+
+ for i_y in range(num_tiles_y):
+ # set bbox for tile i_x,i_y (N, S)
+ if i_y != 0:
+ tile_bbox['miny'] -= tile_y_length
+ tile_bbox['maxy'] -= tile_y_length
+
+ if i_y == num_tiles_y - 1 and last_tile_y:
+ tile_to_temp_map_size_y = last_tile_y_size
+
+ if self.flip_coords:
+ # flips coordinates if WMS strandard is 1.3.0 and
+ # projection is geographic (see:wms_base.py _computeBbox)
+ query_bbox = dict(self._flipBbox(tile_bbox))
+ else:
+ query_bbox = tile_bbox
+
+ query_url = url + "&" + "BBOX=%s,%s,%s,%s" % ( query_bbox['minx'], query_bbox['miny'], query_bbox['maxx'], query_bbox['maxy'])
+ grass.debug(query_url)
+ try:
+ wms_data = urlopen(query_url)
+ except IOError:
+ grass.fatal(_("Unable to fetch data from mapserver"))
+
+ temp_tile = self._tempfile()
+
+ # download data into temporary file
+ try:
+ temp_tile_opened = open(temp_tile, 'w')
+ temp_tile_opened.write(wms_data.read())
+ except IOError:
+ grass.fatal(_("Unable to write data into tempfile"))
+ finally:
+ temp_tile_opened.close()
+
+ tile_dataset_info = gdal.Open(temp_tile, gdal.GA_ReadOnly)
+ if tile_dataset_info is None:
+ # print error xml returned from server
+ try:
+ error_xml_opened = open(temp_tile, 'r')
+ err_str = error_xml_opened.read()
+ except IOError:
+ grass.fatal(_("Unable to read data from tempfile"))
+ finally:
+ error_xml_opened.close()
+
+ if err_str is not None:
+ grass.fatal(_("WMS server error: %s") % err_str)
+ else:
+ grass.fatal(_("WMS server unknown error") )
+
+ band = tile_dataset_info.GetRasterBand(1)
+ cell_type_func = band.__swig_getmethods__["DataType"]#??
+ bands_number_func = tile_dataset_info.__swig_getmethods__["RasterCount"]
+
+ ##### see original r.in.wms - file gdalwarp.py line 117 ####
+ temp_tile_pct2rgb = None
+ if bands_number_func(tile_dataset_info) == 1 and band.GetRasterColorTable() is not None:
+ # expansion of color table into bands
+ temp_tile_pct2rgb = self._tempfile()
+ tile_dataset = self._pct2rgb(temp_tile, temp_tile_pct2rgb)
+ else:
+ tile_dataset = tile_dataset_info
+
+ # initialization of temp_map_dataset, where all tiles are merged
+ if i_x == 0 and i_y == 0:
+ temp_map = self._tempfile()
+
+ driver = gdal.GetDriverByName(self.gdal_drv_format)
+ metadata = driver.GetMetadata()
+ if not metadata.has_key(gdal.DCAP_CREATE) or \
+ metadata[gdal.DCAP_CREATE] == 'NO':
+ grass.fatal(_('Driver %s does not supports Create() method') % drv_format)
+
+ self.temp_map_bands_num = bands_number_func(tile_dataset)
+ temp_map_dataset = driver.Create(temp_map, int(cols), int(rows),
+ self.temp_map_bands_num, cell_type_func(band));
+
+ # tile written into temp_map
+ tile_to_temp_map = tile_dataset.ReadRaster(0, 0, tile_to_temp_map_size_x, tile_to_temp_map_size_y,
+ tile_to_temp_map_size_x, tile_to_temp_map_size_y)
+
+ temp_map_dataset.WriteRaster(self.tile_cols * i_x, self.tile_rows * i_y,
+ tile_to_temp_map_size_x, tile_to_temp_map_size_y, tile_to_temp_map)
+
+ tile_dataset = None
+ tile_dataset_info = None
+ grass.try_remove(temp_tile)
+ grass.try_remove(temp_tile_pct2rgb)
+
+ # georeferencing and setting projection of temp_map
+ projection = grass.read_command('g.proj',
+ flags = 'wf',
+ epsg =self.o_srs).rstrip('\n')
+ temp_map_dataset.SetProjection(projection)
+
+
+
+ pixel_x_length = (self.bbox['maxx'] - self.bbox['minx']) / int(cols)
+ pixel_y_length = (self.bbox['miny'] - self.bbox['maxy']) / int(rows)
+ geo_transform = [ self.bbox['minx'] , pixel_x_length , 0.0 , self.bbox['maxy'] , 0.0 , pixel_y_length ]
+ temp_map_dataset.SetGeoTransform(geo_transform )
+ temp_map_dataset = None
+
+ return temp_map
+
+ def _pct2rgb(self, src_filename, dst_filename):
+ """!Create new dataset with data in dst_filename with bands according to src_filename
+ raster color table - modified code from gdal utility pct2rgb
+
+ @return new dataset
+ """
+ out_bands = 4
+ band_number = 1
+
+ # open source file
+ src_ds = gdal.Open(src_filename)
+ if src_ds is None:
+ grass.fatal(_('Unable to open %s ' % src_filename))
+
+ src_band = src_ds.GetRasterBand(band_number)
+
+ # Build color table
+ lookup = [ Numeric.arrayrange(256),
+ Numeric.arrayrange(256),
+ Numeric.arrayrange(256),
+ Numeric.ones(256)*255 ]
+
+ ct = src_band.GetRasterColorTable()
+ if ct is not None:
+ for i in range(min(256,ct.GetCount())):
+ entry = ct.GetColorEntry(i)
+ for c in range(4):
+ lookup[c][i] = entry[c]
+
+ # create the working file
+ gtiff_driver = gdal.GetDriverByName(self.gdal_drv_format)
+ tif_ds = gtiff_driver.Create(dst_filename,
+ src_ds.RasterXSize, src_ds.RasterYSize, out_bands)
+
+ # do the processing one scanline at a time
+ for iY in range(src_ds.RasterYSize):
+ src_data = src_band.ReadAsArray(0,iY,src_ds.RasterXSize,1)
+
+ for iBand in range(out_bands):
+ band_lookup = lookup[iBand]
+
+ dst_data = Numeric.take(band_lookup,src_data)
+ tif_ds.GetRasterBand(iBand+1).WriteArray(dst_data,0,iY)
+
+ return tif_ds
Property changes on: grass/trunk/scripts/r.in.wms/wms_drv.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Deleted: grass/trunk/scripts/r.in.wms/wms_gdal.py
===================================================================
--- grass/trunk/scripts/r.in.wms/wms_gdal.py 2012-07-28 09:08:59 UTC (rev 52469)
+++ grass/trunk/scripts/r.in.wms/wms_gdal.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -1,93 +0,0 @@
-############################################################################
-#
-# MODULE: r.in.wms / wms_gdal
-#
-# AUTHOR(S): Martin Landa <landa.martin gmail.com>
-#
-# PURPOSE: To import data from web mapping servers
-#
-# 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 subprocess
-
-def checkGdalWms():
- """Check if GDAL WMS driver is available"""
- ps = subprocess.Popen(['gdalinfo',
- '--formats'], stdout = subprocess.PIPE)
-
- for line in ps.communicate()[0].splitlines():
- driver, desc = line.split(':')
- if 'WMS' in driver:
- return True
-
- return False
-
-class GdalWms:
- def __init__(self, options, request):
- self.options = options
-
- # service description XML file path
- self.descFile = None
- self.__createDescFile(request)
-
- def __createDescFile(self, request):
- """Create local service description XML file"""
- # first create directory where to store XML file
- dir = os.path.join(self.options['folder'], self.options['output'])
- if not os.path.exists(self.options['folder']):
- os.mkdir(self.options['folder'])
- if not os.path.exists(dir):
- os.mkdir(dir)
-
- self.descFile = os.path.join(dir, self.options['output'] + '.xml')
- file = open(self.descFile, 'w')
- try:
- indent = 0
- file.write('<GDAL_WMS>\n')
- indent += 4
- file.write('%s<Service name="WMS">\n' % (' ' * indent))
- indent += 4
- if self.options['wmsquery'] and 'version=' in self.options['wmsquery']:
- for item in self.options['wmsquery'].split(';'):
- key, value = item.split('=')
- if key == 'version':
- file.write('%s<Version>%s</Version>\n' % (' ' * indent, value))
- break
- else:
- file.write('%s<Version>1.1.1</Version>\n' % (' ' * indent)) # -> default 1.1.1
- file.write('%s<ServerURL>%s?</ServerURL>\n' % (' ' * indent, self.options['mapserver']))
- file.write('%s<SRS>%s</SRS>\n' % (' ' * indent, self.options['srs']))
- file.write('%s<ImageFormat>image/%s</ImageFormat>\n' % (' ' * indent, self.options['format']))
- file.write('%s<Layers>%s</Layers>\n' % (' ' * indent, self.options['layers']))
- file.write('%s<Styles>%s</Styles>\n' % (' ' * indent, self.options['styles']))
- indent -= 4
- file.write('%s</Service>\n' % (' ' * indent))
- file.write('%s<DataWindow>\n' % (' ' * indent))
- indent += 4
- file.write('%s<UpperLeftX>%s</UpperLeftX>\n' % (' ' * indent, request.Get('w')))
- file.write('%s<UpperLeftY>%s</UpperLeftY>\n' % (' ' * indent, request.Get('n')))
- file.write('%s<LowerRightX>%s</LowerRightX>\n' % (' ' * indent, request.Get('e')))
- file.write('%s<LowerRightY>%s</LowerRightY>\n' % (' ' * indent, request.Get('s')))
- file.write('%s<SizeX>%s</SizeX>\n' % (' ' * indent, request.Get('width'))) #
- file.write('%s<SizeY>%s</SizeY>\n' % (' ' * indent, request.Get('height'))) #
- indent -= 4
- file.write('%s</DataWindow>\n' % (' ' * indent))
- file.write('%s<Projection>%s</Projection>\n' % (' ' * indent, self.options['srs']))
- file.write('%s<BandsCount>3</BandsCount>\n' % (' ' * indent))
- file.write('%s<BlockSizeX>%s</BlockSizeX>\n' % (' ' * indent, self.options['maxcols']))
- file.write('%s<BlockSizeY>%s</BlockSizeY>\n' % (' ' * indent, self.options['maxrows']))
- file.write('</GDAL_WMS>\n')
- finally:
- file.close()
-
- def GetFile(self):
- """Get path of service description XML file"""
- return self.descFile
-
Added: grass/trunk/scripts/r.in.wms/wms_gdal_drv.py
===================================================================
--- grass/trunk/scripts/r.in.wms/wms_gdal_drv.py (rev 0)
+++ grass/trunk/scripts/r.in.wms/wms_gdal_drv.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -0,0 +1,138 @@
+import os
+
+try:
+ from osgeo import gdal
+ from osgeo import gdalconst
+except:
+ grass.fatal(_("Unable to load GDAL Python bindings"))
+
+import xml.etree.ElementTree as etree
+
+import grass.script as grass
+
+from wms_base import WMSBase
+
+class NullDevice():
+ def write(self, s):
+ pass
+
+class WMSGdalDrv(WMSBase):
+ def _createXML(self):
+ """!Create XML for GDAL WMS driver
+
+ @return path to XML file
+ """
+ self._debug("_createXML", "started")
+
+ gdal_wms = etree.Element("GDAL_WMS")
+ service = etree.SubElement(gdal_wms, "Service")
+ name = etree.Element("name")
+ service.set("name","WMS")
+
+ version = etree.SubElement(service, "Version")
+ version.text =self.o_wms_version
+
+ server_url = etree.SubElement(service, "ServerUrl")
+ server_url.text =self.o_mapserver_url
+
+ srs = etree.SubElement(service, self.projection_name)
+ srs.text = 'EPSG:' + str(self.o_srs)
+
+ image_format = etree.SubElement(service, "ImageFormat")
+ image_format.text = self.mime_format
+
+ image_format = etree.SubElement(service, "Transparent")
+ image_format.text = self.transparent
+
+ layers = etree.SubElement(service, "Layers")
+ layers.text = self.o_layers
+
+ styles = etree.SubElement(service, "Styles")
+ styles.text = self.o_styles
+
+ data_window = etree.SubElement(gdal_wms, "DataWindow")
+
+ upper_left_x = etree.SubElement(data_window, "UpperLeftX")
+ upper_left_x.text = str(self.bbox['minx'])
+
+ upper_left_y = etree.SubElement(data_window, "UpperLeftY")
+ upper_left_y.text = str(self.bbox['maxy'])
+
+ lower_right_x = etree.SubElement(data_window, "LowerRightX")
+ lower_right_x.text = str(self.bbox['maxx'])
+
+ lower_right_y = etree.SubElement(data_window, "LowerRightY")
+ lower_right_y.text = str(self.bbox['miny'])
+
+ size_x = etree.SubElement(data_window, "SizeX")
+ size_x.text = str(self.region['cols'])
+
+ size_y = etree.SubElement(data_window, "SizeY")
+ size_y.text = str(self.region['rows'])
+
+ # RGB + alpha
+ self.temp_map_bands_num = 4
+ block_size_x = etree.SubElement(gdal_wms, "BandsCount")
+ block_size_x.text = str(self.temp_map_bands_num)
+
+ block_size_x = etree.SubElement(gdal_wms, "BlockSizeX")
+ block_size_x.text = str(self.tile_cols)
+
+ block_size_y = etree.SubElement(gdal_wms, "BlockSizeY")
+ block_size_y.text = str(self.tile_rows)
+
+ xml_file = self._tempfile()
+
+ etree.ElementTree(gdal_wms).write(xml_file)
+
+ self._debug("_createXML", "finished -> %s" % xml_file)
+
+ return xml_file
+
+ def _download(self):
+ """!Downloads data from WMS server using GDAL WMS driver
+
+ @return temp_map with stored downloaded data
+ """
+ grass.message("Downloading data from WMS server...")
+
+ # GDAL WMS driver does not flip geographic coordinates
+ # according to WMS standard 1.3.0.
+ if self.flip_coords and self.o_wms_version == "1.3.0":
+ grass.warning(_("If module will not be able to fetch the data in this\
+ geographic projection, \n try flag -d or use WMS version 1.1.1."))
+
+ self._debug("_download", "started")
+
+ temp_map = self._tempfile()
+
+ xml_file = self._createXML()
+ wms_dataset = gdal.Open(xml_file, gdal.GA_ReadOnly)
+ grass.try_remove(xml_file)
+ if wms_dataset is None:
+ grass.fatal(_("Unable to open GDAL WMS driver"))
+
+ self._debug("_download", "GDAL dataset created")
+
+ driver = gdal.GetDriverByName(self.gdal_drv_format)
+ if driver is None:
+ grass.fatal(_("Unable to find %s driver" % format))
+
+ metadata = driver.GetMetadata()
+ if not metadata.has_key(gdal.DCAP_CREATECOPY) or \
+ metadata[gdal.DCAP_CREATECOPY] == 'NO':
+ grass.fatal(_('Driver %s supports CreateCopy() method.') % self.gdal_drv_name)
+
+ self._debug("_download", "calling GDAL CreateCopy...")
+
+ temp_map_dataset = driver.CreateCopy(temp_map, wms_dataset, 0)
+
+ if temp_map_dataset is None:
+ grass.fatal(_("Incorrect WMS query"))
+
+ temp_map_dataset = None
+ wms_dataset = None
+
+ self._debug("_download", "finished")
+
+ return temp_map
Property changes on: grass/trunk/scripts/r.in.wms/wms_gdal_drv.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Deleted: grass/trunk/scripts/r.in.wms/wms_parse.py
===================================================================
--- grass/trunk/scripts/r.in.wms/wms_parse.py 2012-07-28 09:08:59 UTC (rev 52469)
+++ grass/trunk/scripts/r.in.wms/wms_parse.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -1,84 +0,0 @@
-############################################################################
-#
-# MODULE: r.in.wms / wms_parse
-#
-# AUTHOR(S): Cedric Shock, 2006
-# Upgraded for GRASS 7 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 xml.sax
-import xml.sax.handler
-HandlerBase=xml.sax.handler.ContentHandler
-from xml.sax import make_parser
-
-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 "\n\n-=-=-=-=-=-\n"
- if ly.has_key('name'):
- print "LAYER: " + ly['name']
- else:
- print "LAYER: unknown"
- 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]
Deleted: grass/trunk/scripts/r.in.wms/wms_request.py
===================================================================
--- grass/trunk/scripts/r.in.wms/wms_request.py 2012-07-28 09:08:59 UTC (rev 52469)
+++ grass/trunk/scripts/r.in.wms/wms_request.py 2012-07-28 09:19:22 UTC (rev 52470)
@@ -1,187 +0,0 @@
-############################################################################
-#
-# MODULE: r.in.wms / wms_request.py
-#
-# AUTHOR(S): Cedric Shock, 2006
-# Update for GRASS 7 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
-from grass.script import core as grass
-
-class WMSRequest:
- def __init__(self, flags, options):
- self.flags = flags
- self.options = options
-
- self.__set_options()
-
- self.data = {}
-
- 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')
- if not self.proj_srs:
- grass.fatal(_('g.proj failed'))
- 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'])
- odir = os.path.join(self.options['folder'], self.options['output'])
- if not os.path.exists(odir):
- os.mkdir(odir)
- self._tdir = os.path.join(self.options['folder'], self.options['output'],
- self.options['region'])
- if not os.path.exists(self._tdir):
- os.mkdir(self._tdir)
-
- 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()
-
- 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'])
- self.data['n'] = n
- s = float(dtile['s'])
- self.data['s'] = s
- e = float(dtile['e'])
- self.data['e'] = e
- w = float(dtile['w'])
- self.data['w'] = w
- nr = int(dtile['rows'])
- nc = int(dtile['cols'])
- self.data['width'] = nc
- self.data['height'] = nr
-
- size = "bbox=%f,%f,%f,%f&width=%d&height=%d" % \
- (w, s, e, n, nc, nr)
- 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 = "service=WMS&request=GetMap&layers=%s&styles=%s&srs=%s&%s&format=%s&%s&%s" % \
- (self.options['layers'], self.options['styles'], self.options['srs'],
- size, self.format, self.transparency, self.options['wmsquery'])
- rf.write('output=%s;server=%s;string=%s\n' % \
- (outputfile, self.options['mapserver'], string))
- i += 1
-
- rf.close()
- grass.message(_("Done: requesting %d tiles") % len(tiles))
- if len(tiles) > 200:
- grass.warning("Proceed with care. This number of tiles may \
- exceed the maximum command line arguments available from \
- the operating system later on in the r.in.gdalwarp step. \
- In addition it may be considered abusive behaivor by the \
- server providers - check their terms of use.")
-
-
- def Get(self, key):
- """Get value"""
- return self.data[key]
More information about the grass-commit
mailing list