From 7b3baee3a1299c6f47f5c20d2de571dbff02246d Mon Sep 17 00:00:00 2001 From: Rich Wareham Date: Thu, 19 Jul 2012 19:03:34 +0100 Subject: [PATCH] python bindings: export Query.resolution property as a tuple Although the mapnik::query class is exposed to the Python bindings, the resolution attribute is a raw boost::tuple. If you attempt to access this tuple from Python, boost complains strongly. This patch adds the required magic to marshal the raw boost::tuple which is query::resolution_type into an honest-to-goodness Python tuple. --- bindings/python/mapnik_query.cpp | 18 +++++++++++++++++ tests/python_tests/query_test.py | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 tests/python_tests/query_test.py diff --git a/bindings/python/mapnik_query.cpp b/bindings/python/mapnik_query.cpp index f2b5c368f..cd49ef967 100644 --- a/bindings/python/mapnik_query.cpp +++ b/bindings/python/mapnik_query.cpp @@ -30,6 +30,8 @@ using mapnik::query; using mapnik::box2d; +namespace python = boost::python; + struct query_pickle_suite : boost::python::pickle_suite { static boost::python::tuple @@ -39,10 +41,26 @@ struct query_pickle_suite : boost::python::pickle_suite } }; +struct resolution_to_tuple +{ + static PyObject* convert(query::resolution_type const& x) + { + python::object tuple(python::make_tuple(x.get<0>(), x.get<1>())); + return python::incref(tuple.ptr()); + } + + static PyTypeObject const* get_pytype() + { + return &PyTuple_Type; + } +}; + void export_query() { using namespace boost::python; + to_python_converter (); + class_("Query", "a spatial query data object", init,query::resolution_type const&,double>() ) .def(init >()) diff --git a/tests/python_tests/query_test.py b/tests/python_tests/query_test.py new file mode 100644 index 000000000..ec636da09 --- /dev/null +++ b/tests/python_tests/query_test.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os, mapnik + +from nose.tools import * +from utilities import execution_path + +def setup(): + # All of the paths used are relative, if we run the tests + # from another directory we need to chdir() + os.chdir(execution_path('.')) + +def test_query_init(): + bbox = (-180, -90, 180, 90) + query = mapnik.Query(mapnik.Box2d(*bbox)) + r = query.resolution + assert_almost_equal(r[0], 1.0, places=7) + assert_almost_equal(r[1], 1.0, places=7) + +# Converting *from* tuples *to* resolutions is not yet supported +@raises(TypeError) +def test_query_resolution(): + bbox = (-180, -90, 180, 90) + init_res = (4.5, 6.7) + query = mapnik.Query(mapnik.Box2d(*bbox), init_res) + r = query.resolution + assert_almost_equal(r[0], init_res[0], places=7) + assert_almost_equal(r[1], init_res[1], places=7) + +if __name__ == "__main__": + setup() + [eval(run)() for run in dir() if 'test_' in run]