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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2172 - (hide annotations)
Tue Apr 13 17:38:26 2004 UTC (20 years, 10 months ago) by joey
Original Path: trunk/thuban/Extensions/wms/wms.py
File MIME type: text/x-python
File size: 10883 byte(s)
Reset an empty URL to None so that the subsequent program can depend
on this, since the dialog will indeed return an empty URL, causing
another declaration of love by Python.

1 bh 2086 # Copyright (C) 2003, 2004 by Intevation GmbH
2 jan 1944 # Authors:
3     # Jan-Oliver Wagner <[email protected]>
4     #
5     # This program is free software under the GPL (>=v2)
6     # Read the file COPYING coming with Thuban for details.
7    
8     """
9     Provide layers via OGC WMS.
10    
11     This extension is in a very experimental stage!
12     It just demonstrates how to add a special
13     layer into Thuban via an extension.
14     Some things are not wired, so be prepared for Exceptions
15     everywhere.
16    
17     You will need PyOGCLib 0.1.0, see
18     http://pyogclib.sourceforge.net/
19     Set the PYTHONPATH to the PyOGCLib directory before
20     starting Thuban.
21     """
22    
23     __version__ = "$Revision$"
24    
25     import os, sys
26     import xml.dom.minidom
27     import tempfile
28    
29     from wxPython.wx import *
30    
31     from ogclib.WMSClient import WMSClient
32    
33     from Thuban.Model.layer import BaseLayer
34     from Thuban.Model.proj import Projection
35     from Thuban.Model.extension import Extension
36 bh 2086 from Thuban.Model.resource import get_system_proj_file, EPSG_PROJ_FILE, \
37     EPSG_DEPRECATED_PROJ_FILE
38 jan 1944 from Thuban.UI.command import registry, Command
39     import Thuban.UI.mainwindow
40 joey 2158 from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
41 jan 1944 from Thuban import _
42     import Thuban.UI.baserenderer
43    
44 joey 2154 from capabilities import WMSCapabilities
45 jan 1944
46     def epsg_code_to_projection(epsg):
47     """Find the projection for the given epsg code.
48    
49 bh 2086 epsg -- EPSG code as string
50 jan 1944 """
51 bh 2086 proj_file, warnings = get_system_proj_file(EPSG_PROJ_FILE)
52    
53 jan 1944 for proj in proj_file.GetProjections():
54     if proj.EPSGCode() == epsg:
55     return proj
56 bh 2086 proj_file, warnings = get_system_proj_file(EPSG_DEPRECATED_PROJ_FILE)
57 jan 1944 for proj in proj_file.GetProjections():
58     if proj.EPSGCode() == epsg:
59     return proj
60     return None
61    
62     class WMSExtension(Extension):
63     def TreeInfo(self):
64     return (_("Extension: %s") % self.title,
65     [ object.TreeInfo() for object in self.objects ])
66    
67 joey 2154 class WMSLayer(BaseLayer):
68 jan 1944
69     def __init__(self, title, url):
70     """Initializes the WMSLayer.
71    
72     title -- Title of this layer.
73     url -- URL of the WMS-Server wich must contain '?'
74    
75     If an error occured, self.error_msg is a string describing
76     the problem(s). Else, self.error_msg is None.
77     """
78     BaseLayer.__init__(self, title, visible = True, projection = None)
79     self.url = url
80     self.bbox = None
81     self.latlonbbox = None
82     self.error_msg = None
83     self.layer_name = None
84 joey 2154 self.capabilities = None
85 jan 1944
86 joey 2154 # Change the cursor to demonstrate that we're busy but working
87 joey 2158 ThubanBeginBusyCursor()
88 joey 2154 self.capabilities = WMSCapabilities(url)
89 joey 2158 ThubanEndBusyCursor()
90 jan 1944
91 joey 2154 # name of the top layer of the remote map
92     foo = self.capabilities.getLayers()
93     if len(foo) == 0:
94     self.error_msg = _('No layers found in remote resource:\n'\
95     '%s') % url
96     return
97     top_layer = foo[0]
98     self.layer_name = top_layer
99 jan 1944
100 joey 2154 # first projection of the top layer
101     foo = self.capabilities.getLayerSRS(top_layer)
102     if len(foo) == 0:
103     self.error_msg = _('No LatLonBoundingBox found for top layer %s')\
104     % top_layer
105     return
106     top_srs = foo[0]
107 jan 1944
108 joey 2154 # BoundingBox of the top layer
109     bbox = self.capabilities.getLayerBBox(top_layer, top_srs)
110     if len(bbox) == 0:
111     self.error_msg = _('No BoundingBox found for layer %s and EPSG:')\
112     % (top_layer, top_srs)
113     return
114     self.bbox = (float(bbox['minx']),
115     float(bbox['miny']),
116     float(bbox['maxx']),
117     float(bbox['maxy']))
118    
119     # LatLonBox of the top layer
120     bbox = self.capabilities.getLayerLatLonBBox(top_layer)
121     self.latlonbbox = (float(bbox['minx']),
122     float(bbox['miny']),
123     float(bbox['maxx']),
124     float(bbox['maxy']))
125    
126 jan 1944 # get projection
127 joey 2154 p = epsg_code_to_projection(top_srs)
128 jan 1944 self.SetProjection(p)
129    
130     if p is None:
131     self.error_msg = _('EPSG projection code %s not found!\n'\
132     'Setting projection to "None".\n'\
133     'Please set an appropriate projection yourself.'\
134 joey 2159 % top_srs)
135 jan 1944
136 joey 2154 # pre-determine the used format
137     self.wmsformat, self.format = \
138     self.calcFormat(self.capabilities.getFormats())
139     if self.wmsformat is None:
140     self.error_msg = \
141     _('No supported image format found in remote resource')
142     return
143 jan 1944
144 joey 2154 # get and set the title
145     self.SetTitle(self.capabilities.getTitle().encode('latin1', 'replace'))
146 jan 1944
147 joey 2154
148 jan 1944 def LatLongBoundingBox(self):
149     """Return the layer's bounding box in lat-lon.
150     """
151     return self.latlonbbox
152    
153     def BoundingBox(self):
154     """Return the layer's bounding box in the intrinsic coordinate system.
155     """
156     return self.bbox
157    
158 joey 2154
159     def getFormat(self, format):
160     """
161     Return the image format for the render engine
162    
163     format -- format as returned by the WMS server
164    
165     If no mapping was found, None is returned
166    
167     An exception rule is implemented in order to not accept
168     image/wbmp or WBMP which refers to WAP bitmap format and is
169     not supported by the included render engine.
170     """
171     fmap = {'png' : "PNG",
172     'jpeg': "JPEG",
173     'jpg' : "JPEG",
174     'tif' : "TIFF",
175     'gif' : "GIF",
176     'wbmp': None,
177     'bmp' : "BMP"}
178    
179     for f in fmap.keys():
180     if format.lower().find(f) > -1:
181     return fmap[f]
182     return None
183    
184    
185     def calcFormat(self, formats):
186     """
187     Calculate the preferred image format
188    
189     formats -- list of formates as returned by the WMS server
190    
191     The following priority is used:
192     - PNG
193     - JPEG
194     - TIFF
195     - GIF
196     - BMP
197    
198     If no matching format was found, None, None will be returned.
199    
200     An exception rule is implemented in order to not accept
201     image/wbmp or WBMP which refers to WAP bitmap format and is
202     not supported by the included render engine.
203     """
204 joey 2171 prio = ['jpeg', 'bmp']
205 joey 2154 for p in prio:
206     for f in formats:
207     if f.lower().find(p) > -1:
208     if f.lower().find('wbmp') == -1:
209     return f, self.getFormat(f)
210     return None, None
211    
212    
213 jan 1944 def GetMapImg(self, width, height, bbox):
214     bbox_dict = { 'minx': bbox[0], 'miny': bbox[1],
215     'maxx': bbox[2], 'maxy': bbox[3] }
216 joey 2154
217     # Change the cursor to demonstrate that we're busy but working
218 joey 2158 ThubanBeginBusyCursor()
219 joey 2154
220     wmsclient = WMSClient()
221    
222 jan 1944 epsg_id = int(self.GetProjection().EPSGCode())
223 joey 2154
224     wms_response = wmsclient.getMap(self.url, self.wmsformat, width, height,
225 jan 1944 epsg_id, bbox_dict,
226 joey 2154 [self.layer_name], version = self.capabilities.getVersion())
227 joey 2158 ThubanEndBusyCursor()
228 joey 2154 return wms_response, self.format
229 jan 1944
230    
231     def render_wms_layer(renderer, layer):
232     offx, offy = renderer.offset
233     width, height = renderer.dc.GetSizeTuple()
234    
235     scale = renderer.scale
236     xmin = (0 - offx) / scale
237     ymin = (offy - height) / scale
238     xmax = (width - offx) / scale
239     ymax = (offy - 0) / scale
240    
241 joey 2154 img, format = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax))
242     renderer.draw_raster_data(img, format)
243 jan 1944
244     return ()
245    
246     Thuban.UI.baserenderer.add_renderer_extension(WMSLayer, render_wms_layer)
247    
248    
249     class SelectWMSServer(wxDialog):
250    
251     ID_COMBOVALUE = 4003
252    
253     def __init__(self, parent):
254     wxDialog.__init__(self, parent, -1, _("Select WMS Server"),
255     style = wxDEFAULT_DIALOG_STYLE
256     | wxSYSTEM_MENU
257     | wxRESIZE_BORDER)
258    
259     self.combo_value = wxComboBox(self, self.ID_COMBOVALUE, size=(500,-1))
260     self.combo_value.Append("")
261     self.combo_value.Append('http://frida.intevation.org/cgi-bin/frida_wms?')
262     #self.combo_value.Append('http://wms.jpl.nasa.gov/wms.cgi?')
263     #self.combo_value.Append('http://eukrante.hq:9089/cgi-bin/wms_shg?')
264     #self.combo_value.Append('http://131.220.106.112:8080/deegree0.7/wms?')
265     #self.combo_value.Append('http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi?CONFIG=gita&')
266     self.combo_value.SetSelection(0)
267    
268     button_ok = wxButton(self, wxID_OK, _("OK"))
269     button_ok.SetDefault()
270     button_close = wxButton(self, wxID_CANCEL, _("Close"))
271    
272     vbox = wxBoxSizer(wxVERTICAL)
273     vbox.Add(self.combo_value, 1, wxEXPAND|wxALL|wxCB_SORT, 10)
274     hbox = wxBoxSizer(wxHORIZONTAL)
275     hbox.Add(button_ok, 0, wxALL, 10)
276     hbox.Add(button_close, 0, wxALL, 10)
277     vbox.Add(hbox, 0, 10)
278    
279     self.SetAutoLayout(True)
280     self.SetSizer(vbox)
281     vbox.Fit(self)
282     vbox.SetSizeHints(self)
283     self.Layout()
284    
285     EVT_BUTTON(self, wxID_OK, self.OnOK)
286     EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
287    
288     def OnOK(self, event):
289     self.url = self.combo_value.GetValue()
290     self.EndModal(wxID_OK)
291    
292     def OnCancel(self, event):
293     self.EndModal(wxID_CANCEL)
294    
295     def wms_dialog(context):
296     """Request URL from user and add WMS Layer.
297    
298     context -- The Thuban context.
299     """
300     dialog = SelectWMSServer(context.mainwindow)
301    
302     if dialog.ShowModal() == wxID_OK:
303     url = dialog.url
304 joey 2172 if len(url) == 0:
305     url = None
306 jan 1944 else:
307     url = None
308     dialog.Destroy()
309    
310     if url is None:
311     return
312    
313     wms_layer = WMSLayer('A WMS Layer', url)
314     if wms_layer.error_msg is not None:
315     context.mainwindow.RunMessageBox(_('WMS'), wms_layer.error_msg)
316    
317     map = context.mainwindow.canvas.Map()
318     if map.projection is None:
319     map.SetProjection(wms_layer.projection)
320     has_layers = map.HasLayers()
321     map.AddLayer(wms_layer)
322     if not has_layers:
323     # if we're adding a layer to an empty map, fit the
324     # new map to the window
325     context.mainwindow.canvas.FitMapToWindow()
326    
327     wxInitAllImageHandlers()
328     wms_extension = WMSExtension('WMS')
329    
330     # register the new command
331     registry.Add(Command('wms', _('Add WMS layer ...'), wms_dialog,
332     helptext = _('Add a WMS Layer')))
333    
334     # find the experimental menu (create it anew if not found)
335     main_menu = Thuban.UI.mainwindow.main_menu
336     experimental_menu = main_menu.find_menu('experimental')
337     if experimental_menu is None:
338     experimental_menu = main_menu.InsertMenu('experimental', _('Experimenta&l'))
339    
340     # finally add the new entry to the experimental menu
341     experimental_menu.InsertItem('wms')

Properties

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26