/[thuban]/branches/WIP-pyshapelib-bramz/Extensions/wms/layer.py
ViewVC logotype

Annotation of /branches/WIP-pyshapelib-bramz/Extensions/wms/layer.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (hide annotations)
Thu Mar 1 12:42:59 2007 UTC (18 years ago) by bramz
File MIME type: text/x-python
File size: 10315 byte(s)
made a copy
1 joey 2175 # Copyright (c) 2003, 2004 by Intevation GmbH
2     # Authors:
3     # Jan-Oliver Wagner <[email protected]>
4     # Martin Schulze <[email protected]>
5     #
6     # This program is free software; you can redistribute it and/or modify
7     # it under the terms of the GNU General Public License as published by
8     # the Free Software Foundation; either version 2 of the License, or
9     # (at your option) any later version.
10     #
11     # This program is distributed in the hope that it will be useful,
12     # but WITHOUT ANY WARRANTY; without even the implied warranty of
13     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     # GNU General Public License for more details.
15     #
16     # You should have received a copy of the GNU General Public License
17     # along with this program; if not, write to the Free Software
18     # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19    
20     """
21     Graphic Layer via OGC WMS.
22    
23     class WMSLayer:
24     __init__()
25    
26 joey 2177 LatLongBoundingBox()
27     BoundingBox()
28 joey 2175
29 joey 2177 getFormat(format)
30     calcFormat(formats)
31    
32 joey 2178 getFormats()
33     getLayers()
34     getLayerTitle()
35    
36     getWMSFormat()
37     setWMSFormat(format)
38    
39 joey 2177 GetMapImg(width, height, bbox)
40    
41 joey 2175 Requirements:
42     - PyOGCLib <http://www.sourceforge.net/projects/pyogclib>
43    
44     Requires the ogclib installed regularily on the system or checked out
45     next to the Thuban checkout. Or set the PYTHONPATH to the PyOGCLib
46     directory before starting Thuban.
47    
48     """
49    
50     __version__ = "$Revision$"
51     # $Source$
52     # $Id$
53    
54    
55     from Thuban.Model.layer import BaseLayer
56     from Thuban.Model.resource import get_system_proj_file, EPSG_PROJ_FILE, \
57     EPSG_DEPRECATED_PROJ_FILE
58     from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
59    
60     from capabilities import WMSCapabilities
61    
62     from ogclib.WMSClient import WMSClient
63    
64    
65     def epsg_code_to_projection(epsg):
66     """Find the projection for the given epsg code.
67    
68     epsg -- EPSG code as string
69     """
70     proj_file, warnings = get_system_proj_file(EPSG_PROJ_FILE)
71    
72     for proj in proj_file.GetProjections():
73     if proj.EPSGCode() == epsg:
74     return proj
75     proj_file, warnings = get_system_proj_file(EPSG_DEPRECATED_PROJ_FILE)
76     for proj in proj_file.GetProjections():
77     if proj.EPSGCode() == epsg:
78     return proj
79     return None
80    
81    
82     class WMSLayer(BaseLayer):
83 joey 2177 """
84     WMS Layer
85 joey 2175
86 joey 2177 This layer incorporates all methods from the Thuban BaseLayer and
87     adds specific methods for operating with a WMS server.
88     """
89    
90 joey 2175 def __init__(self, title, url):
91     """Initializes the WMSLayer.
92    
93     title -- Title of this layer.
94     url -- URL of the WMS-Server wich must contain '?'
95    
96     If an error occured, self.error_msg is a string describing
97     the problem(s). Else, self.error_msg is None.
98     """
99     BaseLayer.__init__(self, title, visible = True, projection = None)
100     self.url = url
101     self.bbox = None
102     self.latlonbbox = None
103     self.error_msg = None
104 joey 2179 self.wms_layers = []
105 joey 2175 self.capabilities = None
106    
107     # Change the cursor to demonstrate that we're busy but working
108     ThubanBeginBusyCursor()
109     self.capabilities = WMSCapabilities(url)
110     ThubanEndBusyCursor()
111    
112     # name of the top layer of the remote map
113     foo = self.capabilities.getLayers()
114     if len(foo) == 0:
115     self.error_msg = _('No layers found in remote resource:\n'\
116     '%s') % url
117     return
118     top_layer = foo[0]
119 joey 2179 self.wms_layers = [top_layer]
120 joey 2175
121     # first projection of the top layer
122     foo = self.capabilities.getLayerSRS(top_layer)
123     if len(foo) == 0:
124     self.error_msg = _('No LatLonBoundingBox found for top layer %s')\
125     % top_layer
126     return
127     top_srs = foo[0]
128    
129     # BoundingBox of the top layer
130     bbox = self.capabilities.getLayerBBox(top_layer, top_srs)
131     if len(bbox) == 0:
132     self.error_msg = _('No BoundingBox found for layer %s and EPSG:')\
133     % (top_layer, top_srs)
134     return
135     self.bbox = (float(bbox['minx']),
136     float(bbox['miny']),
137     float(bbox['maxx']),
138     float(bbox['maxy']))
139    
140     # LatLonBox of the top layer
141     bbox = self.capabilities.getLayerLatLonBBox(top_layer)
142     self.latlonbbox = (float(bbox['minx']),
143     float(bbox['miny']),
144     float(bbox['maxx']),
145     float(bbox['maxy']))
146    
147     # get projection
148     p = epsg_code_to_projection(top_srs)
149     self.SetProjection(p)
150    
151     if p is None:
152     self.error_msg = _('EPSG projection code %s not found!\n'\
153     'Setting projection to "None".\n'\
154     'Please set an appropriate projection yourself.'\
155     % top_srs)
156    
157     # pre-determine the used format
158     self.wmsformat, self.format = \
159     self.calcFormat(self.capabilities.getFormats())
160     if self.wmsformat is None:
161     self.error_msg = \
162     _('No supported image format found in remote resource')
163     return
164    
165     # get and set the title
166     self.SetTitle(self.capabilities.getTitle().encode('latin1', 'replace'))
167    
168    
169     def LatLongBoundingBox(self):
170     """
171 joey 2177 Return the layer's bounding box in lat-lon
172     """
173 joey 2175 return self.latlonbbox
174    
175 joey 2177
176 joey 2175 def BoundingBox(self):
177     """
178 joey 2177 Return the layer's bounding box in the intrinsic coordinate system
179     """
180 joey 2175 return self.bbox
181    
182    
183     def getFormat(self, format):
184     """
185     Return the image format for the render engine
186    
187     format -- format as returned by the WMS server
188    
189 joey 2177 If no mapping was found, None is returned.
190 joey 2175
191 joey 2177 This routine uses a simple heuristic in order to find the
192     broken down image format to be used with the internal render
193     engine.
194    
195 joey 2175 An exception rule is implemented in order to not accept
196     image/wbmp or WBMP which refers to WAP bitmap format and is
197     not supported by the included render engine.
198     """
199     fmap = {'png' : "PNG",
200     'jpeg': "JPEG",
201     'jpg' : "JPEG",
202     'tif' : "TIFF",
203     'gif' : "GIF",
204     'wbmp': None,
205     'bmp' : "BMP"}
206    
207     for f in fmap.keys():
208     if format.lower().find(f) > -1:
209     return fmap[f]
210     return None
211    
212    
213     def calcFormat(self, formats):
214     """
215     Calculate the preferred image format
216    
217     formats -- list of formates as returned by the WMS server
218    
219     The following priority is used:
220     - PNG
221     - JPEG
222     - TIFF
223     - GIF
224     - BMP
225    
226     If no matching format was found, None, None will be returned.
227    
228     An exception rule is implemented in order to not accept
229     image/wbmp or WBMP which refers to WAP bitmap format and is
230     not supported by the included render engine.
231     """
232 joey 2438 prio = ['png', 'gif', 'jpeg', 'bmp']
233 joey 2175 for p in prio:
234     for f in formats:
235     if f.lower().find(p) > -1:
236     if f.lower().find('wbmp') == -1:
237     return f, self.getFormat(f)
238     return None, None
239    
240    
241 joey 2178 def getFormats(self):
242     """
243     Return the list of supported image formats by the WMS server
244    
245     These formats may be used in the WMS GetMap request. Data is
246     retrieved from the included WMSCapabilities object.
247    
248     The called method from WMSCapabilities will default to
249     'image/jpeg' if no format is recognised in XML Capabilities,
250     assuming that JPEG will always be supported on the server side
251     with this encoding.
252     """
253     return self.capabilities.getFormats()
254    
255    
256     def getLayers(self):
257     """
258     Return the list of layer names supported by the WMS server
259    
260     Data is retrieved from the included WMSCapabilities object.
261    
262     Only named layers will be returned, since a layer may have a
263     title but doesn't have to have a name associated to it as
264     well. If no layers were found, an empty list is returned.
265     """
266     return self.capabilities.getLayers()
267    
268    
269     def getLayerTitle(self, layer):
270     """
271     Return the title of the named layer
272    
273     Data is retrieved from the included WMSCapabilities object.
274    
275     If no such title or no such layer exists, an empty string is
276     returned.
277     """
278     return self.capabilities.getLayerTitle(layer)
279    
280    
281     def getWMSFormat(self):
282     """
283     Return the image format that is used for WMS GetMap requests
284     """
285     return self.wmsformat
286    
287    
288     def setWMSFormat(self, format):
289     """
290     Set the image format that is used for WMS GetMap requests
291    
292     format -- format, one of getFormats()
293     """
294     self.wmsformat = format
295 joey 2181 self.format = self.getFormat(format)
296 joey 2178
297    
298 joey 2179 def getVisibleLayers(self):
299     """
300     Return the list of names for all visible layers
301    
302     """
303     return self.wms_layers
304    
305    
306     def setVisibleLayers(self, layers):
307     """
308     Set the list of names for all visible layers
309    
310     """
311     self.wms_layers = layers
312    
313    
314 joey 2175 def GetMapImg(self, width, height, bbox):
315 joey 2177 """
316     Retrieve a new map from the WMS server and return it
317    
318     width -- width in pixel of the desired image
319     height -- height in pixel of the desired image
320     bbox -- array of min(x,y) max(x,y) in the given SRS
321    
322     SRS and used image format will be retrieved from within the
323     layer itself.
324     """
325 joey 2175 bbox_dict = { 'minx': bbox[0], 'miny': bbox[1],
326     'maxx': bbox[2], 'maxy': bbox[3] }
327    
328     # Change the cursor to demonstrate that we're busy but working
329     ThubanBeginBusyCursor()
330    
331     wmsclient = WMSClient()
332    
333     epsg_id = int(self.GetProjection().EPSGCode())
334    
335     wms_response = wmsclient.getMap(self.url, self.wmsformat, width, height,
336     epsg_id, bbox_dict,
337 joey 2179 self.wms_layers, version = self.capabilities.getVersion())
338 joey 2175 ThubanEndBusyCursor()
339     return wms_response, self.format

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26