- Improve WMS compliance

- Remove unused code
- Rework layer and style bulding
- minor doc changes
This commit is contained in:
Jean-Francois Doyon 2006-04-13 02:39:49 +00:00
parent 39d14bdb5f
commit af55c99fa4
7 changed files with 69 additions and 57 deletions

View file

@ -37,48 +37,44 @@ class Handler(cgi.DebugHandler):
conf.readfp(open(self.configpath))
self.conf = conf
mapfactorymodule = __import__(conf.get('server', 'module'))
self.mapfactory = getattr(mapfactorymodule, 'MapFactory')()
self.requesthandlers = {}
self.mapfactory = getattr(mapfactorymodule, 'WMSFactory')()
def process(self, req):
exceptionhandler = ExceptionHandler
reqparams = {}
for key, value in req.params.items():
reqparams[key.lower()] = value
onlineresource = 'http://%s:%s%s' % (req.environ['SERVER_NAME'], req.environ['SERVER_PORT'], req.environ['SCRIPT_NAME'])
onlineresource = 'http://%s:%s%s?' % (req.environ['SERVER_NAME'], req.environ['SERVER_PORT'], req.environ['SCRIPT_NAME'])
# try:
if not reqparams.has_key('request'):
raise OGCException('Missing request parameter.')
if reqparams['request'] == 'GetCapabilities' and not reqparams.has_key('service'):
raise OGCException('Missing service parameter.')
if reqparams['request'] in ['GetMap', 'GetFeatureInfo']:
reqparams['service'] = 'wms'
service = reqparams['service'].lower()
try:
if not reqparams.has_key('request'):
raise OGCException('Missing request parameter.')
request = reqparams['request'].lower()
if request == 'getcapabilities' and not reqparams.has_key('service'):
raise OGCException('Missing service parameter.')
if request in ['getmap', 'getfeatureinfo']:
reqparams['service'] = 'wms'
service = reqparams['service'].lower()
srkey = (service, request)
if self.requesthandlers.has_key(srkey):
requesthandler = self.requesthandlers[srkey]
else:
try:
mapnikmodule = __import__('mapnik.ogcserver.' + service)
except:
raise OGCException('Unsupported service "%s".' % service)
ServiceHandlerFactory = getattr(mapnikmodule.ogcserver, service).ServiceHandlerFactory
servicehandler, exceptionhandler = ServiceHandlerFactory(self.conf, self.mapfactory, onlineresource, reqparams.get('version', None))
if request not in servicehandler.SERVICE_PARAMS.keys():
raise OGCException('Operation "%s" not supported.' % request, 'OperationNotSupported')
ogcparams = servicehandler.processParameters(request, reqparams)
try:
requesthandler = getattr(servicehandler, request)
except:
raise OGCException('Operation "%s" not supported.' % request, 'OperationNotSupported')
else:
self.requesthandlers[srkey] = requesthandler
response = requesthandler(ogcparams)
mapnikmodule = __import__('mapnik.ogcserver.' + service)
except:
raise OGCException('Unsupported service "%s".' % service)
ServiceHandlerFactory = getattr(mapnikmodule.ogcserver, service).ServiceHandlerFactory
servicehandler, exceptionhandler = ServiceHandlerFactory(self.conf, self.mapfactory, onlineresource, reqparams.get('version', None))
if reqparams['request'] not in servicehandler.SERVICE_PARAMS.keys():
raise OGCException('Operation "%s" not supported.' % reqparams['request'], 'OperationNotSupported')
ogcparams = servicehandler.processParameters(reqparams['request'], reqparams)
try:
requesthandler = getattr(servicehandler, reqparams['request'])
except:
raise OGCException('Operation "%s" not supported.' % reqparams['request'], 'OperationNotSupported')
response = requesthandler(ogcparams)
# except:
# raise
# else:
req.set_header('Content-Type', response.content_type)
req.write(response.content)
"""
except OGCException:
eh = exceptionhandler()
req.set_header('Content-Type', eh.mimetype)
req.write(ElementTree.tostring(eh.getexcetree(sys.exc_info()[1])))
else:
req.set_header('Content-Type', response.content_type)
req.write(response.content)
"""

View file

@ -194,7 +194,7 @@ class CRSFactory:
class WMSBaseServiceHandler(BaseServiceHandler):
def getmap(self, params):
def GetMap(self, params):
if str(params['crs']) != str(self.crs):
raise OGCException('Unsupported CRS requested. Must be "%s" and not "%s".' % (self.crs, params['crs']), 'InvalidCRS')
if params['bbox'][0] >= params['bbox'][2]:

View file

@ -35,4 +35,12 @@ def ServiceHandlerFactory(conf, mapfactory, onlineresource, version):
if version >= '1.3.0':
return (ServiceHandler130(conf, mapfactory, onlineresource), ExceptionHandler130)
else:
return (ServiceHandler111(conf, mapfactory, onlineresource), ExceptionHandler111)
return (ServiceHandler111(conf, mapfactory, onlineresource), ExceptionHandler111)
class BaseWMSFactory:
def registerLayer(self, layer):
pass
def registerStyle(self, name, style):
pass

View file

@ -27,10 +27,10 @@ from lxml import etree as ElementTree
class ServiceHandler(WMSBaseServiceHandler):
SERVICE_PARAMS = {
'getcapabilities': {
'GetCapabilities': {
'updatesequence': ParameterDefinition(False, str)
},
'getmap': {
'GetMap': {
'version': ParameterDefinition(True, Version, allowedvalues=(Version('1.1.1'),)),
'layers': ParameterDefinition(True, ListFactory(str)),
'styles': ParameterDefinition(True, ListFactory(str)),
@ -109,7 +109,6 @@ class ServiceHandler(WMSBaseServiceHandler):
self.crs = CRS('EPSG', self.conf.get('service', 'epsg'))
else:
ServerConfigurationError('EPSG code not properly configured.')
if not opsonlineresource.endswith('?'): opsonlineresource += '?'
capetree = ElementTree.fromstring(self.capabilitiesxmltemplate)
@ -169,7 +168,7 @@ class ServiceHandler(WMSBaseServiceHandler):
self.capabilities = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n' + ElementTree.tostring(capetree)
def getcapabilities(self, params):
def GetCapabilities(self, params):
response = Response('application/vnd.ogc.wms_xml', self.capabilities)
return response

View file

@ -27,11 +27,11 @@ from lxml import etree as ElementTree
class ServiceHandler(WMSBaseServiceHandler):
SERVICE_PARAMS = {
'getcapabilities': {
'GetCapabilities': {
'format': ParameterDefinition(False, str, 'text/xml', ('text/xml',), True),
'updatesequence': ParameterDefinition(False, str)
},
'getmap': {
'GetMap': {
'version': ParameterDefinition(True, Version, allowedvalues=(Version('1.3.0'),)),
'layers': ParameterDefinition(True, ListFactory(str)),
'styles': ParameterDefinition(True, ListFactory(str)),
@ -115,7 +115,6 @@ class ServiceHandler(WMSBaseServiceHandler):
self.crs = CRS('EPSG', self.conf.get('service', 'epsg'))
else:
raise ServerConfigurationError('EPSG code not properly configured.')
if not opsonlineresource.endswith('?'): opsonlineresource += '?'
capetree = ElementTree.fromstring(self.capabilitiesxmltemplate)
@ -184,14 +183,14 @@ class ServiceHandler(WMSBaseServiceHandler):
self.capabilities = '<?xml version="1.0" encoding="UTF-8"?>' + ElementTree.tostring(capetree)
def getcapabilities(self, params):
def GetCapabilities(self, params):
response = Response('text/xml', self.capabilities)
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')):
raise OGCException('Requested map size exceeds limits set by this server.')
return WMSBaseServiceHandler.getmap(self, params)
return WMSBaseServiceHandler.GetMap(self, params)
class ExceptionHandler(BaseExceptionHandler):

View file

@ -3,11 +3,14 @@
Mapnik OGC Server
-----------------
Introduction
------------
Mapnik provides an OGC server package to allow the publishing of maps
through open and standard interfaces. It is in implemented in Python.
Mapnik provides a server package to allow the publishing of maps
through the open and standard WMS interface published by the Open Geospatial
Consortium (OGC). It is in implemented in Python, around the core C++
library.
Features/Caveats
@ -19,6 +22,7 @@ Features/Caveats
- GIF/JPEG/PNG output
- XML error handling only
- No real layer metadata support yet
- No re-projection support
Dependencies
@ -70,21 +74,23 @@ Configuring the server
- Copy the sample configuration "ogcserver.conf" file in utils/ogcserver to
the location you specified in the previous step.
- Edit the file to your liking, the comments within the file will help you
further. Be sure to at the very minimum edit the "module" parameter, the
server will not work without you setting it properly first.
- Edit the configuration file to your liking, the comments within the file will
help you further. Be sure to at the very minimum edit the "module"
parameter, the server will not work without you setting it properly first.
Creating a map for use by the ogcserver
---------------------------------------
Defining layers and styles for use by the ogcserver
---------------------------------------------------
The ogcserver obviously needs a map to publish. For now, with Mapnik, this
The ogcserver obviously needs layers to publish. For now, with Mapnik, this
can only be done by writing code. In this case, a Python script will need to be
written to describe the map's layers and styles. For information on the Python
written to describe the layers and respective styles. For information on the Python
API, look in demo/python, or in docs/epydocs.
The server needs a module, and a class that looks like this:
The server needs a python module, with code that looks like this:
from mapnik.ogcserver.wms import BaseWMSFactory
class MapFactory:
def __init(self):

View file

@ -37,3 +37,7 @@ epsg=4326
# resource pointing to the CGI.
onlineresource=http://www.mapnik.org/
[contact]
name=
email=