Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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?

share|improve this question
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. –  Loxodrome 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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.