Convert to unix line endings

This commit is contained in:
Dane Springmeyer 2009-02-12 01:11:18 +00:00
parent 8839d9fd3f
commit 75d5e1c9e1
4 changed files with 531 additions and 531 deletions

View file

@ -1,20 +1,20 @@
# #
# This file is part of Mapnik (c++ mapping toolkit) # This file is part of Mapnik (c++ mapping toolkit)
# #
# Copyright (C) 2006 Jean-Francois Doyon # Copyright (C) 2006 Jean-Francois Doyon
# #
# Mapnik is free software; you can redistribute it and/or # Mapnik is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public # modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either # License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version. # version 2.1 of the License, or (at your option) any later version.
# #
# This library is distributed in the hope that it will be useful, # This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details. # Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# #
# $Id$ # $Id$

View file

@ -1,44 +1,44 @@
# #
# This file is part of Mapnik (c++ mapping toolkit) # This file is part of Mapnik (c++ mapping toolkit)
# #
# Copyright (C) 2006 Jean-Francois Doyon # Copyright (C) 2006 Jean-Francois Doyon
# #
# Mapnik is free software; you can redistribute it and/or # Mapnik is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public # modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either # License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version. # version 2.1 of the License, or (at your option) any later version.
# #
# This library is distributed in the hope that it will be useful, # This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details. # Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# #
# $Id$ # $Id$
""" Change SafeConfigParser behavior to treat options without values as """ Change SafeConfigParser behavior to treat options without values as
non-existent. non-existent.
""" """
from ConfigParser import SafeConfigParser as OrigSafeConfigParser from ConfigParser import SafeConfigParser as OrigSafeConfigParser
class SafeConfigParser(OrigSafeConfigParser): class SafeConfigParser(OrigSafeConfigParser):
def items_with_value(self, section): def items_with_value(self, section):
finallist = [] finallist = []
items = self.items(section) items = self.items(section)
for item in items: for item in items:
if item[1] != '': if item[1] != '':
finallist.append(item) finallist.append(item)
return finallist return finallist
def has_option_with_value(self, section, option): def has_option_with_value(self, section, option):
if self.has_option(section, option): if self.has_option(section, option):
if self.get(section, option) == '': if self.get(section, option) == '':
return False return False
else: else:
return False return False
return True return True

View file

@ -1,229 +1,229 @@
# #
# This file is part of Mapnik (c++ mapping toolkit) # This file is part of Mapnik (c++ mapping toolkit)
# #
# Copyright (C) 2006 Jean-Francois Doyon # Copyright (C) 2006 Jean-Francois Doyon
# #
# Mapnik is free software; you can redistribute it and/or # Mapnik is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public # modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either # License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version. # version 2.1 of the License, or (at your option) any later version.
# #
# This library is distributed in the hope that it will be useful, # This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details. # Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# #
# $Id$ # $Id$
from common import ParameterDefinition, Response, Version, ListFactory, \ from common import ParameterDefinition, Response, Version, ListFactory, \
ColorFactory, CRSFactory, WMSBaseServiceHandler, CRS, \ ColorFactory, CRSFactory, WMSBaseServiceHandler, CRS, \
BaseExceptionHandler, Projection BaseExceptionHandler, Projection
from exceptions import OGCException, ServerConfigurationError from exceptions import OGCException, ServerConfigurationError
from lxml import etree as ElementTree from lxml import etree as ElementTree
from mapnik import Coord from mapnik import Coord
class ServiceHandler(WMSBaseServiceHandler): class ServiceHandler(WMSBaseServiceHandler):
SERVICE_PARAMS = { SERVICE_PARAMS = {
'GetCapabilities': { 'GetCapabilities': {
'updatesequence': ParameterDefinition(False, str) 'updatesequence': ParameterDefinition(False, str)
}, },
'GetMap': { 'GetMap': {
'layers': ParameterDefinition(True, ListFactory(str)), 'layers': ParameterDefinition(True, ListFactory(str)),
'styles': ParameterDefinition(True, ListFactory(str)), 'styles': ParameterDefinition(True, ListFactory(str)),
'srs': ParameterDefinition(True, CRSFactory(['EPSG'])), 'srs': ParameterDefinition(True, CRSFactory(['EPSG'])),
'bbox': ParameterDefinition(True, ListFactory(float)), 'bbox': ParameterDefinition(True, ListFactory(float)),
'width': ParameterDefinition(True, int), 'width': ParameterDefinition(True, int),
'height': ParameterDefinition(True, int), 'height': ParameterDefinition(True, int),
'format': ParameterDefinition(True, str, allowedvalues=('image/png', 'image/jpeg')), 'format': ParameterDefinition(True, str, allowedvalues=('image/png', 'image/jpeg')),
'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')), 'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')),
'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')), 'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')),
'exceptions': ParameterDefinition(False, str, 'application/vnd.ogc.se_xml', ('application/vnd.ogc.se_xml', 'application/vnd.ogc.se_inimage', 'application/vnd.ogc.se_blank')) 'exceptions': ParameterDefinition(False, str, 'application/vnd.ogc.se_xml', ('application/vnd.ogc.se_xml', 'application/vnd.ogc.se_inimage', 'application/vnd.ogc.se_blank'))
}, },
'GetFeatureInfo': { 'GetFeatureInfo': {
'layers': ParameterDefinition(True, ListFactory(str)), 'layers': ParameterDefinition(True, ListFactory(str)),
'styles': ParameterDefinition(False, ListFactory(str)), 'styles': ParameterDefinition(False, ListFactory(str)),
'srs': ParameterDefinition(True, CRSFactory(['EPSG'])), 'srs': ParameterDefinition(True, CRSFactory(['EPSG'])),
'bbox': ParameterDefinition(True, ListFactory(float)), 'bbox': ParameterDefinition(True, ListFactory(float)),
'width': ParameterDefinition(True, int), 'width': ParameterDefinition(True, int),
'height': ParameterDefinition(True, int), 'height': ParameterDefinition(True, int),
'format': ParameterDefinition(False, str, allowedvalues=('image/png', 'image/jpeg')), 'format': ParameterDefinition(False, str, allowedvalues=('image/png', 'image/jpeg')),
'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')), 'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')),
'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')), 'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')),
'exceptions': ParameterDefinition(False, str, 'application/vnd.ogc.se_xml', ('application/vnd.ogc.se_xml', 'application/vnd.ogc.se_inimage', 'application/vnd.ogc.se_blank')), 'exceptions': ParameterDefinition(False, str, 'application/vnd.ogc.se_xml', ('application/vnd.ogc.se_xml', 'application/vnd.ogc.se_inimage', 'application/vnd.ogc.se_blank')),
'query_layers': ParameterDefinition(True, ListFactory(str)), 'query_layers': ParameterDefinition(True, ListFactory(str)),
'info_format': ParameterDefinition(True, str, allowedvalues=('text/plain', 'text/xml')), 'info_format': ParameterDefinition(True, str, allowedvalues=('text/plain', 'text/xml')),
'feature_count': ParameterDefinition(False, int, 1), 'feature_count': ParameterDefinition(False, int, 1),
'x': ParameterDefinition(True, int), 'x': ParameterDefinition(True, int),
'y': ParameterDefinition(True, int) 'y': ParameterDefinition(True, int)
} }
} }
CONF_SERVICE = [ CONF_SERVICE = [
['title', 'Title', str], ['title', 'Title', str],
['abstract', 'Abstract', str], ['abstract', 'Abstract', str],
['onlineresource', 'OnlineResource', str], ['onlineresource', 'OnlineResource', str],
['fees', 'Fees', str], ['fees', 'Fees', str],
['accessconstraints', 'AccessConstraints', str], ['accessconstraints', 'AccessConstraints', str],
['keywordlist', 'KeywordList', str] ['keywordlist', 'KeywordList', str]
] ]
capabilitiesxmltemplate = """<?xml version="1.0" encoding="UTF-8" standalone="no"?> capabilitiesxmltemplate = """<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE WMT_MS_Capabilities SYSTEM "http://www.digitalearth.gov/wmt/xml/capabilities_1_1_1.dtd"> <!DOCTYPE WMT_MS_Capabilities SYSTEM "http://www.digitalearth.gov/wmt/xml/capabilities_1_1_1.dtd">
<WMT_MS_Capabilities version="1.1.1" updateSequence="0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.opengis.net/wms"> <WMT_MS_Capabilities version="1.1.1" updateSequence="0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.opengis.net/wms">
<Service> <Service>
<Name>WMS</Name> <Name>WMS</Name>
</Service> </Service>
<Capability> <Capability>
<Request> <Request>
<GetCapabilities> <GetCapabilities>
<Format>application/vnd.ogc.wms_xml</Format> <Format>application/vnd.ogc.wms_xml</Format>
<DCPType> <DCPType>
<HTTP> <HTTP>
<Get> <Get>
<OnlineResource xlink:type="simple"/> <OnlineResource xlink:type="simple"/>
</Get> </Get>
</HTTP> </HTTP>
</DCPType> </DCPType>
</GetCapabilities> </GetCapabilities>
<GetMap> <GetMap>
<Format>image/png</Format> <Format>image/png</Format>
<Format>image/jpeg</Format> <Format>image/jpeg</Format>
<DCPType> <DCPType>
<HTTP> <HTTP>
<Get> <Get>
<OnlineResource xlink:type="simple"/> <OnlineResource xlink:type="simple"/>
</Get> </Get>
</HTTP> </HTTP>
</DCPType> </DCPType>
</GetMap> </GetMap>
<GetFeatureInfo> <GetFeatureInfo>
<Format>text/plain</Format> <Format>text/plain</Format>
<DCPType> <DCPType>
<HTTP> <HTTP>
<Get> <Get>
<OnlineResource xlink:type="simple"/> <OnlineResource xlink:type="simple"/>
</Get> </Get>
</HTTP> </HTTP>
</DCPType> </DCPType>
</GetFeatureInfo> </GetFeatureInfo>
</Request> </Request>
<Exception> <Exception>
<Format>application/vnd.ogc.se_xml</Format> <Format>application/vnd.ogc.se_xml</Format>
<Format>application/vnd.ogc.se_inimage</Format> <Format>application/vnd.ogc.se_inimage</Format>
<Format>application/vnd.ogc.se_blank</Format> <Format>application/vnd.ogc.se_blank</Format>
</Exception> </Exception>
<Layer> <Layer>
<Title>A Mapnik WMS Server</Title> <Title>A Mapnik WMS Server</Title>
<Abstract>A Mapnik WMS Server</Abstract> <Abstract>A Mapnik WMS Server</Abstract>
</Layer> </Layer>
</Capability> </Capability>
</WMT_MS_Capabilities> </WMT_MS_Capabilities>
""" """
def __init__(self, conf, mapfactory, opsonlineresource): def __init__(self, conf, mapfactory, opsonlineresource):
self.conf = conf self.conf = conf
self.mapfactory = mapfactory self.mapfactory = mapfactory
self.opsonlineresource = opsonlineresource self.opsonlineresource = opsonlineresource
if self.conf.has_option('service', 'allowedepsgcodes'): if self.conf.has_option('service', 'allowedepsgcodes'):
self.allowedepsgcodes = map(lambda code: 'epsg:%s' % code, self.conf.get('service', 'allowedepsgcodes').split(',')) self.allowedepsgcodes = map(lambda code: 'epsg:%s' % code, self.conf.get('service', 'allowedepsgcodes').split(','))
else: else:
raise ServerConfigurationError('Allowed EPSG codes not properly configured.') raise ServerConfigurationError('Allowed EPSG codes not properly configured.')
self.capabilities = None self.capabilities = None
def GetCapabilities(self, params): def GetCapabilities(self, params):
if not self.capabilities: if not self.capabilities:
capetree = ElementTree.fromstring(self.capabilitiesxmltemplate) capetree = ElementTree.fromstring(self.capabilitiesxmltemplate)
elements = capetree.findall('Capability//OnlineResource') elements = capetree.findall('Capability//OnlineResource')
for element in elements: for element in elements:
element.set('{http://www.w3.org/1999/xlink}href', self.opsonlineresource) element.set('{http://www.w3.org/1999/xlink}href', self.opsonlineresource)
self.processServiceCapabilities(capetree) self.processServiceCapabilities(capetree)
rootlayerelem = capetree.find('{http://www.opengis.net/wms}Capability/{http://www.opengis.net/wms}Layer') rootlayerelem = capetree.find('{http://www.opengis.net/wms}Capability/{http://www.opengis.net/wms}Layer')
for epsgcode in self.allowedepsgcodes: for epsgcode in self.allowedepsgcodes:
rootlayercrs = ElementTree.Element('SRS') rootlayercrs = ElementTree.Element('SRS')
rootlayercrs.text = epsgcode.upper() rootlayercrs.text = epsgcode.upper()
rootlayerelem.append(rootlayercrs) rootlayerelem.append(rootlayercrs)
for layer in self.mapfactory.layers.values(): for layer in self.mapfactory.layers.values():
layerproj = Projection(layer.srs) layerproj = Projection(layer.srs)
layername = ElementTree.Element('Name') layername = ElementTree.Element('Name')
layername.text = layer.name layername.text = layer.name
env = layer.envelope() env = layer.envelope()
llp = layerproj.inverse(Coord(env.minx, env.miny)) llp = layerproj.inverse(Coord(env.minx, env.miny))
urp = layerproj.inverse(Coord(env.maxx, env.maxy)) urp = layerproj.inverse(Coord(env.maxx, env.maxy))
latlonbb = ElementTree.Element('LatLonBoundingBox') latlonbb = ElementTree.Element('LatLonBoundingBox')
latlonbb.set('minx', str(llp.x)) latlonbb.set('minx', str(llp.x))
latlonbb.set('miny', str(llp.y)) latlonbb.set('miny', str(llp.y))
latlonbb.set('maxx', str(urp.x)) latlonbb.set('maxx', str(urp.x))
latlonbb.set('maxy', str(urp.y)) latlonbb.set('maxy', str(urp.y))
layerbbox = ElementTree.Element('BoundingBox') layerbbox = ElementTree.Element('BoundingBox')
layerbbox.set('SRS', layerproj.epsgstring()) layerbbox.set('SRS', layerproj.epsgstring())
layerbbox.set('minx', str(env.minx)) layerbbox.set('minx', str(env.minx))
layerbbox.set('miny', str(env.miny)) layerbbox.set('miny', str(env.miny))
layerbbox.set('maxx', str(env.maxx)) layerbbox.set('maxx', str(env.maxx))
layerbbox.set('maxy', str(env.maxy)) layerbbox.set('maxy', str(env.maxy))
layere = ElementTree.Element('Layer') layere = ElementTree.Element('Layer')
layere.append(layername) layere.append(layername)
if layer.title: if layer.title:
layertitle = ElementTree.Element('Title') layertitle = ElementTree.Element('Title')
layertitle.text = layer.title layertitle.text = layer.title
layere.append(layertitle) layere.append(layertitle)
if layer.abstract: if layer.abstract:
layerabstract = ElementTree.Element('Abstract') layerabstract = ElementTree.Element('Abstract')
layerabstract.text = layer.abstract layerabstract.text = layer.abstract
layere.append(layerabstract) layere.append(layerabstract)
if layer.queryable: if layer.queryable:
layere.set('queryable', '1') layere.set('queryable', '1')
layere.append(latlonbb) layere.append(latlonbb)
layere.append(layerbbox) layere.append(layerbbox)
if len(layer.wmsextrastyles) > 0: if len(layer.wmsextrastyles) > 0:
for extrastyle in [layer.wmsdefaultstyle] + list(layer.wmsextrastyles): for extrastyle in [layer.wmsdefaultstyle] + list(layer.wmsextrastyles):
style = ElementTree.Element('Style') style = ElementTree.Element('Style')
stylename = ElementTree.Element('Name') stylename = ElementTree.Element('Name')
stylename.text = extrastyle stylename.text = extrastyle
styletitle = ElementTree.Element('Title') styletitle = ElementTree.Element('Title')
styletitle.text = extrastyle styletitle.text = extrastyle
style.append(stylename) style.append(stylename)
style.append(styletitle) style.append(styletitle)
layere.append(style) layere.append(style)
rootlayerelem.append(layere) rootlayerelem.append(layere)
self.capabilities = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' + ElementTree.tostring(capetree) self.capabilities = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' + ElementTree.tostring(capetree)
response = Response('application/vnd.ogc.wms_xml', self.capabilities) response = Response('application/vnd.ogc.wms_xml', self.capabilities)
return response return response
def GetMap(self, params): def GetMap(self, params):
params['crs'] = params['srs'] params['crs'] = params['srs']
return WMSBaseServiceHandler.GetMap(self, params) return WMSBaseServiceHandler.GetMap(self, params)
def GetFeatureInfo(self, params): def GetFeatureInfo(self, params):
params['crs'] = params['srs'] params['crs'] = params['srs']
params['i'] = params['x'] params['i'] = params['x']
params['j'] = params['y'] params['j'] = params['y']
return WMSBaseServiceHandler.GetFeatureInfo(self, params, 'query_map_point') return WMSBaseServiceHandler.GetFeatureInfo(self, params, 'query_map_point')
class ExceptionHandler(BaseExceptionHandler): class ExceptionHandler(BaseExceptionHandler):
xmlmimetype = "application/vnd.ogc.se_xml" xmlmimetype = "application/vnd.ogc.se_xml"
xmltemplate = ElementTree.fromstring("""<?xml version='1.0' encoding="UTF-8" standalone="no"?> xmltemplate = ElementTree.fromstring("""<?xml version='1.0' encoding="UTF-8" standalone="no"?>
<!DOCTYPE ServiceExceptionReport SYSTEM "http://www.digitalearth.gov/wmt/xml/exception_1_1_1.dtd"> <!DOCTYPE ServiceExceptionReport SYSTEM "http://www.digitalearth.gov/wmt/xml/exception_1_1_1.dtd">
<ServiceExceptionReport version="1.1.1"> <ServiceExceptionReport version="1.1.1">
<ServiceException /> <ServiceException />
</ServiceExceptionReport> </ServiceExceptionReport>
""") """)
xpath = 'ServiceException' xpath = 'ServiceException'
handlers = {'application/vnd.ogc.se_xml': BaseExceptionHandler.xmlhandler, handlers = {'application/vnd.ogc.se_xml': BaseExceptionHandler.xmlhandler,
'application/vnd.ogc.se_inimage': BaseExceptionHandler.inimagehandler, 'application/vnd.ogc.se_inimage': BaseExceptionHandler.inimagehandler,
'application/vnd.ogc.se_blank': BaseExceptionHandler.blankhandler} 'application/vnd.ogc.se_blank': BaseExceptionHandler.blankhandler}
defaulthandler = 'application/vnd.ogc.se_xml' defaulthandler = 'application/vnd.ogc.se_xml'

View file

@ -1,240 +1,240 @@
# #
# This file is part of Mapnik (c++ mapping toolkit) # This file is part of Mapnik (c++ mapping toolkit)
# #
# Copyright (C) 2006 Jean-Francois Doyon # Copyright (C) 2006 Jean-Francois Doyon
# #
# Mapnik is free software; you can redistribute it and/or # Mapnik is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public # modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either # License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version. # version 2.1 of the License, or (at your option) any later version.
# #
# This library is distributed in the hope that it will be useful, # This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of # but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details. # Lesser General Public License for more details.
# #
# You should have received a copy of the GNU Lesser General Public # You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software # License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# #
# $Id$ # $Id$
from common import ParameterDefinition, Response, Version, ListFactory, \ from common import ParameterDefinition, Response, Version, ListFactory, \
ColorFactory, CRSFactory, CRS, WMSBaseServiceHandler, \ ColorFactory, CRSFactory, CRS, WMSBaseServiceHandler, \
BaseExceptionHandler, Projection BaseExceptionHandler, Projection
from exceptions import OGCException, ServerConfigurationError from exceptions import OGCException, ServerConfigurationError
from lxml import etree as ElementTree from lxml import etree as ElementTree
from mapnik import Coord from mapnik import Coord
class ServiceHandler(WMSBaseServiceHandler): class ServiceHandler(WMSBaseServiceHandler):
SERVICE_PARAMS = { SERVICE_PARAMS = {
'GetCapabilities': { 'GetCapabilities': {
'format': ParameterDefinition(False, str, 'text/xml', ('text/xml',), True), 'format': ParameterDefinition(False, str, 'text/xml', ('text/xml',), True),
'updatesequence': ParameterDefinition(False, str) 'updatesequence': ParameterDefinition(False, str)
}, },
'GetMap': { 'GetMap': {
'layers': ParameterDefinition(True, ListFactory(str)), 'layers': ParameterDefinition(True, ListFactory(str)),
'styles': ParameterDefinition(True, ListFactory(str)), 'styles': ParameterDefinition(True, ListFactory(str)),
'crs': ParameterDefinition(True, CRSFactory(['EPSG'])), 'crs': ParameterDefinition(True, CRSFactory(['EPSG'])),
'bbox': ParameterDefinition(True, ListFactory(float)), 'bbox': ParameterDefinition(True, ListFactory(float)),
'width': ParameterDefinition(True, int), 'width': ParameterDefinition(True, int),
'height': ParameterDefinition(True, int), 'height': ParameterDefinition(True, int),
'format': ParameterDefinition(True, str, allowedvalues=('image/png', 'image/jpeg')), 'format': ParameterDefinition(True, str, allowedvalues=('image/png', 'image/jpeg')),
'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')), 'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')),
'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')), 'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')),
'exceptions': ParameterDefinition(False, str, 'XML', ('XML', 'INIMAGE', 'BLANK')), 'exceptions': ParameterDefinition(False, str, 'XML', ('XML', 'INIMAGE', 'BLANK')),
}, },
'GetFeatureInfo': { 'GetFeatureInfo': {
'layers': ParameterDefinition(True, ListFactory(str)), 'layers': ParameterDefinition(True, ListFactory(str)),
'styles': ParameterDefinition(False, ListFactory(str)), 'styles': ParameterDefinition(False, ListFactory(str)),
'crs': ParameterDefinition(True, CRSFactory(['EPSG'])), 'crs': ParameterDefinition(True, CRSFactory(['EPSG'])),
'bbox': ParameterDefinition(True, ListFactory(float)), 'bbox': ParameterDefinition(True, ListFactory(float)),
'width': ParameterDefinition(True, int), 'width': ParameterDefinition(True, int),
'height': ParameterDefinition(True, int), 'height': ParameterDefinition(True, int),
'format': ParameterDefinition(False, str, allowedvalues=('image/png', 'image/jpeg')), 'format': ParameterDefinition(False, str, allowedvalues=('image/png', 'image/jpeg')),
'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')), 'transparent': ParameterDefinition(False, str, 'FALSE', ('TRUE', 'FALSE')),
'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')), 'bgcolor': ParameterDefinition(False, ColorFactory, ColorFactory('0xFFFFFF')),
'exceptions': ParameterDefinition(False, str, 'XML', ('XML', 'INIMAGE', 'BLANK')), 'exceptions': ParameterDefinition(False, str, 'XML', ('XML', 'INIMAGE', 'BLANK')),
'query_layers': ParameterDefinition(True, ListFactory(str)), 'query_layers': ParameterDefinition(True, ListFactory(str)),
'info_format': ParameterDefinition(True, str, allowedvalues=('text/plain', 'text/xml')), 'info_format': ParameterDefinition(True, str, allowedvalues=('text/plain', 'text/xml')),
'feature_count': ParameterDefinition(False, int, 1), 'feature_count': ParameterDefinition(False, int, 1),
'i': ParameterDefinition(True, float), 'i': ParameterDefinition(True, float),
'j': ParameterDefinition(True, float) 'j': ParameterDefinition(True, float)
} }
} }
CONF_SERVICE = [ CONF_SERVICE = [
['title', 'Title', str], ['title', 'Title', str],
['abstract', 'Abstract', str], ['abstract', 'Abstract', str],
['onlineresource', 'OnlineResource', str], ['onlineresource', 'OnlineResource', str],
['fees', 'Fees', str], ['fees', 'Fees', str],
['accessconstraints', 'AccessConstraints', str], ['accessconstraints', 'AccessConstraints', str],
['layerlimit', 'LayerLimit', int], ['layerlimit', 'LayerLimit', int],
['maxwidth', 'MaxWidth', int], ['maxwidth', 'MaxWidth', int],
['maxheight', 'MaxHeight', int], ['maxheight', 'MaxHeight', int],
['keywordlist', 'KeywordList', str] ['keywordlist', 'KeywordList', str]
] ]
capabilitiesxmltemplate = """<?xml version="1.0" encoding="UTF-8"?> capabilitiesxmltemplate = """<?xml version="1.0" encoding="UTF-8"?>
<WMS_Capabilities version="1.3.0" xmlns="http://www.opengis.net/wms" <WMS_Capabilities version="1.3.0" xmlns="http://www.opengis.net/wms"
xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd"> xsi:schemaLocation="http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd">
<Service> <Service>
<Name>WMS</Name> <Name>WMS</Name>
</Service> </Service>
<Capability> <Capability>
<Request> <Request>
<GetCapabilities> <GetCapabilities>
<Format>text/xml</Format> <Format>text/xml</Format>
<DCPType> <DCPType>
<HTTP> <HTTP>
<Get> <Get>
<OnlineResource xlink:type="simple"/> <OnlineResource xlink:type="simple"/>
</Get> </Get>
</HTTP> </HTTP>
</DCPType> </DCPType>
</GetCapabilities> </GetCapabilities>
<GetMap> <GetMap>
<Format>image/png</Format> <Format>image/png</Format>
<Format>image/jpeg</Format> <Format>image/jpeg</Format>
<DCPType> <DCPType>
<HTTP> <HTTP>
<Get> <Get>
<OnlineResource xlink:type="simple"/> <OnlineResource xlink:type="simple"/>
</Get> </Get>
</HTTP> </HTTP>
</DCPType> </DCPType>
</GetMap> </GetMap>
<GetFeatureInfo> <GetFeatureInfo>
<Format>text/plain</Format> <Format>text/plain</Format>
<DCPType> <DCPType>
<HTTP> <HTTP>
<Get> <Get>
<OnlineResource xlink:type="simple"/> <OnlineResource xlink:type="simple"/>
</Get> </Get>
</HTTP> </HTTP>
</DCPType> </DCPType>
</GetFeatureInfo> </GetFeatureInfo>
</Request> </Request>
<Exception> <Exception>
<Format>XML</Format> <Format>XML</Format>
<Format>INIMAGE</Format> <Format>INIMAGE</Format>
<Format>BLANK</Format> <Format>BLANK</Format>
</Exception> </Exception>
<Layer> <Layer>
<Title>A Mapnik WMS Server</Title> <Title>A Mapnik WMS Server</Title>
<Abstract>A Mapnik WMS Server</Abstract> <Abstract>A Mapnik WMS Server</Abstract>
</Layer> </Layer>
</Capability> </Capability>
</WMS_Capabilities> </WMS_Capabilities>
""" """
def __init__(self, conf, mapfactory, opsonlineresource): def __init__(self, conf, mapfactory, opsonlineresource):
self.conf = conf self.conf = conf
self.mapfactory = mapfactory self.mapfactory = mapfactory
self.opsonlineresource = opsonlineresource self.opsonlineresource = opsonlineresource
if self.conf.has_option('service', 'allowedepsgcodes'): if self.conf.has_option('service', 'allowedepsgcodes'):
self.allowedepsgcodes = map(lambda code: 'epsg:%s' % code, self.conf.get('service', 'allowedepsgcodes').split(',')) self.allowedepsgcodes = map(lambda code: 'epsg:%s' % code, self.conf.get('service', 'allowedepsgcodes').split(','))
else: else:
raise ServerConfigurationError('Allowed EPSG codes not properly configured.') raise ServerConfigurationError('Allowed EPSG codes not properly configured.')
self.capabilities = None self.capabilities = None
def GetCapabilities(self, params): def GetCapabilities(self, params):
if not self.capabilities: if not self.capabilities:
capetree = ElementTree.fromstring(self.capabilitiesxmltemplate) capetree = ElementTree.fromstring(self.capabilitiesxmltemplate)
elements = capetree.findall('{http://www.opengis.net/wms}Capability//{http://www.opengis.net/wms}OnlineResource') elements = capetree.findall('{http://www.opengis.net/wms}Capability//{http://www.opengis.net/wms}OnlineResource')
for element in elements: for element in elements:
element.set('{http://www.w3.org/1999/xlink}href', self.opsonlineresource) element.set('{http://www.w3.org/1999/xlink}href', self.opsonlineresource)
self.processServiceCapabilities(capetree) self.processServiceCapabilities(capetree)
rootlayerelem = capetree.find('{http://www.opengis.net/wms}Capability/{http://www.opengis.net/wms}Layer') rootlayerelem = capetree.find('{http://www.opengis.net/wms}Capability/{http://www.opengis.net/wms}Layer')
for epsgcode in self.allowedepsgcodes: for epsgcode in self.allowedepsgcodes:
rootlayercrs = ElementTree.Element('CRS') rootlayercrs = ElementTree.Element('CRS')
rootlayercrs.text = epsgcode.upper() rootlayercrs.text = epsgcode.upper()
rootlayerelem.append(rootlayercrs) rootlayerelem.append(rootlayercrs)
for layer in self.mapfactory.layers.values(): for layer in self.mapfactory.layers.values():
layerproj = Projection(layer.srs) layerproj = Projection(layer.srs)
layername = ElementTree.Element('Name') layername = ElementTree.Element('Name')
layername.text = layer.name layername.text = layer.name
env = layer.envelope() env = layer.envelope()
layerexgbb = ElementTree.Element('EX_GeographicBoundingBox') layerexgbb = ElementTree.Element('EX_GeographicBoundingBox')
ll = layerproj.inverse(Coord(env.minx, env.miny)) ll = layerproj.inverse(Coord(env.minx, env.miny))
ur = layerproj.inverse(Coord(env.maxx, env.maxy)) ur = layerproj.inverse(Coord(env.maxx, env.maxy))
exgbb_wbl = ElementTree.Element('westBoundLongitude') exgbb_wbl = ElementTree.Element('westBoundLongitude')
exgbb_wbl.text = str(ll.x) exgbb_wbl.text = str(ll.x)
layerexgbb.append(exgbb_wbl) layerexgbb.append(exgbb_wbl)
exgbb_ebl = ElementTree.Element('eastBoundLongitude') exgbb_ebl = ElementTree.Element('eastBoundLongitude')
exgbb_ebl.text = str(ur.x) exgbb_ebl.text = str(ur.x)
layerexgbb.append(exgbb_ebl) layerexgbb.append(exgbb_ebl)
exgbb_sbl = ElementTree.Element('southBoundLatitude') exgbb_sbl = ElementTree.Element('southBoundLatitude')
exgbb_sbl.text = str(ll.y) exgbb_sbl.text = str(ll.y)
layerexgbb.append(exgbb_sbl) layerexgbb.append(exgbb_sbl)
exgbb_nbl = ElementTree.Element('northBoundLatitude') exgbb_nbl = ElementTree.Element('northBoundLatitude')
exgbb_nbl.text = str(ur.y) exgbb_nbl.text = str(ur.y)
layerexgbb.append(exgbb_nbl) layerexgbb.append(exgbb_nbl)
layerbbox = ElementTree.Element('BoundingBox') layerbbox = ElementTree.Element('BoundingBox')
layerbbox.set('CRS', layerproj.epsgstring()) layerbbox.set('CRS', layerproj.epsgstring())
layerbbox.set('minx', str(env.minx)) layerbbox.set('minx', str(env.minx))
layerbbox.set('miny', str(env.miny)) layerbbox.set('miny', str(env.miny))
layerbbox.set('maxx', str(env.maxx)) layerbbox.set('maxx', str(env.maxx))
layerbbox.set('maxy', str(env.maxy)) layerbbox.set('maxy', str(env.maxy))
layere = ElementTree.Element('Layer') layere = ElementTree.Element('Layer')
layere.append(layername) layere.append(layername)
if layer.title: if layer.title:
layertitle = ElementTree.Element('Title') layertitle = ElementTree.Element('Title')
layertitle.text = layer.title layertitle.text = layer.title
layere.append(layertitle) layere.append(layertitle)
if layer.abstract: if layer.abstract:
layerabstract = ElementTree.Element('Abstract') layerabstract = ElementTree.Element('Abstract')
layerabstract.text = layer.abstract layerabstract.text = layer.abstract
layere.append(layerabstract) layere.append(layerabstract)
if layer.queryable: if layer.queryable:
layere.set('queryable', '1') layere.set('queryable', '1')
layere.append(layerexgbb) layere.append(layerexgbb)
layere.append(layerbbox) layere.append(layerbbox)
if len(layer.wmsextrastyles) > 0: if len(layer.wmsextrastyles) > 0:
for extrastyle in [layer.wmsdefaultstyle] + list(layer.wmsextrastyles): for extrastyle in [layer.wmsdefaultstyle] + list(layer.wmsextrastyles):
style = ElementTree.Element('Style') style = ElementTree.Element('Style')
stylename = ElementTree.Element('Name') stylename = ElementTree.Element('Name')
stylename.text = extrastyle stylename.text = extrastyle
styletitle = ElementTree.Element('Title') styletitle = ElementTree.Element('Title')
styletitle.text = extrastyle styletitle.text = extrastyle
style.append(stylename) style.append(stylename)
style.append(styletitle) style.append(styletitle)
layere.append(style) layere.append(style)
rootlayerelem.append(layere) rootlayerelem.append(layere)
self.capabilities = '<?xml version="1.0" encoding="UTF-8"?>' + ElementTree.tostring(capetree) self.capabilities = '<?xml version="1.0" encoding="UTF-8"?>' + ElementTree.tostring(capetree)
response = Response('text/xml', self.capabilities) response = Response('text/xml', self.capabilities)
return response return response
def GetMap(self, params): def GetMap(self, params):
if params['width'] > int(self.conf.get('service', 'maxwidth')) or params['height'] > int(self.conf.get('service', 'maxheight')): if params['width'] > int(self.conf.get('service', 'maxwidth')) or params['height'] > int(self.conf.get('service', 'maxheight')):
raise OGCException('Requested map size exceeds limits set by this server.') raise OGCException('Requested map size exceeds limits set by this server.')
return WMSBaseServiceHandler.GetMap(self, params) return WMSBaseServiceHandler.GetMap(self, params)
class ExceptionHandler(BaseExceptionHandler): class ExceptionHandler(BaseExceptionHandler):
xmlmimetype = "text/xml" xmlmimetype = "text/xml"
xmltemplate = ElementTree.fromstring("""<?xml version='1.0' encoding="UTF-8"?> xmltemplate = ElementTree.fromstring("""<?xml version='1.0' encoding="UTF-8"?>
<ServiceExceptionReport version="1.3.0" <ServiceExceptionReport version="1.3.0"
xmlns="http://www.opengis.net/ogc" xmlns="http://www.opengis.net/ogc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd"> xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd">
<ServiceException/> <ServiceException/>
</ServiceExceptionReport> </ServiceExceptionReport>
""") """)
xpath = '{http://www.opengis.net/ogc}ServiceException' xpath = '{http://www.opengis.net/ogc}ServiceException'
handlers = {'XML': BaseExceptionHandler.xmlhandler, handlers = {'XML': BaseExceptionHandler.xmlhandler,
'INIMAGE': BaseExceptionHandler.inimagehandler, 'INIMAGE': BaseExceptionHandler.inimagehandler,
'BLANK': BaseExceptionHandler.blankhandler} 'BLANK': BaseExceptionHandler.blankhandler}
defaulthandler = 'XML' defaulthandler = 'XML'