I'm trying to modify rundemo.py (comes canned with Mapnik Windows binaries) to render output files at a higher resolution, but it seems I still have issues with my Mapnik-to-Cairo setup.
I've got mapnik and its python bindings working, and I've also got cairo and these python bindings working (..I think). If I start Python, I can do the following without issue:
E:\x_FOSS\mapnik\v2.0.0\mapnik-2.0.1rc0\demo\python>python.exe
Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import mapnik
>>> import cairo
>>>
Meanwhile, back in rundemo.py line 351, it fails on this condition:
if HAS_PYCAIRO_MODULE and mapnik.has_pycairo():
And this..
print mapnik.has_pycairo() # returns False.
But this conflicts with what I'm reading in the Mapnik blog which says these Windows binaries are built with Cairo backend support.
Does anyone know what conditions have to be in place for mapnik.has_pycairo() to return True?
[Update, are these build, or runtime instructions?]
Per Zero_Qualms' advice, I downloaded the mapnik source and found reference to HAVE_PYCAIRO in %\mapnik-v2.0.1\bindings\python\mapnik_python.cpp. I'm not familiar with C++, so I'm not sure if these are build instructions or runtime instructions. First, line 86 has this block following several #include statements:
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
#include <pycairo.h>
static Pycairo_CAPI_t *Pycairo_CAPI;
#endif
Then there are a couple insignificant calls to defined(HAVE_PYCAIRO), followed by this has_pycairo() property at line 347:
// indicator for pycairo support in the python bindings
bool has_pycairo()
{
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
Pycairo_CAPI = (Pycairo_CAPI_t*) PyCObject_Import(const_cast<char *>("cairo"), const_cast<char *>("CAPI"));
if (Pycairo_CAPI == NULL){
/*
Case where pycairo support has been compiled into
mapnik but at runtime the cairo python module
is unable to be imported and therefore Pycairo surfaces
and contexts cannot be passed to mapnik.render()
*/
return false;
}
return true;
#else
return false;
#endif
}
That block comment seems to imply my mapnik-pycairo linkage just isn't correct, and that it can be fixed. Next I searched for PyCObject_Import and found the following block in this file:
%\mapnik-v2.0.1\bindings\python\python_cairo.cpp:
void register_cairo()
{
Pycairo_CAPI = (Pycairo_CAPI_t*) PyCObject_Import(const_cast<char *>("cairo"), const_cast<char *>("CAPI"));
if (Pycairo_CAPI == NULL) return;
boost::python::converter::registry::insert(&extract_surface, boost::python::type_id<PycairoSurface>());
boost::python::converter::registry::insert(&extract_context, boost::python::type_id<PycairoContext>());
}
Blast! It seems reasonable that I could create the registry entries manually, but ..what entries?