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)