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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1944 - (show annotations)
Wed Nov 12 08:26:56 2003 UTC (21 years, 3 months ago) by jan
Original Path: trunk/thuban/Extensions/wms/wms.py
File MIME type: text/x-python
File size: 8487 byte(s)
Provide layers via OGC WMS.

1 # Copyright (C) 2003 by Intevation GmbH
2 # 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 from Thuban.Model.resource import read_proj_file
37 from Thuban.UI.command import registry, Command
38 import Thuban.UI.mainwindow
39 from Thuban import _
40 import Thuban.UI.baserenderer
41
42
43 def epsg_code_to_projection(epsg):
44 """Find the projection for the given epsg code.
45
46 epsg -- EPSG code as string
47 """
48 proj_file, warnings = read_proj_file("Resources/Projections/epsg.proj")
49 for proj in proj_file.GetProjections():
50 if proj.EPSGCode() == epsg:
51 return proj
52 proj_file, warnings = read_proj_file("Resources/Projections/epsg-deprecated.proj")
53 for proj in proj_file.GetProjections():
54 if proj.EPSGCode() == epsg:
55 return proj
56 return None
57
58 class WMSExtension(Extension):
59 def TreeInfo(self):
60 return (_("Extension: %s") % self.title,
61 [ object.TreeInfo() for object in self.objects ])
62
63 class WMSLayer(BaseLayer, WMSClient):
64
65 def __init__(self, title, url):
66 """Initializes the WMSLayer.
67
68 title -- Title of this layer.
69 url -- URL of the WMS-Server wich must contain '?'
70
71 If an error occured, self.error_msg is a string describing
72 the problem(s). Else, self.error_msg is None.
73 """
74 BaseLayer.__init__(self, title, visible = True, projection = None)
75 self.url = url
76 self.bbox = None
77 self.latlonbbox = None
78 self.error_msg = None
79 self.layer_name = None
80
81 wms_response = self.getCapabilities(self.url, '1.0')
82 self._capa_dom = xml.dom.minidom.parseString(wms_response)
83
84 root = self._capa_dom.documentElement
85 cap = root.getElementsByTagName('Capability')[0]
86 layer = cap.getElementsByTagName('Layer')[0]
87
88 # get projected bounding box and latlon bounding box
89 for node in layer.childNodes:
90 if node.nodeName == 'BoundingBox':
91 minx = node.attributes.get('minx').nodeValue
92 miny = node.attributes.get('miny').nodeValue
93 maxx = node.attributes.get('maxx').nodeValue
94 maxy = node.attributes.get('maxy').nodeValue
95 self.bbox = (float(minx), float(miny), float(maxx), float(maxy))
96 bbox = layer.getElementsByTagName('LatLonBoundingBox')[0]
97 self.layer_name = layer.getElementsByTagName('Name')[0].childNodes[0].data
98 minx = bbox.attributes.get('minx').nodeValue
99 miny = bbox.attributes.get('miny').nodeValue
100 maxx = bbox.attributes.get('maxx').nodeValue
101 maxy = bbox.attributes.get('maxy').nodeValue
102 self.latlonbbox = (float(minx), float(miny), float(maxx), float(maxy))
103
104 # get projection
105 srs = layer.getElementsByTagName('SRS')[0].childNodes[0].data
106 if len(srs.split(':')) == 1:
107 epsg_id = srs
108 else:
109 epsg_id = srs.split(':')[1]
110
111 p = epsg_code_to_projection(epsg_id)
112 self.SetProjection(p)
113
114 if p is None:
115 self.error_msg = _('EPSG projection code %s not found!\n'\
116 'Setting projection to "None".\n'\
117 'Please set an appropriate projection yourself.'\
118 % epsg_id)
119
120 # get title
121 title = layer.getElementsByTagName('Title')[0].childNodes[0].data
122 self.SetTitle(title.encode('latin1', 'replace'))
123
124 self._capa_dom.unlink()
125
126 def LatLongBoundingBox(self):
127 """Return the layer's bounding box in lat-lon.
128 """
129 return self.latlonbbox
130
131 def BoundingBox(self):
132 """Return the layer's bounding box in the intrinsic coordinate system.
133 """
134 return self.bbox
135
136 def GetMapImg(self, width, height, bbox):
137 bbox_dict = { 'minx': bbox[0], 'miny': bbox[1],
138 'maxx': bbox[2], 'maxy': bbox[3] }
139 epsg_id = int(self.GetProjection().EPSGCode())
140 wms_response = self.getMap(self.url, 'JPEG', width, height,
141 epsg_id, bbox_dict,
142 [self.layer_name], version = '1.0')
143 return wms_response
144
145
146
147 def render_wms_layer(renderer, layer):
148 offx, offy = renderer.offset
149 width, height = renderer.dc.GetSizeTuple()
150
151 scale = renderer.scale
152 xmin = (0 - offx) / scale
153 ymin = (offy - height) / scale
154 xmax = (width - offx) / scale
155 ymax = (offy - 0) / scale
156
157 img = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax))
158 renderer.draw_raster_data(img, "JPEG")
159
160 return ()
161
162 Thuban.UI.baserenderer.add_renderer_extension(WMSLayer, render_wms_layer)
163
164
165 class SelectWMSServer(wxDialog):
166
167 ID_COMBOVALUE = 4003
168
169 def __init__(self, parent):
170 wxDialog.__init__(self, parent, -1, _("Select WMS Server"),
171 style = wxDEFAULT_DIALOG_STYLE
172 | wxSYSTEM_MENU
173 | wxRESIZE_BORDER)
174
175 self.combo_value = wxComboBox(self, self.ID_COMBOVALUE, size=(500,-1))
176 self.combo_value.Append("")
177 self.combo_value.Append('http://frida.intevation.org/cgi-bin/frida_wms?')
178 #self.combo_value.Append('http://wms.jpl.nasa.gov/wms.cgi?')
179 #self.combo_value.Append('http://eukrante.hq:9089/cgi-bin/wms_shg?')
180 #self.combo_value.Append('http://131.220.106.112:8080/deegree0.7/wms?')
181 #self.combo_value.Append('http://demo.cubewerx.com/demo/cubeserv/cubeserv.cgi?CONFIG=gita&')
182 self.combo_value.SetSelection(0)
183
184 button_ok = wxButton(self, wxID_OK, _("OK"))
185 button_ok.SetDefault()
186 button_close = wxButton(self, wxID_CANCEL, _("Close"))
187
188 vbox = wxBoxSizer(wxVERTICAL)
189 vbox.Add(self.combo_value, 1, wxEXPAND|wxALL|wxCB_SORT, 10)
190 hbox = wxBoxSizer(wxHORIZONTAL)
191 hbox.Add(button_ok, 0, wxALL, 10)
192 hbox.Add(button_close, 0, wxALL, 10)
193 vbox.Add(hbox, 0, 10)
194
195 self.SetAutoLayout(True)
196 self.SetSizer(vbox)
197 vbox.Fit(self)
198 vbox.SetSizeHints(self)
199 self.Layout()
200
201 EVT_BUTTON(self, wxID_OK, self.OnOK)
202 EVT_BUTTON(self, wxID_CANCEL, self.OnCancel)
203
204 def OnOK(self, event):
205 self.url = self.combo_value.GetValue()
206 self.EndModal(wxID_OK)
207
208 def OnCancel(self, event):
209 self.EndModal(wxID_CANCEL)
210
211 def wms_dialog(context):
212 """Request URL from user and add WMS Layer.
213
214 context -- The Thuban context.
215 """
216 dialog = SelectWMSServer(context.mainwindow)
217
218 if dialog.ShowModal() == wxID_OK:
219 url = dialog.url
220 else:
221 url = None
222 dialog.Destroy()
223
224 if url is None:
225 return
226
227 wms_layer = WMSLayer('A WMS Layer', url)
228 if wms_layer.error_msg is not None:
229 context.mainwindow.RunMessageBox(_('WMS'), wms_layer.error_msg)
230
231 map = context.mainwindow.canvas.Map()
232 if map.projection is None:
233 map.SetProjection(wms_layer.projection)
234 has_layers = map.HasLayers()
235 map.AddLayer(wms_layer)
236 if not has_layers:
237 # if we're adding a layer to an empty map, fit the
238 # new map to the window
239 context.mainwindow.canvas.FitMapToWindow()
240
241 wxInitAllImageHandlers()
242 wms_extension = WMSExtension('WMS')
243
244 # register the new command
245 registry.Add(Command('wms', _('Add WMS layer ...'), wms_dialog,
246 helptext = _('Add a WMS Layer')))
247
248 # find the experimental menu (create it anew if not found)
249 main_menu = Thuban.UI.mainwindow.main_menu
250 experimental_menu = main_menu.find_menu('experimental')
251 if experimental_menu is None:
252 experimental_menu = main_menu.InsertMenu('experimental', _('Experimenta&l'))
253
254 # finally add the new entry to the experimental menu
255 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