wms_request.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. ############################################################################
  2. #
  3. # MODULE: r.in.wms / wms_request.py
  4. #
  5. # AUTHOR(S): Cedric Shock, 2006
  6. # Update for GRASS 7 by Martin Landa <landa.martin gmail.com>, 2009
  7. #
  8. # PURPOSE: To import data from web mapping servers
  9. # (based on Bash script by Cedric Shock)
  10. #
  11. # COPYRIGHT: (C) 2009 Martin Landa, and GRASS development team
  12. #
  13. # This program is free software under the GNU General
  14. # Public License (>=v2). Read the file COPYING that
  15. # comes with GRASS for details.
  16. #
  17. #############################################################################
  18. import os
  19. import glob
  20. import grass
  21. class WMSRequest:
  22. def __init__(self, flags, options):
  23. self.flags = flags
  24. self.options = options
  25. self.__set_options()
  26. def __set_options(self):
  27. # if the user asserts that this projection is the same as the
  28. # source use this projection as the source to get a trivial
  29. # tiling from r.tileset
  30. if self.flags['p']:
  31. self.proj_srs = grass.read_command('g.proj', flags='j')
  32. if not self.proj_srs:
  33. grass.fatal('g.proj failed')
  34. self.srs_scale = int(grass.parse_key_val(proj_srs['+to_meter']))
  35. else:
  36. self.proj_srs = '+init=%s' % self.options['srs'].lower()
  37. self.srs_scale = 1
  38. # options for r.tileset
  39. self.tileset_options = grass.parse_key_val(self.options['tileoptions'])
  40. if self.options['region']:
  41. self.tileset_options['region'] = self.options['region']
  42. # set transparency
  43. if self.flags['o']:
  44. self.transparency = "transparent=FALSE"
  45. else:
  46. self.transparency = "transparent=FALSE"
  47. # image format
  48. format_opt = self.options['format']
  49. if format_opt == "geotiff":
  50. self.format = "image/geotiff"
  51. self.worldfile = ".tfw"
  52. self.file_extent = ".geotiff"
  53. elif format_opt == "tiff":
  54. self.format = "image/tiff"
  55. self.worldfile = ".tfw"
  56. self.file_extent = ".tiff"
  57. elif format_opt == "png":
  58. self.format = "image/png"
  59. self.worldfile = ".pgw"
  60. self.file_extent = ".png"
  61. elif format_opt == "jpeg":
  62. self.format = "image/jpeg"
  63. self.worldfile = ".jgw"
  64. self.file_extent = ".jpeg"
  65. elif format_opt == "gif":
  66. self.format = "image/gif"
  67. self.worldfile = ".gfw"
  68. self.file_extent = ".gif"
  69. else:
  70. grass.fatal("Uknown image format '%s'" % format_opt)
  71. # create download directory
  72. if not os.path.exists(self.options['folder']):
  73. os.mkdir(self.options['folder'])
  74. odir = os.path.join(self.options['folder'], self.options['output'])
  75. if not os.path.exists(odir):
  76. os.mkdir(odir)
  77. self._tdir = os.path.join(self.options['folder'], self.options['output'],
  78. self.options['region'])
  79. if not os.path.exists(self._tdir):
  80. os.mkdir(self._tdir)
  81. self.request_file = os.path.join(self._tdir, 'request')
  82. def GetRequestFile(self):
  83. return self.request_file
  84. def GetRequests(self):
  85. ret = []
  86. rf = open(self.request_file)
  87. try:
  88. for line in rf.readlines():
  89. ret.append(grass.parse_key_val(line, vsep = ';'))
  90. finally:
  91. rf.close()
  92. return ret
  93. def GetTiles(self):
  94. grass.message("Calculating tiles...")
  95. tiles = grass.read_command('r.tileset',
  96. quiet = True,
  97. flags = 'g',
  98. sourceproj = self.proj_srs,
  99. sourcescale = self.srs_scale,
  100. overlap = 2,
  101. maxcols = int(self.options['maxcols']),
  102. maxrows = int(self.options['maxrows']),
  103. **self.tileset_options)
  104. if not tiles:
  105. grass.fatal("r.tileset failed")
  106. tiles = tiles.splitlines()
  107. if self.flags['c']:
  108. rmfiles = os.path.join(self._tdir, '*')
  109. grass.verbose("Removing files '%s'" % rmfiles)
  110. for file in glob.glob(rmfiles):
  111. if os.path.isdir(file):
  112. os.rmdir(file)
  113. else:
  114. os.remove(file)
  115. rf = open(self.request_file, 'w')
  116. i = 0
  117. for tile in tiles:
  118. outputfile = os.path.join(self._tdir, str(i) + self.file_extent)
  119. worldfile = os.path.join(self._tdir, str(i) + self.worldfile)
  120. dtile = grass.parse_key_val(tile, vsep=';')
  121. n = float(dtile['n'])
  122. s = float(dtile['s'])
  123. e = float(dtile['e'])
  124. w = float(dtile['w'])
  125. nr = int(dtile['rows'])
  126. nc = int(dtile['cols'])
  127. size = "bbox=%f,%f,%f,%f&width=%d&height=%d" % \
  128. (w, s, e, n, nc, nr)
  129. xres = (e - w) / nc
  130. yres = (s - n) / nr
  131. # center of top left cell
  132. top_left_cell_center_x = w + xres / 2
  133. top_left_cell_center_y = n + yres / 2
  134. # write the world file
  135. wf = open(worldfile, 'w')
  136. try:
  137. wf.write("%f\n0.0\n0.0\n%f\n%f\n%f\n" % \
  138. (xres, yres, top_left_cell_center_x, top_left_cell_center_y))
  139. finally:
  140. wf.close()
  141. # request for data
  142. string = "service=WMS&request=GetMap&layers=%s&styles=%s&srs=%s&%s&format=%s&%s&%s" % \
  143. (self.options['layers'], self.options['styles'], self.options['srs'],
  144. size, self.format, self.transparency, self.options['wmsquery'])
  145. rf.write('output=%s;server=%s;string=%s\n' % \
  146. (outputfile, self.options['mapserver'], string))
  147. i += 1
  148. rf.close()
  149. grass.message("Done: requesting %d tiles" % len(tiles))