1 |
# Copyright (C) 2003 by Intevation GmbH |
# Copyright (C) 2003, 2004 by Intevation GmbH |
2 |
# Authors: |
# Authors: |
3 |
# Jan-Oliver Wagner <[email protected]> |
# Jan-Oliver Wagner <[email protected]> |
4 |
# |
# |
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$" |
19 |
|
# $Source$ |
20 |
|
# $Id$ |
21 |
|
|
22 |
import os, sys |
import os, sys |
23 |
import xml.dom.minidom |
import xml.dom.minidom |
25 |
|
|
26 |
from wxPython.wx import * |
from wxPython.wx import * |
27 |
|
|
|
from ogclib.WMSClient import WMSClient |
|
|
|
|
|
from Thuban.Model.layer import BaseLayer |
|
28 |
from Thuban.Model.proj import Projection |
from Thuban.Model.proj import Projection |
29 |
from Thuban.Model.extension import Extension |
from Thuban.Model.extension import Extension |
|
from Thuban.Model.resource import read_proj_file |
|
30 |
from Thuban.UI.command import registry, Command |
from Thuban.UI.command import registry, Command |
31 |
import Thuban.UI.mainwindow |
from Thuban.UI.mainwindow import main_menu |
32 |
from Thuban import _ |
from Thuban import _ |
33 |
import Thuban.UI.baserenderer |
import Thuban.UI.baserenderer |
34 |
|
|
35 |
|
from layer import WMSLayer |
36 |
|
|
|
def epsg_code_to_projection(epsg): |
|
|
"""Find the projection for the given epsg code. |
|
|
|
|
|
epsg -- EPSG code as string |
|
|
""" |
|
|
proj_file, warnings = read_proj_file("Resources/Projections/epsg.proj") |
|
|
for proj in proj_file.GetProjections(): |
|
|
if proj.EPSGCode() == epsg: |
|
|
return proj |
|
|
proj_file, warnings = read_proj_file("Resources/Projections/epsg-deprecated.proj") |
|
|
for proj in proj_file.GetProjections(): |
|
|
if proj.EPSGCode() == epsg: |
|
|
return proj |
|
|
return None |
|
37 |
|
|
38 |
class WMSExtension(Extension): |
class WMSExtension(Extension): |
39 |
def TreeInfo(self): |
def TreeInfo(self): |
40 |
return (_("Extension: %s") % self.title, |
return (_("Extension: %s") % self.title, |
41 |
[ object.TreeInfo() for object in self.objects ]) |
[ object.TreeInfo() for object in self.objects ]) |
42 |
|
|
|
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 |
|
|
|
|
|
|
|
43 |
|
|
44 |
def render_wms_layer(renderer, layer): |
def render_wms_layer(renderer, layer): |
45 |
offx, offy = renderer.offset |
offx, offy = renderer.offset |
51 |
xmax = (width - offx) / scale |
xmax = (width - offx) / scale |
52 |
ymax = (offy - 0) / scale |
ymax = (offy - 0) / scale |
53 |
|
|
54 |
img = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax)) |
img, format = layer.GetMapImg(width, height, (xmin, ymin, xmax, ymax)) |
55 |
renderer.draw_raster_data(img, "JPEG") |
renderer.draw_raster_data(img, format) |
56 |
|
|
57 |
return () |
return () |
58 |
|
|
114 |
|
|
115 |
if dialog.ShowModal() == wxID_OK: |
if dialog.ShowModal() == wxID_OK: |
116 |
url = dialog.url |
url = dialog.url |
117 |
|
if len(url) == 0: |
118 |
|
url = None |
119 |
else: |
else: |
120 |
url = None |
url = None |
121 |
dialog.Destroy() |
dialog.Destroy() |
145 |
helptext = _('Add a WMS Layer'))) |
helptext = _('Add a WMS Layer'))) |
146 |
|
|
147 |
# find the experimental menu (create it anew if not found) |
# find the experimental menu (create it anew if not found) |
148 |
main_menu = Thuban.UI.mainwindow.main_menu |
experimental_menu = main_menu.FindOrInsertMenu('experimental', |
149 |
experimental_menu = main_menu.find_menu('experimental') |
_('Experimenta&l')) |
|
if experimental_menu is None: |
|
|
experimental_menu = main_menu.InsertMenu('experimental', _('Experimenta&l')) |
|
150 |
|
|
151 |
# finally add the new entry to the experimental menu |
# finally add the new entry to the experimental menu |
152 |
experimental_menu.InsertItem('wms') |
experimental_menu.InsertItem('wms') |