- Improve WMS compliance
- Remove unused code - Rework layer and style bulding - minor doc changes
This commit is contained in:
parent
39d14bdb5f
commit
af55c99fa4
7 changed files with 69 additions and 57 deletions
|
@ -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)
|
||||
"""
|
|
@ -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]:
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -37,3 +37,7 @@ epsg=4326
|
|||
# resource pointing to the CGI.
|
||||
|
||||
onlineresource=http://www.mapnik.org/
|
||||
|
||||
[contact]
|
||||
name=
|
||||
email=
|
||||
|
|
Loading…
Add table
Reference in a new issue