From 92ca0a8ac92f256133b5bf0033d9709ed0e68c3c Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Sun, 24 May 2009 06:12:32 +0000 Subject: [PATCH] +expose parameters as python list and dict, and add pickle support by taking advantage of boost visitation - needs further review - see #345 --- bindings/python/mapnik_parameters.cpp | 121 +++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 10 deletions(-) diff --git a/bindings/python/mapnik_parameters.cpp b/bindings/python/mapnik_parameters.cpp index da5534290..def97833d 100644 --- a/bindings/python/mapnik_parameters.cpp +++ b/bindings/python/mapnik_parameters.cpp @@ -21,20 +21,48 @@ *****************************************************************************/ //$Id: mapnik_parameters.cpp 17 2005-03-08 23:58:43Z pavlenko $ +// boost #include -#include + +// mapnik #include using mapnik::parameter; using mapnik::parameters; +struct pickle_value : public boost::static_visitor<> +{ + public: + pickle_value( boost::python::list vals): + vals_(vals) {} + + void operator () ( int val ) + { + vals_.append(val); + } + + void operator () ( double val ) + { + vals_.append(val); + } + + void operator () ( std::string val ) + { + vals_.append(val); + } + + private: + boost::python::list vals_; + +}; + struct parameter_pickle_suite : boost::python::pickle_suite { static boost::python::tuple getinitargs(const parameter& p) { using namespace boost::python; - return boost::python::make_tuple(p.first,p.second); + return boost::python::make_tuple(p.first,boost::get(p.second)); } }; @@ -48,7 +76,11 @@ struct parameters_pickle_suite : boost::python::pickle_suite parameters::const_iterator pos=p.begin(); while(pos!=p.end()) { - d[pos->first]=pos->second; + boost::python::list vals; + pickle_value serializer( vals ); + mapnik::value_holder val = pos->second; + boost::apply_visitor( serializer, val ); + d[pos->first] = vals[0]; ++pos; } return boost::python::make_tuple(d); @@ -65,26 +97,95 @@ struct parameters_pickle_suite : boost::python::pickle_suite ); throw_error_already_set(); } + dict d = extract(state[0]); - boost::python::list keys=d.keys(); - for (int i=0;i(keys[i]); - std::string value=extract(d[key]); // FIXME: use boost::variant as a value object. Add Py_Int/Py_Float/Py_String extractors. - p[key] = value; - } + std::string key = extract(keys[i]); + object obj = d[key]; + extract ex0(obj); + extract ex1(obj); + extract ex2(obj); + + if (ex0.check()) + { + p[key] = ex0(); + } + else if (ex1.check()) + { + p[key] = ex1(); + } + else if (ex2.check()) + { + p[key] = ex2(); + } + + /* + extract_value serializer( p, key ); + mapnik::value_holder val = extract(d[key]); + boost::apply_visitor( serializer, val ); + */ + } } }; +boost::python::dict dict_params(parameters& p) +{ + boost::python::dict d; + parameters::const_iterator pos=p.begin(); + while(pos!=p.end()) + { + boost::python::list vals; + pickle_value serializer( vals ); + mapnik::value_holder val = pos->second; + boost::apply_visitor( serializer, val ); + d[pos->first] = vals[0]; + ++pos; + } + return d; +} + +boost::python::list list_params(parameters& p) +{ + boost::python::list l; + parameters::const_iterator pos=p.begin(); + while(pos!=p.end()) + { + boost::python::list vals; + pickle_value serializer( vals ); + mapnik::value_holder val = pos->second; + boost::apply_visitor( serializer, val ); + l.append(boost::python::make_tuple(pos->first,vals[0])); + ++pos; + } + return l; +} + +boost::python::dict dict_param(parameter& p) +{ + boost::python::dict d; + d[p.first] = boost::get(p.second); + return d; +} + +boost::python::tuple tuple_param(parameter& p) +{ + return boost::python::make_tuple(p.first,boost::get(p.second)); +} void export_parameters() { using namespace boost::python; class_("Parameter",init()) .def_pickle(parameter_pickle_suite()) + .def("as_dict",dict_param) + .def("as_tuple",tuple_param) ; class_("Parameters",init<>()) .def_pickle(parameters_pickle_suite()) + .def("as_dict",dict_params) + .def("as_list",list_params) ; -} +} \ No newline at end of file