13 |
layer into Thuban via an extension. |
layer into Thuban via an extension. |
14 |
Some things are not wired, so be prepared for Exceptions |
Some things are not wired, so be prepared for Exceptions |
15 |
everywhere. |
everywhere. |
|
|
|
|
You will need PyOGCLib 0.1.0, see |
|
|
http://pyogclib.sourceforge.net/ |
|
|
Set the PYTHONPATH to the PyOGCLib directory before |
|
|
starting Thuban. |
|
16 |
""" |
""" |
17 |
|
|
18 |
__version__ = "$Revision$" |
__version__ = "$Revision$" |
23 |
|
|
24 |
from wxPython.wx import * |
from wxPython.wx import * |
25 |
|
|
|
from ogclib.WMSClient import WMSClient |
|
|
|
|
|
from Thuban.Model.layer import BaseLayer |
|
26 |
from Thuban.Model.proj import Projection |
from Thuban.Model.proj import Projection |
27 |
from Thuban.Model.extension import Extension |
from Thuban.Model.extension import Extension |
|
from Thuban.Model.resource import get_system_proj_file, EPSG_PROJ_FILE, \ |
|
|
EPSG_DEPRECATED_PROJ_FILE |
|
28 |
from Thuban.UI.command import registry, Command |
from Thuban.UI.command import registry, Command |
29 |
import Thuban.UI.mainwindow |
import Thuban.UI.mainwindow |
30 |
from Thuban import _ |
from Thuban import _ |
31 |
import Thuban.UI.baserenderer |
import Thuban.UI.baserenderer |
32 |
|
|
33 |
|
from layer import WMSLayer |
34 |
|
|
|
def epsg_code_to_projection(epsg): |
|
|
"""Find the projection for the given epsg code. |
|
|
|
|
|
epsg -- EPSG code as string |
|
|
""" |
|
|
proj_file, warnings = get_system_proj_file(EPSG_PROJ_FILE) |
|
|
|
|
|
for proj in proj_file.GetProjections(): |
|
|
if proj.EPSGCode() == epsg: |
|
|
return proj |
|
|
proj_file, warnings = get_system_proj_file(EPSG_DEPRECATED_PROJ_FILE) |
|
|
for proj in proj_file.GetProjections(): |
|
|
if proj.EPSGCode() == epsg: |
|
|
return proj |
|
|
return None |
|
35 |
|
|
36 |
class WMSExtension(Extension): |
class WMSExtension(Extension): |
37 |
def TreeInfo(self): |
def TreeInfo(self): |
38 |
return (_("Extension: %s") % self.title, |
return (_("Extension: %s") % self.title, |
39 |
[ object.TreeInfo() for object in self.objects ]) |
[ object.TreeInfo() for object in self.objects ]) |
40 |
|
|
|
class WMSLayer(BaseLayer, WMSClient): |
|
|
|
|
|
def __init__(self, title, url): |
|
|
"""Initializes the WMSLayer. |
|
|
|
|
|
title -- Title of this layer. |
|
|
url -- URL of the WMS-Server wich must contain '?' |
|
|
|
|
|
If an error occured, self.error_msg is a string describing |
|
|
the problem(s). Else, self.error_msg is None. |
|
|
""" |
|
|
BaseLayer.__init__(self, title, visible = True, projection = None) |
|
|
self.url = url |
|
|
self.bbox = None |
|
|
self.latlonbbox = None |
|
|
self.error_msg = None |
|
|
self.layer_name = None |
|
|
|
|
|
wms_response = self.getCapabilities(self.url, '1.0') |
|
|
self._capa_dom = xml.dom.minidom.parseString(wms_response) |
|
|
|
|
|
root = self._capa_dom.documentElement |
|
|
cap = root.getElementsByTagName('Capability')[0] |
|
|
layer = cap.getElementsByTagName('Layer')[0] |
|
|
|
|
|
# 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)) |
|
|
|
|
|
# get projection |
|
|
srs = layer.getElementsByTagName('SRS')[0].childNodes[0].data |
|
|
if len(srs.split(':')) == 1: |
|
|
epsg_id = srs |
|
|
else: |
|
|
epsg_id = srs.split(':')[1] |
|
|
|
|
|
p = epsg_code_to_projection(epsg_id) |
|
|
self.SetProjection(p) |
|
|
|
|
|
if p is None: |
|
|
self.error_msg = _('EPSG projection code %s not found!\n'\ |
|
|
'Setting projection to "None".\n'\ |
|
|
'Please set an appropriate projection yourself.'\ |
|
|
% epsg_id) |
|
|
|
|
|
# get title |
|
|
title = layer.getElementsByTagName('Title')[0].childNodes[0].data |
|
|
self.SetTitle(title.encode('latin1', 'replace')) |
|
|
|
|
|
self._capa_dom.unlink() |
|
|
|
|
|
def LatLongBoundingBox(self): |
|
|
"""Return the layer's bounding box in lat-lon. |
|
|
""" |
|
|
return self.latlonbbox |
|
|
|
|
|
def BoundingBox(self): |
|
|
"""Return the layer's bounding box in the intrinsic coordinate system. |
|
|
""" |
|
|
return self.bbox |
|
|
|
|
|
def GetMapImg(self, width, height, bbox): |
|
|
bbox_dict = { 'minx': bbox[0], 'miny': bbox[1], |
|
|
'maxx': bbox[2], 'maxy': bbox[3] } |
|
|
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 |
|
|
|
|
|
|
|
41 |
|
|
42 |
def render_wms_layer(renderer, layer): |
def render_wms_layer(renderer, layer): |
43 |
offx, offy = renderer.offset |
offx, offy = renderer.offset |
49 |
xmax = (width - offx) / scale |
xmax = (width - offx) / scale |
50 |
ymax = (offy - 0) / scale |
ymax = (offy - 0) / scale |
51 |
|
|
52 |
img = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax)) |
img, format = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax)) |
53 |
renderer.draw_raster_data(img, "JPEG") |
renderer.draw_raster_data(img, format) |
54 |
|
|
55 |
return () |
return () |
56 |
|
|
112 |
|
|
113 |
if dialog.ShowModal() == wxID_OK: |
if dialog.ShowModal() == wxID_OK: |
114 |
url = dialog.url |
url = dialog.url |
115 |
|
if len(url) == 0: |
116 |
|
url = None |
117 |
else: |
else: |
118 |
url = None |
url = None |
119 |
dialog.Destroy() |
dialog.Destroy() |