Browse Source

r.in.wms: wms_gdal.py for GDAL WMS driver added
TODO: rewrite gdalwarp.py


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@37108 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa 16 years ago
parent
commit
15264ab749

+ 1 - 1
scripts/r.in.wms/Makefile

@@ -4,7 +4,7 @@ PGM=r.in.wms
 
 
 include $(MODULE_TOPDIR)/include/Make/Script.make
 include $(MODULE_TOPDIR)/include/Make/Script.make
 
 
-SRCFILES = wms_parse.py wms_request.py wms_download.py gdalwarp.py r.in.gdalwarp.py
+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))
 DSTFILES := $(patsubst %,$(ETC)/r.in.wms/%,$(SRCFILES))
 
 
 default: script
 default: script

+ 8 - 2
scripts/r.in.wms/gdalwarp.py

@@ -16,6 +16,10 @@
 #
 #
 #############################################################################
 #############################################################################
 
 
+#
+# This file needs major rewrite...
+#
+
 import os
 import os
 import subprocess
 import subprocess
 
 
@@ -206,7 +210,9 @@ class GDALWarp():
                                    '-r', self.options['method'],
                                    '-r', self.options['method'],
                                    file, warpfile])
                                    file, warpfile])
             
             
-        if ps.wait() != 0:
+        ps.wait()
+        if ps.returncode != 0 or \
+                not os.path.exists(warpfile):
             grass.fatal('gdalwarp failed')
             grass.fatal('gdalwarp failed')
     
     
         # import it into a temporary map
         # import it into a temporary map
@@ -256,7 +262,7 @@ class GDALWarp():
         
         
         # calculate the new maps:
         # calculate the new maps:
         for suffix in self.channel_suffixes:
         for suffix in self.channel_suffixes:
-            grass.debug("alpha=%s MAPsfx=%s% tmpname=%s%s" % \
+            grass.debug("alpha=%s MAPsfx=%s%s tmpname=%s%s" % \
                             (alphalayer, map, suffix, tmpmapname, suffix))
                             (alphalayer, map, suffix, tmpmapname, suffix))
             if alphalayer:
             if alphalayer:
                 # Use alpha channel for nulls: problem: I've seen a map
                 # Use alpha channel for nulls: problem: I've seen a map

+ 27 - 10
scripts/r.in.wms/r.in.wms.py

@@ -58,6 +58,11 @@
 #% description: This may be needed to connect to servers which lack POST capability
 #% description: This may be needed to connect to servers which lack POST capability
 #% guisection: Request
 #% guisection: Request
 #%end
 #%end
+#%flag
+#% key: a
+#% description: Use GDAL WMS driver
+#% guisection: Request
+#%end
 #%option
 #%option
 #% key: output
 #% key: output
 #% type: string
 #% type: string
@@ -170,7 +175,6 @@ import os
 import sys
 import sys
 import tempfile
 import tempfile
 import urllib
 import urllib
-
 import xml.sax
 import xml.sax
 
 
 import grass
 import grass
@@ -182,6 +186,7 @@ try:
     import wms_request
     import wms_request
     import wms_download
     import wms_download
     import gdalwarp
     import gdalwarp
+    import wms_gdal
 except ImportError:
 except ImportError:
     pass
     pass
 
 
@@ -246,23 +251,35 @@ def main():
     if not request:
     if not request:
         grass.fatal("WMS request failed")
         grass.fatal("WMS request failed")
     
     
-    # download data
-    download = wms_download.WMSDownload(flags, options)
-    download.GetTiles(request.GetRequests())
+    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()
+    else:
+        # 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)
+        # 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
     # add flags for r.in.gdalwarp
-    options['input'] = files
     flags['e'] = False
     flags['e'] = False
     flags['c'] = True
     flags['c'] = True
     options['warpoptions'] = ''
     options['warpoptions'] = ''
     
     
     return gdalwarp.GDALWarp(flags, options).run()
     return gdalwarp.GDALWarp(flags, options).run()
+    
+    return 0
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
     options, flags = grass.parser()
     options, flags = grass.parser()

+ 93 - 0
scripts/r.in.wms/wms_gdal.py

@@ -0,0 +1,93 @@
+############################################################################
+#
+# 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
+

+ 12 - 0
scripts/r.in.wms/wms_request.py

@@ -26,6 +26,8 @@ class WMSRequest:
         self.options = options
         self.options = options
         
         
         self.__set_options()
         self.__set_options()
+
+        self.data = {}
         
         
     def __set_options(self):
     def __set_options(self):
         # if the user asserts that this projection is the same as the
         # if the user asserts that this projection is the same as the
@@ -134,11 +136,17 @@ class WMSRequest:
             worldfile = os.path.join(self._tdir, str(i) + self.worldfile)
             worldfile = os.path.join(self._tdir, str(i) + self.worldfile)
             dtile = grass.parse_key_val(tile, vsep=';')
             dtile = grass.parse_key_val(tile, vsep=';')
             n = float(dtile['n'])
             n = float(dtile['n'])
+            self.data['n'] = n
             s = float(dtile['s'])
             s = float(dtile['s'])
+            self.data['s'] = s
             e = float(dtile['e'])
             e = float(dtile['e'])
+            self.data['e'] = e
             w = float(dtile['w'])
             w = float(dtile['w'])
+            self.data['w'] = w
             nr = int(dtile['rows'])
             nr = int(dtile['rows'])
             nc = int(dtile['cols'])
             nc = int(dtile['cols'])
+            self.data['width'] = nc
+            self.data['height'] = nr
             
             
             size = "bbox=%f,%f,%f,%f&width=%d&height=%d" % \
             size = "bbox=%f,%f,%f,%f&width=%d&height=%d" % \
                 (w, s, e, n, nc, nr)
                 (w, s, e, n, nc, nr)
@@ -166,3 +174,7 @@ class WMSRequest:
             
             
         rf.close()
         rf.close()
         grass.message("Done: requesting %d tiles" % len(tiles))
         grass.message("Done: requesting %d tiles" % len(tiles))
+
+    def Get(self, key):
+        """Get value"""
+        return self.data[key]