/usr/lib/python2.7/dist-packages/owslib/tms.py is in python-owslib 0.16.0-1.
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 | # -*- coding: UTF-8 -*-
# =============================================================================
# Copyright (C) 2013 Christian Ledermann <christian.ledermann@gmail.com>
#
# Based on wms.py, which has the following copyright statement:
# Copyright (c) 2004, 2006 Sean C. Gillies
# Copyright (c) 2005 Nuxeo SARL <http://nuxeo.com>
#
# Authors : Sean Gillies <sgillies@frii.com>
# Julien Anguenot <ja@nuxeo.com>
#
# Contact email: sgillies@frii.com
# =============================================================================
# TMS as defined in:
# http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification
from __future__ import (absolute_import, division, print_function)
from .etree import etree
from .util import openURL, testXMLValue, ServiceException
FORCE900913 = False
def force900913(epsg):
# http://osgeo-org.1560.n6.nabble.com/OSGEO-code-td3852851.html
# "EPSG:900913" = ["OSGEO:41001", "EPSG:3785", "EPSG:3857", "EPSG:54004"]
if FORCE900913 and epsg.upper() in ["OSGEO:41001", "EPSG:3785",
"EPSG:3857", "EPSG:54004"]:
return "EPSG:900913"
else:
return epsg
class TileMapService(object):
"""Abstraction for OGC Tile Map Service (TMS).
Implements IWebMapService.
"""
def __init__(self, url, version='1.0.0', xml=None, username=None, password=None, parse_remote_metadata=False, timeout=30):
"""Initialize."""
self.url = url
self.username = username
self.password = password
self.version = version
self.timeout = timeout
self.services = None
self._capabilities = None
self.contents={}
# Authentication handled by Reader
reader = TMSCapabilitiesReader(
self.version, url=self.url, un=self.username, pw=self.password
)
if xml: # read from stored xml
self._capabilities = reader.readString(xml)
else: # read from server
self._capabilities = reader.read(self.url, timeout=self.timeout)
# build metadata objects
self._buildMetadata(parse_remote_metadata)
def _getcapproperty(self):
if not self._capabilities:
reader = TMSCapabilitiesReader(
self.version, url=self.url, un=self.username, pw=self.password
)
self._capabilities = ServiceMetadata(reader.read(self.url))
return self._capabilities
def _buildMetadata(self, parse_remote_metadata=False):
''' set up capabilities metadata objects '''
if self._capabilities.attrib.get('version'):
self.version = self._capabilities.attrib.get('version')
self.identification=ServiceIdentification(self._capabilities, self.version)
self.contents={}
tilemaps = self._capabilities.find('TileMaps')
if tilemaps is not None:
for tilemap in tilemaps.findall('TileMap'):
cm = ContentMetadata(tilemap, un=self.username, pw=self.password)
if cm.id:
if cm.id in self.contents:
raise KeyError('Content metadata for layer "%s" already exists' % cm.id)
self.contents[cm.id] = cm
def getServiceXML(self):
xml = None
if self._capabilities is not None:
xml = etree.tostring(self._capabilities)
return xml
def items(self, srs=None, profile=None):
'''supports dict-like items() access'''
items=[]
if not srs and not profile:
for item in self.contents:
items.append((item,self.contents[item]))
elif srs and profile:
for item in self.contents:
if (self.contents[item].srs == srs and
self.contents[item].profile == profile):
items.append((item,self.contents[item]))
elif srs:
for item in self.contents:
if self.contents[item].srs == srs:
items.append((item,self.contents[item]))
elif profile:
for item in self.contents:
if self.contents[item].profile == profile:
items.append((item,self.contents[item]))
return items
def _gettilefromset(self, tilesets, x, y,z, ext, timeout=None):
for tileset in tilesets:
if tileset['order'] == z:
url = tileset['href'] + '/' + str(x) +'/' + str(y) + '.' + ext
u = openURL(url, '', username = self.username,
password = self.password, timeout=timeout or self.timeout)
return u
else:
raise ValueError('cannot find zoomlevel %i for TileMap' % z)
def gettile(self, x,y,z, id=None, title=None, srs=None, mimetype=None, timeout=None):
if not id and not title and not srs:
raise ValueError('either id or title and srs must be specified')
if id:
return self._gettilefromset(self.contents[id].tilemap.tilesets,
x, y, z, self.contents[id].tilemap.extension, timeout=timeout)
elif title and srs:
for tm in self.contents.values():
if tm.title == title and tm.srs == srs:
if mimetype:
if tm.tilemap.mimetype == mimetype:
return self._gettilefromset(tm.tilemap.tilesets,
x, y, z, tm.tilemap.extension, timeout=timeout)
else:
#if no format is given we return the tile from the
# first tilemap that matches name and srs
return self._gettilefromset(tm.tilemap.tilesets,
x, y,z, tm.tilemap.extension, timeout=timeout)
else:
raise ValueError('cannot find %s with projection %s for zoomlevel %i'
%(title, srs, z) )
elif title or srs:
ValueError('both title and srs must be specified')
raise ValueError('''Specified Tile with id %s, title %s
projection %s format %s at zoomlevel %i cannot be found'''
%(id, title, srs, format, z))
class ServiceIdentification(object):
def __init__(self, infoset, version):
self._root=infoset
if self._root.tag != 'TileMapService':
raise ServiceException("Expected TileMapService tag, got %s" % self._root.tag)
self.version = version
self.title = testXMLValue(self._root.find('Title'))
self.abstract = testXMLValue(self._root.find('Abstract'))
self.keywords = []
f = self._root.find('KeywordList')
if f is not None:
self.keywords = f.text.split()
self.url = self._root.attrib.get('services')
class ContentMetadata(object):
"""
Abstraction for TMS layer metadata.
"""
def __str__(self):
return 'Layer Title: %s, URL: %s' % (self.title, self.id)
def __init__(self, elem, un=None, pw=None):
if elem.tag != 'TileMap':
raise ValueError('%s should be a TileMap' % (elem,))
self.id = elem.attrib['href']
self.title = elem.attrib['title']
self.srs = force900913(elem.attrib['srs'])
self.profile = elem.attrib['profile']
self.password = pw
self.username = pw
self._tile_map = None
self.type = elem.attrib.get('type')
def _get_tilemap(self):
if self._tile_map is None:
self._tile_map = TileMap(self.id, un=self.username, pw=self.password)
assert(self._tile_map.srs == self.srs)
return self._tile_map
@property
def tilemap(self):
return self._get_tilemap()
@property
def abstract(self):
return self._get_tilemap().abstract
@property
def width(self):
return self._get_tilemap().width
@property
def height(self):
return self._get_tilemap().height
@property
def mimetype(self):
return self._get_tilemap().mimetype
@property
def extension(self):
return self._get_tilemap().extension
@property
def boundingBox(self):
return self._get_tilemap().boundingBox
@property
def origin(self):
return self._get_tilemap().origin
class TileMap(object):
title = None
abstract = None
srs = None
boundingBox = None
origin = None
width = None
height = None
mimetype = None
extension = None
_element = None
version = None
tilemapservice = None
tilesets = None
profile = None
def __init__(self, url=None, xml=None, un=None, pw=None):
self.url = url
self.username = un
self.password = pw
self.tilesets = []
if xml and not url:
self.readString(xml)
elif url:
self.read(url)
def _parse(self, elem):
if elem.tag != 'TileMap':
raise ValueError('%s should be a TileMap' % (elem,))
self._element = elem
self.version = elem.attrib.get('version')
self.tilemapservice = elem.attrib.get('tilemapservice')
self.title = testXMLValue(elem.find('Title'))
self.abstract = testXMLValue(elem.find('Abstract'))
self.srs = force900913(testXMLValue(elem.find('SRS')))
bbox = elem.find('BoundingBox')
self.boundingBox = (float(bbox.attrib['minx']),
float(bbox.attrib['miny']),
float(bbox.attrib['maxx']),
float(bbox.attrib['maxy']))
origin = elem.find('Origin')
self.origin = (float(origin.attrib['x']), float(origin.attrib['y']))
tf = elem.find('TileFormat')
self.width = int(tf.attrib['width'])
self.height = int(tf.attrib['height'])
self.mimetype = tf.attrib['mime-type']
self.extension = tf.attrib['extension']
ts = elem.find('TileSets')
if ts is not None:
self.profile = ts.attrib.get('profile')
tilesets = ts.findall('TileSet')
for tileset in tilesets:
href = tileset.attrib['href']
upp = float(tileset.attrib['units-per-pixel'])
order = int(tileset.attrib['order'])
self.tilesets.append({
'href': href,
'units-per-pixel': upp,
'order': order})
def read(self, url):
u = openURL(url, '', method='Get', username = self.username, password = self.password)
self._parse(etree.fromstring(u.read()))
def readString(self, st):
if not isinstance(st, str):
raise ValueError("String must be of type string, not %s" % type(st))
self._parse(etree.fromstring(st))
class TMSCapabilitiesReader(object):
"""Read and parse capabilities document into a lxml.etree infoset
"""
def __init__(self, version='1.0.0', url=None, un=None, pw=None):
"""Initialize"""
self.version = version
self._infoset = None
self.url = url
self.username = un
self.password = pw
def read(self, service_url, timeout=30):
"""Get and parse a TMS capabilities document, returning an
elementtree instance
"""
u = openURL(service_url, '', method='Get', username=self.username, password=self.password, timeout=timeout)
return etree.fromstring(u.read())
def readString(self, st):
"""Parse a TMS capabilities document, returning an elementtree instance
string should be an XML capabilities document
"""
if not isinstance(st, str):
raise ValueError("String must be of type string, not %s" % type(st))
return etree.fromstring(st)
|