[Mapnik-devel] Prototype WMS interface to Mapnik (cherry_mapnik.py)
Matthew Perry
perrygeo at gmail.com
Wed Apr 5 09:20:03 CEST 2006
Well sounds like you got alot further that I have! Let us know where
we can access the code and I'll take it for a spin. Will this
eventually become part of the mapnik distribution?
matt
On 4/4/06, Jean-François Doyon <jfdoyon at gmail.com> wrote:
> Cool!
>
> I've been working on a CGI/FastCGI OGC Server for Mapnik the last little
> while.
>
> I have a working WMS 1.3.0, but not client, so I'm going to implement a
> 1.1.1 very soon now :)
>
> It uses jonpy and ElementTree, and is also a framework to facilitate
> writing other OGC servers (like WFS or WCS).
>
> We'll see if I can get something committed tonight :)
>
> J.F.
>
> Matthew Perry wrote:
> > Hey mapnikers,
> >
> > So the nice rainy sunday prompted me to resume my trials with
> > mapnik. I was able to build the latest SVN against the ubuntu 6.04
> > boost libraries and everything went well. Alot has changed since the
> > tutorial on the website and that threw me off for a few minutes until
> > I found the excellent demo script! Beautiful cartography. Beautiful
> > python.
> >
> > I have also been working a bit evaluating python web application
> > frameworks and cherrypy impressed me with it's ease of use and very
> > "pythonic" approach.
> >
> > So putting the two together, I worked up a simple pseudo-WMS server
> > as an interface to mapnik. I say pseudo-WMS server because it doesn't
> > even come close to complying with the WMS spec. The only thing it can
> > do is handle a simple GetMap request:
> > http://localhost:8080/wms?VERSION=1.1.1&REQUEST=GetMap&LAYERS=states&FORMAT=image/jpeg&SRS=EPSG:4326&STYLES=&BBOX=-120,15,-70,65&width=400&height=400
> >
> > But for some very simple WMS clients, this is all you need. I set up a
> > nifty little interactive map using wms-map
> > (http://wms-map.sourceforge.net/) which I'll make public as soon as I
> > get mapnik installed on a server somewhere.
> >
> > Cherrypy servers run as standalone servers bound to a specific port
> > but can optionally be put behind an apache server... Setting up this
> > WMS server as a standalone should be fairly simple. You'll need the
> > cherrypy and mapnik python modules to start. There is a createMap()
> > function that contains all the usual mapnik code which you can tweak
> > for your specific data. Then there is a WMS class that parses the WMS
> > requests and passes them off to createMap() which writes an image to
> > disk and returns the map image to the client. I didn't have alot of
> > time to spend so this only a proof-of-concept.
> >
> > My initial testing against a Mapserver-based WMS (running on the same
> > machine, same dataset) indicates that for single requests, Mapserver
> > is only about 15% faster. But for many simultaneous requests (such as
> > the tiled WMS clients make; 9 requests on every pan) mapnik/cherrypy
> > is 3-400% faster (!!) under a decent load. Put this behind an apache
> > server and you could have a fast, solid WMS server with mapnik on the
> > backend. Plus mapnik's image quality is by far the most impressive of
> > any map rendering engine i've seen! Here's a screenshot comparing the
> > WMS clients based on both mapserver and mapnik -
> > http://perrygeo.net/img/mapserver_mapnik.png (a screenshot of one of
> > my favorite places in the world. any guesses??). Just look at that
> > beautiful line work.. did I mention I was impressed?
> >
> > Attached is the code. Please give the prototype WMS server a shot and
> > let me know how it goes. My understanding of both mapnik and cherrypy
> > is limited so please jump in and make suggestions.
> >
> > --
> > Matt Perry
> > perrygeo at gmail.com
> > http://www.perrygeo.net
> >
> > ------------------------------------------------------------------------
> >
> > #!/usr/bin/env python
> > """
> > cherry_mapnik.py
> >
> > Description:
> > Proof of concept WMS server using cherrypy as the web framework and
> > mapnik as the map rendering engine
> >
> > Author:
> > Matthew Perry
> >
> > Last Modified:
> > 04/02/06
> >
> > License:
> > Free to use and modify for any purpose. ABSOLUTELY NO WARRANTY OF ANY KIND.
> >
> > Caveat:
> > Does not even come close to complying with the WMS spec.
> > Only very limited GetMap requests supported
> >
> > Example:
> > start the server with "python cherry_mapnik.py"
> > point your browser to http://localhost:8080/wms?VERSION=1.1.1&REQUEST=GetMap&LAYERS=states&FORMAT=image/jpeg&SRS=EPSG:4326&STYLES=&BBOX=-120,15,-70,65&width=400&height=400
> > """
> >
> > import cherrypy, random
> > from mapnik import *
> > from cherrypy.lib import cptools
> >
> > def createMap(envelope,mapsize,imagetype,layers):
> >
> > #=========================#
> > # System-specific variables
> >
> > # The polygon shapefile (minus the .shp extension)
> > shpfile = '/home/perrygeo/data/states/statesp020'
> >
> > # The output image directory where mapnik will cache images
> > # It really helps to have a cron task to clean out this dir!
> > imagedir = '/home/perrygeo/www/tmp'
> >
> > #=========================#
> >
> > # Set up the Mapnik Map
> > m = Map(mapsize[0],mapsize[1])
> > m.background = Color('#525367')
> >
> > # Turn on 'states' layer if requested
> > if 'states' in layers:
> > states_lyr = Layer(name='states', type='shape', file=shpfile)
> > states_style = Style()
> > states_rule = Rule()
> > states_rule.symbols.append(PolygonSymbolizer(Color(248,216,136)))
> > states_rule.symbols.append(LineSymbolizer(Color(48,48,48),1))
> > states_style.rules.append( states_rule )
> > m.append_style('states', states_style)
> > states_lyr.styles.append('states')
> > m.layers.append(states_lyr)
> >
> > # Set the BBOX extent
> > m.zoom_to_box(envelope)
> >
> > # Get the proper image type and file extensions
> > if imagetype=='png': ext='png'
> > if imagetype=='jpeg' or imagetype=='jpg':
> > ext='jpg'
> > imagetype='jpeg'
> >
> > # Generate an image with random filename
> > rand = random.randint(0,90000000)
> > prefix = "mapnik_%s" % rand
> > path = imagedir + '/' + prefix + '.' + ext
> >
> > render_to_file(m, path, imagetype)
> > return path
> >
> > class WMS:
> > def getCapabilities(self):
> > xml = '<test>Capabilities not supported yet </test>'
> > return xml
> >
> > def wms(self, *args, **kwargs):
> > # WMS spec calls for case insensitive parameter names
> > lc = {}
> > for k,v in kwargs.iteritems():
> > lc[str(k).lower()] = v
> >
> > if lc['request']=='GetCapabilities' and lc['service']=='WMS':
> > cherrypy.response.headerMap['Content-Type']= 'text/xml'
> > return self.getCapabilities()
> > elif lc['request']=='GetMap':
> > corners = lc['bbox'].split(',')
> > envelope = Envelope(float(corners[0]),float(corners[1]), \
> > float(corners[2]),float(corners[3]))
> > imagetype = lc['format'].replace('image/','')
> > mapsize=(int( lc['width'] ),int( lc['height'] ))
> > layers = lc['layers'].split(',')
> >
> > path = createMap(envelope,mapsize,imagetype,layers)
> > return cptools.serveFile(path)
> > else:
> > cherrypy.response.headerMap['Content-Type']= 'text/xml'
> > return "<test>You gotta request something</test>"
> >
> > wms.exposed = True
> >
> > if __name__ == '__main__':
> > cherrypy.root = WMS()
> > cherrypy.config.update({
> > 'global': {
> > 'server.socket_port' : 8080,
> > 'server.thread_pool' : 10,
> > 'logDebugInfoFilter.on' : False }})
> > cherrypy.server.start()
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
> >
>
>
--
Matt Perry
perrygeo at gmail.com
http://www.perrygeo.net
More information about the Mapnik-devel
mailing list