joey: thuban/Extensions/wms wms.py,1.2,1.3

cvs@intevation.de cvs at intevation.de
Sat Apr 10 21:08:01 CEST 2004


Author: joey

Update of /thubanrepository/thuban/Extensions/wms
In directory doto:/tmp/cvs-serv18556

Modified Files:
	wms.py 
Log Message:
Incorporate WMSCapabilities from capabilities.py and parser.py.
Implement priority list for supported graphics formats, take care of
  wbmp != bmp.  PNG, TIFF and GIF are supported here, but not yet by
  main Thuban.  Hence, support for them may be removed later.
Special contribution to usability: get wxWidgets to change the cursor
    when we're waiting for data from the network so the user won't
    start to worry.  This causes a redrawing error/warning, though.

Index: wms.py
===================================================================
RCS file: /thubanrepository/thuban/Extensions/wms/wms.py,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- wms.py	20 Feb 2004 20:09:25 -0000	1.2
+++ wms.py	10 Apr 2004 19:07:59 -0000	1.3
@@ -40,6 +40,7 @@
 from Thuban import _
 import Thuban.UI.baserenderer
 
+from capabilities import WMSCapabilities
 
 def epsg_code_to_projection(epsg):
     """Find the projection for the given epsg code.
@@ -62,7 +63,7 @@
         return (_("Extension: %s") % self.title,
                 [ object.TreeInfo() for object in self.objects ])
 
-class WMSLayer(BaseLayer, WMSClient):
+class WMSLayer(BaseLayer):
 
     def __init__(self, title, url):
         """Initializes the WMSLayer.
@@ -79,38 +80,50 @@
         self.latlonbbox = None
         self.error_msg = None
         self.layer_name = None
+        self.capabilities = None
 
-        wms_response = self.getCapabilities(self.url, '1.0')
-        self._capa_dom = xml.dom.minidom.parseString(wms_response)
+        # Change the cursor to demonstrate that we're busy but working
+        wxBeginBusyCursor()
+        self.capabilities = WMSCapabilities(url)
+        wxEndBusyCursor()
 
-        root = self._capa_dom.documentElement
-        cap = root.getElementsByTagName('Capability')[0]
-        layer = cap.getElementsByTagName('Layer')[0]
+        # name of the top layer of the remote map
+        foo = self.capabilities.getLayers()
+        if len(foo) == 0:
+            self.error_msg = _('No layers found in remote resource:\n'\
+                               '%s') % url
+            return
+        top_layer = foo[0]
+        self.layer_name = top_layer
 
-        # get projected bounding box and latlon bounding box
-        for node in layer.childNodes:
-            if node.nodeName == 'BoundingBox':
-                minx = node.attributes.get('minx').nodeValue
-                miny = node.attributes.get('miny').nodeValue
-                maxx = node.attributes.get('maxx').nodeValue
-                maxy = node.attributes.get('maxy').nodeValue
-                self.bbox = (float(minx), float(miny), float(maxx), float(maxy))
-        bbox = layer.getElementsByTagName('LatLonBoundingBox')[0]
-        self.layer_name = layer.getElementsByTagName('Name')[0].childNodes[0].data
-        minx = bbox.attributes.get('minx').nodeValue
-        miny = bbox.attributes.get('miny').nodeValue
-        maxx = bbox.attributes.get('maxx').nodeValue
-        maxy = bbox.attributes.get('maxy').nodeValue
-        self.latlonbbox = (float(minx), float(miny), float(maxx), float(maxy))
+        # first projection of the top layer
+        foo = self.capabilities.getLayerSRS(top_layer)
+        if len(foo) == 0:
+            self.error_msg = _('No LatLonBoundingBox found for top layer %s')\
+                             % top_layer
+            return
+        top_srs = foo[0]
 
-        # get projection
-        srs = layer.getElementsByTagName('SRS')[0].childNodes[0].data
-        if len(srs.split(':')) == 1:
-            epsg_id = srs
-        else:
-            epsg_id = srs.split(':')[1]
+        # BoundingBox of the top layer
+        bbox = self.capabilities.getLayerBBox(top_layer, top_srs)
+        if len(bbox) == 0:
+            self.error_msg = _('No BoundingBox found for layer %s and EPSG:')\
+                             % (top_layer, top_srs)
+            return
+        self.bbox = (float(bbox['minx']),
+                     float(bbox['miny']),
+                     float(bbox['maxx']),
+                     float(bbox['maxy']))
 
-        p = epsg_code_to_projection(epsg_id)
+        # LatLonBox of the top layer
+        bbox = self.capabilities.getLayerLatLonBBox(top_layer)
+        self.latlonbbox = (float(bbox['minx']),
+                           float(bbox['miny']),
+                           float(bbox['maxx']),
+                           float(bbox['maxy']))
+
+        # get projection
+        p = epsg_code_to_projection(top_srs)
         self.SetProjection(p)
 
         if p is None:
@@ -119,11 +132,17 @@
                                'Please set an appropriate projection yourself.'\
                                % epsg_id)
 
-        # get title
-        title = layer.getElementsByTagName('Title')[0].childNodes[0].data
-        self.SetTitle(title.encode('latin1', 'replace'))
+        # pre-determine the used format
+        self.wmsformat, self.format = \
+            self.calcFormat(self.capabilities.getFormats())
+        if self.wmsformat is None:
+            self.error_msg = \
+                _('No supported image format found in remote resource')
+            return
+
+        # get and set the title
+        self.SetTitle(self.capabilities.getTitle().encode('latin1', 'replace'))
 
-        self._capa_dom.unlink()
 
     def LatLongBoundingBox(self):
         """Return the layer's bounding box in lat-lon.
@@ -135,15 +154,77 @@
         """
         return self.bbox
 
+
+    def getFormat(self, format):
+        """
+        Return the image format for the render engine
+
+        format -- format as returned by the WMS server
+
+        If no mapping was found, None is returned
+
+        An exception rule is implemented in order to not accept
+        image/wbmp or WBMP which refers to WAP bitmap format and is
+        not supported by the included render engine.
+        """
+        fmap = {'png' : "PNG",
+                'jpeg': "JPEG",
+                'jpg' : "JPEG",
+                'tif' : "TIFF",
+                'gif' : "GIF",
+                'wbmp': None,
+                'bmp' : "BMP"}
+
+        for f in fmap.keys():
+            if format.lower().find(f) > -1:
+                    return fmap[f]
+        return None
+
+        
+    def calcFormat(self, formats):
+        """
+        Calculate the preferred image format
+
+        formats -- list of formates as returned by the WMS server
+
+        The following priority is used:
+        - PNG
+        - JPEG
+        - TIFF
+        - GIF
+        - BMP
+
+        If no matching format was found, None, None will be returned.
+
+        An exception rule is implemented in order to not accept
+        image/wbmp or WBMP which refers to WAP bitmap format and is
+        not supported by the included render engine.
+        """
+        prio = ['png', 'jpeg', 'jpg', 'tif', 'gif', 'bmp']
+        for p in prio:
+            for f in formats:
+                if f.lower().find(p) > -1:
+                    if f.lower().find('wbmp') == -1:
+                        return f, self.getFormat(f)
+        return None, None
+        
+
     def GetMapImg(self, width, height, bbox):
         bbox_dict = { 'minx': bbox[0], 'miny': bbox[1],
                       'maxx': bbox[2], 'maxy': bbox[3] }
+
+        # Change the cursor to demonstrate that we're busy but working
+        wxBeginBusyCursor()
+
+        wmsclient = WMSClient()
+
         epsg_id = int(self.GetProjection().EPSGCode())
-        wms_response = self.getMap(self.url, 'JPEG', width, height,
-                                   epsg_id, bbox_dict,
-                                   [self.layer_name], version = '1.0')
-        return wms_response
 
+        wms_response = wmsclient.getMap(self.url, self.wmsformat, width, height,
+                                   epsg_id, bbox_dict,
+                                   [self.layer_name], version = self.capabilities.getVersion())
+        wxEndBusyCursor()
+        return wms_response, self.format
 
 
 def render_wms_layer(renderer, layer):
@@ -156,8 +237,8 @@
     xmax = (width - offx) / scale
     ymax = (offy - 0) / scale
 
-    img = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax))
-    renderer.draw_raster_data(img, "JPEG")
+    img, format = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax))
+    renderer.draw_raster_data(img, format)
 
     return ()
 





More information about the Thuban-devel mailing list

This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)