/***************************************************************************** * * This file is part of Mapnik (c++ mapping toolkit) * * Copyright (C) 2006 Artem Pavlenko, Jean-Francois Doyon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "boost_std_shared_shim.hpp" // boost #include // mapnik #include #include using mapnik::coord; using mapnik::box2d; struct envelope_pickle_suite : boost::python::pickle_suite { static boost::python::tuple getinitargs(const box2d& e) { using namespace boost::python; return boost::python::make_tuple(e.minx(),e.miny(),e.maxx(),e.maxy()); } }; box2d from_string(std::string const& s) { box2d bbox; bool success = bbox.from_string(s); if (success) { return bbox; } else { std::stringstream ss; ss << "Could not parse bbox from string: '" << s << "'"; throw mapnik::value_error(ss.str()); } } //define overloads here void (box2d::*width_p1)(double) = &box2d::width; double (box2d::*width_p2)() const = &box2d::width; void (box2d::*height_p1)(double) = &box2d::height; double (box2d::*height_p2)() const = &box2d::height; void (box2d::*expand_to_include_p1)(double,double) = &box2d::expand_to_include; void (box2d::*expand_to_include_p2)(coord const& ) = &box2d::expand_to_include; void (box2d::*expand_to_include_p3)(box2d const& ) = &box2d::expand_to_include; bool (box2d::*contains_p1)(double,double) const = &box2d::contains; bool (box2d::*contains_p2)(coord const&) const = &box2d::contains; bool (box2d::*contains_p3)(box2d const&) const = &box2d::contains; //intersects bool (box2d::*intersects_p1)(double,double) const = &box2d::intersects; bool (box2d::*intersects_p2)(coord const&) const = &box2d::intersects; bool (box2d::*intersects_p3)(box2d const&) const = &box2d::intersects; // intersect box2d (box2d::*intersect)(box2d const&) const = &box2d::intersect; // re_center void (box2d::*re_center_p1)(double,double) = &box2d::re_center; void (box2d::*re_center_p2)(coord const& ) = &box2d::re_center; // clip void (box2d::*clip)(box2d const&) = &box2d::clip; // pad void (box2d::*pad)(double) = &box2d::pad; // deepcopy box2d box2d_deepcopy(box2d & obj, boost::python::dict memo) { // FIXME::ignore memo for now box2d result(obj); return result; } void export_envelope() { using namespace boost::python; class_ >("Box2d", // class docstring is in mapnik/__init__.py, class _Coord init( (arg("minx"),arg("miny"),arg("maxx"),arg("maxy")), "Constructs a new envelope from the coordinates\n" "of its lower left and upper right corner points.\n")) .def(init<>("Equivalent to Box2d(0, 0, -1, -1).\n")) .def(init&, const coord&>( (arg("ll"),arg("ur")), "Equivalent to Box2d(ll.x, ll.y, ur.x, ur.y).\n")) .def("from_string",from_string) .staticmethod("from_string") .add_property("minx", &box2d::minx, "X coordinate for the lower left corner") .add_property("miny", &box2d::miny, "Y coordinate for the lower left corner") .add_property("maxx", &box2d::maxx, "X coordinate for the upper right corner") .add_property("maxy", &box2d::maxy, "Y coordinate for the upper right corner") .def("center", &box2d::center, "Returns the coordinates of the center of the bounding box.\n" "\n" "Example:\n" ">>> e = Box2d(0, 0, 100, 100)\n" ">>> e.center()\n" "Coord(50, 50)\n") .def("center", re_center_p1, (arg("x"), arg("y")), "Moves the envelope so that the given coordinates become its new center.\n" "The width and the height are preserved.\n" "\n " "Example:\n" ">>> e = Box2d(0, 0, 100, 100)\n" ">>> e.center(60, 60)\n" ">>> e.center()\n" "Coord(60.0,60.0)\n" ">>> (e.width(), e.height())\n" "(100.0, 100.0)\n" ">>> e\n" "Box2d(10.0, 10.0, 110.0, 110.0)\n" ) .def("center", re_center_p2, (arg("Coord")), "Moves the envelope so that the given coordinates become its new center.\n" "The width and the height are preserved.\n" "\n " "Example:\n" ">>> e = Box2d(0, 0, 100, 100)\n" ">>> e.center(Coord60, 60)\n" ">>> e.center()\n" "Coord(60.0,60.0)\n" ">>> (e.width(), e.height())\n" "(100.0, 100.0)\n" ">>> e\n" "Box2d(10.0, 10.0, 110.0, 110.0)\n" ) .def("clip", clip, (arg("other")), "Clip the envelope based on the bounds of another envelope.\n" "\n " "Example:\n" ">>> e = Box2d(0, 0, 100, 100)\n" ">>> c = Box2d(-50, -50, 50, 50)\n" ">>> e.clip(c)\n" ">>> e\n" "Box2d(0.0,0.0,50.0,50.0\n" ) .def("pad", pad, (arg("padding")), "Pad the envelope based on a padding value.\n" "\n " "Example:\n" ">>> e = Box2d(0, 0, 100, 100)\n" ">>> e.pad(10)\n" ">>> e\n" "Box2d(-10.0,-10.0,110.0,110.0\n" ) .def("width", width_p1, (arg("new_width")), "Sets the width to new_width of the envelope preserving its center.\n" "\n " "Example:\n" ">>> e = Box2d(0, 0, 100, 100)\n" ">>> e.width(120)\n" ">>> e.center()\n" "Coord(50.0,50.0)\n" ">>> e\n" "Box2d(-10.0, 0.0, 110.0, 100.0)\n" ) .def("width", width_p2, "Returns the width of this envelope.\n" ) .def("height", height_p1, (arg("new_height")), "Sets the height to new_height of the envelope preserving its center.\n" "\n " "Example:\n" ">>> e = Box2d(0, 0, 100, 100)\n" ">>> e.height(120)\n" ">>> e.center()\n" "Coord(50.0,50.0)\n" ">>> e\n" "Box2d(0.0, -10.0, 100.0, 110.0)\n" ) .def("height", height_p2, "Returns the height of this envelope.\n" ) .def("expand_to_include",expand_to_include_p1, (arg("x"),arg("y")), "Expands this envelope to include the point given by x and y.\n" "\n" "Example:\n", ">>> e = Box2d(0, 0, 100, 100)\n" ">>> e.expand_to_include(110, 110)\n" ">>> e\n" "Box2d(0.0, 00.0, 110.0, 110.0)\n" ) .def("expand_to_include",expand_to_include_p2, (arg("p")), "Equivalent to expand_to_include(p.x, p.y)\n" ) .def("expand_to_include",expand_to_include_p3, (arg("other")), "Equivalent to:\n" " expand_to_include(other.minx, other.miny)\n" " expand_to_include(other.maxx, other.maxy)\n" ) .def("contains",contains_p1, (arg("x"),arg("y")), "Returns True iff this envelope contains the point\n" "given by x and y.\n" ) .def("contains",contains_p2, (arg("p")), "Equivalent to contains(p.x, p.y)\n" ) .def("contains",contains_p3, (arg("other")), "Equivalent to:\n" " contains(other.minx, other.miny) and contains(other.maxx, other.maxy)\n" ) .def("intersects",intersects_p1, (arg("x"),arg("y")), "Returns True iff this envelope intersects the point\n" "given by x and y.\n" "\n" "Note: For points, intersection is equivalent\n" "to containment, i.e. the following holds:\n" " e.contains(x, y) == e.intersects(x, y)\n" ) .def("intersects",intersects_p2, (arg("p")), "Equivalent to contains(p.x, p.y)\n") .def("intersects",intersects_p3, (arg("other")), "Returns True iff this envelope intersects the other envelope,\n" "This relationship is symmetric." "\n" "Example:\n" ">>> e1 = Box2d(0, 0, 100, 100)\n" ">>> e2 = Box2d(50, 50, 150, 150)\n" ">>> e1.intersects(e2)\n" "True\n" ">>> e1.contains(e2)\n" "False\n" ) .def("intersect",intersect, (arg("other")), "Returns the overlap of this envelope and the other envelope\n" "as a new envelope.\n" "\n" "Example:\n" ">>> e1 = Box2d(0, 0, 100, 100)\n" ">>> e2 = Box2d(50, 50, 150, 150)\n" ">>> e1.intersect(e2)\n" "Box2d(50.0, 50.0, 100.0, 100.0)\n" ) .def(self == self) // __eq__ .def(self != self) // __neq__ .def(self + self) // __add__ .def(self * float()) // __mult__ .def(float() * self) .def(self / float()) // __div__ .def("__getitem__",&box2d::operator[]) .def("valid",&box2d::valid) .def_pickle(envelope_pickle_suite()) .def("__deepcopy__", &box2d_deepcopy) ; }