123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- ############################################################################
- #
- # 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]
|