Would it be any easier for PCL to approach mapnik? I think there's only one technical hurdle. Within PCL's rendering framework we've eschewed duck typing, and embraced zope.interface:
if ISLDRasterSymbolizer.implementedBy(symbclass):
lo.draw(mo, im)
...
Because of our freedom to morph Python classes, the solution seems pretty simple:
from zope.interface import classImplements
from mapnik import RasterSymbolizer
classImplements(RasterSymbolizer, ISLDRasterSymbolizer)
The principle is sound, but until I update mapnik I won't be able to try this. Anybody with mapnik installed willing to give it a shot? Here's a simpler test:
>>> from zope.interface import Interface, classImplements, implementedBy
>>> class IFoo(Interface): pass
>>> from mapnik import PointSymbolizer
>>> classImplements(PointSymbolizer, IFoo)
>>> [i.getName() for i in implementedBy(PointSymbolizer)]
['IFoo']
Looking good? Maybe all we have to do is hammer out little differences in the APIs. Here's an example of PCL styling and rendering code, output from which is shown at the top of the post. The point is not to compare MapServer's graphical powers to those of mapnik. It really isn't fair to compare GD to Agg. Instead, I want to point out how we have almost identical classes with rather different constructors:
# Irish electoral districts (OSI)
store = DiskFeatureStore('./data/hai.ovf')
layer = Layer(store, 'ErhaDeds2')
style = Style('default')
p = PolygonSymbolizer(fill=Fill('#FFFFFF', opacity=0.25),
stroke=Stroke('#333333', opacity=0.25))
t = TextSymbolizer('DEDName', Font('Vera', size=7), halo=Halo(radius=1),
minfeaturesize=20)
r = Rule('Deds', [p, t])
style.rules.append(r)
deds = ContextLayer('Deds', layer, style)
# Integrated CEOS European Data Server (ICEDS)
store = WMSRasterStore('http://128.40.25.70/cgi-bin/wms?map=wms.map',
version='1.1.1')
layer = Layer(store, 'srtm')
layer.ows_srs = 'EPSG:4326'
layer.ows_format = 'image/png'
style = Style()
style.rules.append(Rule('topography', [RasterSymbolizer()]))
topo = ContextLayer('Topo', layer, style)
# Map context
ExampleContext = MapContext([topo, deds])
to render:
FONTSET = 'fonts.txt'
mapper = MapRenderer('MAPSERVER', fontset=FONTSET, incoming='/tmp/')
srs = SpatialReference(epsg=29900)
view = View(srs, [230000, 155000, 350000, 275000])
size = [600, 600]
image = mapper.render(ExampleContext, view, 'image/jpg', size=size,
bgcolor='#4080CC')
I'm optimistic that PCL and mapnik can come to an agreement on a styling API before their respective 1.0 releases.
I have no idea how relevant it is in the Python world, and if you can get the same implementation that's the way to go. But one compromise we go for with GeoTools is to encourage others to do the same interface, which allows people to do their own thing in implementation, yet makes it so you can share somem code.