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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2734 - (show 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 # 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 LatLongBoundingBox()
27 BoundingBox()
28
29 getFormat(format)
30 calcFormat(formats)
31
32 getFormats()
33 getLayers()
34 getLayerTitle()
35
36 getWMSFormat()
37 setWMSFormat(format)
38
39 GetMapImg(width, height, bbox)
40
41 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 """
84 WMS Layer
85
86 This layer incorporates all methods from the Thuban BaseLayer and
87 adds specific methods for operating with a WMS server.
88 """
89
90 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 self.wms_layers = []
105 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 self.wms_layers = [top_layer]
120
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 Return the layer's bounding box in lat-lon
172 """
173 return self.latlonbbox
174
175
176 def BoundingBox(self):
177 """
178 Return the layer's bounding box in the intrinsic coordinate system
179 """
180 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 If no mapping was found, None is returned.
190
191 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 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 prio = ['png', 'gif', 'jpeg', 'bmp']
233 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 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 self.format = self.getFormat(format)
296
297
298 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 def GetMapImg(self, width, height, bbox):
315 """
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 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 self.wms_layers, version = self.capabilities.getVersion())
338 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