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:

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;

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;
    return false;

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:


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?

  • 1
    I can't answer your question directly, but perhaps have a look in the backend of the Mapnik python bindings, see what conditions are being asked? Might help explain why it returns False. – James Milner May 8 '12 at 0:17
  • @Zero_Qualms, I took your advice and added some more information. I'm still not very sure what I'm looking at here, however. Thanks for your help. /E – elrobis May 8 '12 at 4:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.