Changeset 1162

Show
Ignore:
Timestamp:
05/24/09 02:12:32 (14 months ago)
Author:
dane
Message:

+expose parameters as python list and dict, and add pickle support by taking advantage of boost visitation - needs further review - see #345

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/bindings/python/mapnik_parameters.cpp

    r485 r1162  
    2222//$Id: mapnik_parameters.cpp 17 2005-03-08 23:58:43Z pavlenko $ 
    2323 
     24// boost 
    2425#include <boost/python.hpp> 
    25 #include <boost/python/detail/api_placeholder.hpp> 
     26 
     27// mapnik 
    2628#include <mapnik/params.hpp> 
    2729 
    2830using mapnik::parameter; 
    2931using mapnik::parameters; 
     32 
     33struct pickle_value : public boost::static_visitor<> 
     34{ 
     35    public: 
     36        pickle_value( boost::python::list vals):  
     37        vals_(vals) {} 
     38             
     39        void operator () ( int val ) 
     40        { 
     41            vals_.append(val); 
     42        } 
     43         
     44        void operator () ( double val ) 
     45        { 
     46            vals_.append(val); 
     47        } 
     48 
     49        void operator () ( std::string val ) 
     50        { 
     51            vals_.append(val); 
     52        } 
     53         
     54    private: 
     55        boost::python::list vals_; 
     56 
     57}; 
    3058 
    3159struct parameter_pickle_suite : boost::python::pickle_suite 
     
    3563    { 
    3664        using namespace boost::python; 
    37         return boost::python::make_tuple(p.first,p.second); 
     65        return boost::python::make_tuple(p.first,boost::get<std::string>(p.second)); 
    3866    } 
    3967}; 
     
    4977        while(pos!=p.end()) 
    5078        { 
    51             d[pos->first]=pos->second; 
     79            boost::python::list vals; 
     80            pickle_value serializer( vals ); 
     81            mapnik::value_holder val = pos->second; 
     82            boost::apply_visitor( serializer, val ); 
     83            d[pos->first] = vals[0]; 
    5284            ++pos; 
    5385        } 
     
    6698            throw_error_already_set(); 
    6799        } 
     100         
    68101        dict d = extract<dict>(state[0]); 
    69         boost::python::list keys=d.keys(); 
    70         for (int i=0;i<len(keys);++i) 
     102        boost::python::list keys = d.keys(); 
     103        for (int i=0; i<len(keys); ++i) 
    71104        { 
    72             std::string key=extract<std::string>(keys[i]); 
    73             std::string value=extract<std::string>(d[key]); // FIXME: use boost::variant as a value object. Add Py_Int/Py_Float/Py_String extractors.  
    74             p[key] = value; 
    75         } 
     105            std::string key = extract<std::string>(keys[i]); 
     106            object obj = d[key]; 
     107            extract<std::string> ex0(obj); 
     108            extract<int> ex1(obj); 
     109            extract<double> ex2(obj); 
     110             
     111            if (ex0.check()) 
     112            { 
     113               p[key] = ex0(); 
     114            } 
     115            else if (ex1.check()) 
     116            { 
     117               p[key] = ex1(); 
     118            } 
     119            else if (ex2.check()) 
     120            { 
     121               p[key] = ex2(); 
     122            }            
     123             
     124            /* 
     125            extract_value serializer( p, key ); 
     126            mapnik::value_holder val = extract<mapnik::value_holder>(d[key]); 
     127            boost::apply_visitor( serializer, val ); 
     128            */ 
     129        }         
    76130    } 
    77131}; 
    78132 
     133boost::python::dict dict_params(parameters& p) 
     134{ 
     135    boost::python::dict d; 
     136    parameters::const_iterator pos=p.begin(); 
     137    while(pos!=p.end()) 
     138    { 
     139        boost::python::list vals; 
     140        pickle_value serializer( vals ); 
     141        mapnik::value_holder val = pos->second; 
     142        boost::apply_visitor( serializer, val ); 
     143        d[pos->first] = vals[0]; 
     144        ++pos; 
     145    } 
     146    return d; 
     147} 
     148 
     149boost::python::list list_params(parameters& p) 
     150{ 
     151    boost::python::list l; 
     152    parameters::const_iterator pos=p.begin(); 
     153    while(pos!=p.end()) 
     154    { 
     155        boost::python::list vals; 
     156        pickle_value serializer( vals ); 
     157        mapnik::value_holder val = pos->second; 
     158        boost::apply_visitor( serializer, val ); 
     159        l.append(boost::python::make_tuple(pos->first,vals[0])); 
     160        ++pos; 
     161    } 
     162    return l; 
     163} 
     164 
     165boost::python::dict dict_param(parameter& p) 
     166{ 
     167    boost::python::dict d; 
     168    d[p.first] = boost::get<std::string>(p.second); 
     169    return d; 
     170} 
     171 
     172boost::python::tuple tuple_param(parameter& p) 
     173{ 
     174    return boost::python::make_tuple(p.first,boost::get<std::string>(p.second)); 
     175} 
    79176 
    80177void export_parameters() 
     
    83180    class_<parameter>("Parameter",init<std::string,std::string>()) 
    84181        .def_pickle(parameter_pickle_suite()) 
     182        .def("as_dict",dict_param) 
     183        .def("as_tuple",tuple_param) 
    85184        ; 
    86185 
    87186    class_<parameters>("Parameters",init<>()) 
    88187        .def_pickle(parameters_pickle_suite()) 
     188        .def("as_dict",dict_params) 
     189        .def("as_list",list_params) 
    89190        ; 
    90191}