I hope it should be a good design philosophy to think about a global refactoring of such pieces.
The idea is to move the real rendering (agg/cairo) and metawriters code in output plugins, allowing one to create more of them (adding more graphics backends for example) without actually mess with the mapnik internals too much, or tight the writing code with internal storage and definition of drawing/output styles.
Even when not using real shared libraries for this, again would be better to organize those piece of code that work with outputting data in their own folders, just to keep the codebase lighter.
For example, i would need to implement a sort of "transformators", which takes data from a datasource, but instead of rendering an image, or outputting a json, it should manipulate the geometries / attributes in various ways. Probably possible with python, but would be cool if people would shed some light here.
I would love to see plugin based arch for rendering, 'output' vector formats, and for image i/o - maybe more.
This way, if each plugin was built as shared lib, libmapnik would not have to link to cairo libs, or image libs. But, I think the build system should support static linking as well, depending on your needs (I have a patch somewhere to allow existing input plugins to be statically linked).
This should be doable, just requires good design ideas and refactoring, but I'm very supportive.
Also, +1 to idea of feature transformers. We should allow for simplification on the fly and then output as vectors (json, protocol buffers, etc). And ideally, if you wanted to build mapnik with only this support you could do it without linking in image libraries.