/usr/lib/thuban/Extensions/wms/layer.py is in thuban 1.2.2-12build3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | # Copyright (c) 2003, 2004, 2007, 2008 by Intevation GmbH
# Authors:
# Didrik Pinte <dpinte@dipole-consulting.com>
# Jan-Oliver Wagner <jan@intevation.de>
# Martin Schulze <joey@infodrom.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
Graphic Layer via OGC WMS.
class WMSLayer:
__init__()
LatLongBoundingBox()
BoundingBox()
getFormat(format)
calcFormat(formats)
getFormats()
getLayers()
getLayerTitle()
getWMSFormat()
setWMSFormat(format)
GetMapImg(width, height, bbox)
Requirements:
- OWSLib <http://trac.gispython.org/projects/PCL/wiki/OwsLib>
Requires the owslib installed regularily on the system or checked out
next to the Thuban checkout. Or set the PYTHONPATH to the OWSLib
directory before starting Thuban.
"""
__version__ = "$Revision: 2868 $"
# $Source$
# $Id: layer.py 2868 2008-12-08 08:50:53Z dpinte $
from Thuban import internal_from_unicode, _
from Thuban.Model.layer import BaseLayer
from Thuban.Model.resource import get_system_proj_file, EPSG_PROJ_FILE, \
EPSG_DEPRECATED_PROJ_FILE
from Thuban.UI.common import ThubanBeginBusyCursor, ThubanEndBusyCursor
from owslib.wms import WebMapService
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
class WMSLayer(BaseLayer):
"""
WMS Layer
This layer incorporates all methods from the Thuban BaseLayer and
adds specific methods for operating with a WMS server.
"""
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 occurred, 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.wms_layers = []
self.capabilities = None
self.cached_bbox = None
# Change the cursor to demonstrate that we're busy but working
ThubanBeginBusyCursor()
self.wmsserver = WebMapService(url, version="1.1.1")
self.capabilities = [op.name for op in self.wmsserver.operations]
ThubanEndBusyCursor()
# name of the top layer of the remote map
layers = list(self.wmsserver.contents)
if len(layers) == 0:
self.error_msg = _('No layers found in remote resource:\n'\
'%s') % url
return
top_layer = layers[1]
self.wms_layers = [top_layer]
# first projection of the top layer
crs = self.wmsserver[top_layer].crsOptions
if len(crs) == 0:
self.error_msg = _('No LatLonBoundingBox found for top layer %s')\
% top_layer
return
# extract only the EPSG code from the EPSG string
# received 'EPSG:4326' but keep only '4326'
top_srs = crs[0].split(':')[1]
# LatLonBox of the top layer
bbox = self.wmsserver.contents[top_layer].boundingBoxWGS84
self.latlonbbox = (float(bbox[0]),
float(bbox[1]),
float(bbox[2]),
float(bbox[3]))
# BoundingBox of the top layer
# Do we really need to know the bbox not in WGS84 ?
bbox = self.wmsserver.contents[top_layer].boundingBox
if bbox is None or len(bbox) == 0:
# self.error_msg = _('No BoundingBox found for layer %s and EPSG %s')\
# % (top_layer, top_srs)
self.bbox = None
else :
self.bbox = (float(bbox[0]),
float(bbox[1]),
float(bbox[2]),
float(bbox[3]))
if self.bbox is None:
self.bbox =self.latlonbbox
# get projection
p = epsg_code_to_projection(top_srs)
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.'\
% top_srs)
# pre-determine the used format
self.wmsformat, self.format = \
self.calcFormat(self.wmsserver.getOperationByName('GetMap').formatOptions)
if self.wmsformat is None:
self.error_msg = \
_('No supported image format found in remote resource')
return
# get and set the title
self.SetTitle(internal_from_unicode(self.wmsserver.identification.title))
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 getFormat(self, format):
"""
Return the image format for the render engine
format -- format as returned by the WMS server
If no mapping was found, None is returned.
This routine uses a simple heuristic in order to find the
broken down image format to be used with the internal render
engine.
An exception rule is implemented in order to not accept
image/wbmp or WBMP which refers to WAP bitmap format and is
not supported by the included render engine.
"""
fmap = {'png' : "PNG",
'jpeg': "JPEG",
'jpg' : "JPEG",
'tif' : "TIFF",
'gif' : "GIF",
'wbmp': None,
'bmp' : "BMP"}
for f in fmap.keys():
if format.lower().find(f) > -1:
return fmap[f]
return None
def calcFormat(self, formats):
"""
Calculate the preferred image format
formats -- list of formates as returned by the WMS server
The following priority is used:
- PNG
- JPEG
- TIFF
- GIF
- BMP
If no matching format was found, None, None will be returned.
An exception rule is implemented in order to not accept
image/wbmp or WBMP which refers to WAP bitmap format and is
not supported by the included render engine.
"""
prio = ['png', 'gif', 'jpeg', 'bmp']
for p in prio:
for f in formats:
if f.lower().find(p) > -1:
if f.lower().find('wbmp') == -1:
return f, self.getFormat(f)
return None, None
def getFormats(self):
"""
Return the list of supported image formats by the WMS server
These formats may be used in the WMS GetMap request. Data is
retrieved from the included WMSCapabilities object.
The called method from WMSCapabilities will default to
'image/jpeg' if no format is recognised in XML Capabilities,
assuming that JPEG will always be supported on the server side
with this encoding.
"""
return self.wmsserver.getOperationByName('GetMap').formatOptions
def getLayers(self):
"""
Return the list of layer names supported by the WMS server
Data is retrieved from the included WMSCapabilities object.
Only named layers will be returned, since a layer may have a
title but doesn't have to have a name associated to it as
well. If no layers were found, an empty list is returned.
"""
return list(self.wmsserver.contents)
def getLayerTitle(self, layer):
"""
Return the title of the named layer
Data is retrieved from the included WMSCapabilities object.
If no such title or no such layer exists, an empty string is
returned.
"""
return self.wmsserver[layer].title
def getWMSFormat(self):
"""
Return the image format that is used for WMS GetMap requests
"""
return self.wmsformat
def setWMSFormat(self, format):
"""
Set the image format that is used for WMS GetMap requests
format -- format, one of getFormats()
"""
self.wmsformat = format
self.format = self.getFormat(format)
def getVisibleLayers(self):
"""
Return the list of names for all visible layers
"""
return self.wms_layers
def setVisibleLayers(self, layers):
"""
Set the list of names for all visible layers
"""
self.wms_layers = layers
def GetMapImg(self, width, height, bbox):
"""
Retrieve a new map from the WMS server and return it
width -- width in pixel of the desired image
height -- height in pixel of the desired image
bbox -- array of min(x,y) max(x,y) in the given SRS
SRS and used image format will be retrieved from within the
layer itself.
"""
bbox_dict = { 'minx': bbox[0], 'miny': bbox[1],
'maxx': bbox[2], 'maxy': bbox[3] }
if self.cached_bbox is not None:
for i in xrange(4):
if self.cached_bbox[i] != bbox[i]:
break
else:
if self.cached_response is not None:
return self.cached_response, self.format
self.cached_bbox = bbox
# Change the cursor to demonstrate that we're busy but working
ThubanBeginBusyCursor()
epsg_id = int(self.GetProjection().EPSGCode())
wms_response = self.wmsserver.getmap(layers=self.wms_layers,
styles=None,
srs="EPSG:%s" % epsg_id,
bbox=bbox,
size=(width, height),
format=self.wmsformat,
transparent=False)
self.cached_response = wms_response.read()
ThubanEndBusyCursor()
return self.cached_response , self.format
|