diff --git a/src/geometry.cpp b/src/geometry.cpp index fe2ae674..9749847b 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -18,98 +18,10 @@ template class FactoryManager; template class FactoryManager; PYBIND11_MODULE(_geometry, m) { - py::class_>(m, "BaseGeometry") - .def("set_field", &BaseGeometry::setField) - .def("get_field", &BaseGeometry::getField) - .def_property_readonly("fields", &BaseGeometry::getFields) - .def_property_readonly("pointer_id", &BaseGeometry::getPointerId); - - py::class_>(m, "Polygon") - .def(py::init<>()) - .def(py::init()) - .def(py::init> &, - const std::vector>> &>()) - .def(py::init([](const std::shared_ptr &p) { - // Share the same C++ object, not creating a new one - return p; - })) - .def(py::init([](const Polygon &other) { - // Explicitly copy parameters when copying the polygon - auto newPolygon = std::make_shared(*other.polygon_); - newPolygon->parameters_ = other.parameters_; // Copy the parameters - return newPolygon; - })) - .def("set_exterior", &Polygon::setExterior) - .def("set_interiors", &Polygon::setInteriors) - .def("get_exterior", &Polygon::getExterior) - .def("get_exterior_iterator", - [](Polygon &self) { - return py::make_iterator(self.getExteriorAsIterator().begin(), self.getExteriorAsIterator().end()); - }) - .def("get_interiors_iterator", - [](Polygon &self) { - return py::make_iterator(self.getInteriorAsIterator().begin(), self.getInteriorAsIterator().end()); - }) - .def("scale", &Polygon::scale, py::arg("scaling")) - .def("get_interiors", &Polygon::getInteriors) - .def("correct_orientation", &Polygon::correctIfNeeded) - .def("simplify", &Polygon::simplifyPolygon) - .def("contains", &Polygon::contains, py::arg("other"), - "Check if the polygon fully contains another polygon. Does not check if the fields are equal") - .def("make_valid", &Polygon::makeValid, - "Make the polygon valid by removing self-intersections and duplicate points") - .def("equals", &Polygon::equals, py::arg("other"), - "Check if the polygon is equal to another polygon. Checks if the fields are equal.") - .def_property_readonly("wkt", &Polygon::toWkt) - .def_property_readonly("is_valid", &Polygon::isValid) - .def_property_readonly("area", &Polygon::getArea); - - py::class_>(m, "Box") - .def(py::init<>()) - .def(py::init()) - .def(py::init &, const std::array &>()) - .def(py::init([](const std::shared_ptr &p) { - // Share the same C++ object, not creating a new one - return p; - })) - .def(py::init([](const Box &other) { - // Explicitly copy parameters when copying the Box - auto newBox = std::make_shared(*other.box_); - newBox->parameters_ = other.parameters_; // Copy the parameters - return newBox; - })) - .def("as_polygon", &Box::asPolygonPyObject, "Convert the box to a polygon") - .def("scale", &Box::scale, py::arg("scaling"), "Scale the box in-place by a factor") - - .def_property_readonly("coordinates", &Box::getCoordinates, - "Get the top-left coordinates of the box as an (x, y) tuple") - .def_property_readonly("size", &Box::getSize, "Get the size of the box as an (h, w) tuple") - .def_property_readonly("area", &Box::getArea) - .def_property_readonly("wkt", &Box::toWkt, "Get the WKT representation of the box"); - - py::class_>(m, "Point") - .def(py::init<>()) - .def(py::init()) - .def(py::init()) - .def(py::init([](const std::shared_ptr &p) { - // Share the same C++ object, not creating a new one - return p; - })) - .def(py::init([](const Point &other) { - // Explicitly copy parameters when copying the polygon - auto newPoint = std::make_shared(*other.point_); - newPoint->parameters_ = other.parameters_; // Copy the parameters - return newPoint; - })) - .def_property_readonly("coordinates", &Point::getCoordinates, - "Get the coordinates of the point as an (x, y) tuple") - .def_property_readonly("x", &Point::getX, "Get the X coordinate") - .def_property_readonly("y", &Point::getY, "Get the Y coordinate") - .def("distance_to", &Point::distanceTo, py::arg("other"), "Calculate the distance to another point") - .def("equals", &Point::equals, py::arg("other"), "Check if the point is equal to another point") - .def("within", &Point::within, py::arg("polygon"), "Check if the point is within a polygon") - .def("scale", &Point::scale, py::arg("scaling"), "Scale the point in-place point by a factor") - .def_property_readonly("wkt", &Point::toWkt, "Get the WKT representation of the point"); + declare_base_geometry(m); + declare_polygon(m); + declare_box(m); + declare_point(m); m.def("set_polygon_factory", &FactoryManager::setFactory, "Set the factory function for Polygons"); m.def("set_box_factory", &FactoryManager::setFactory, "Set the factory function for Boxes"); diff --git a/src/geometry/base.h b/src/geometry/base.h index bf8666f7..79b85e47 100644 --- a/src/geometry/base.h +++ b/src/geometry/base.h @@ -54,4 +54,12 @@ class BaseGeometry { protected: }; +inline void declare_base_geometry(py::module &m) { + py::class_>(m, "BaseGeometry") + .def("set_field", &BaseGeometry::setField) + .def("get_field", &BaseGeometry::getField) + .def_property_readonly("fields", &BaseGeometry::getFields) + .def_property_readonly("pointer_id", &BaseGeometry::getPointerId); +} + #endif // DLUP_GEOMETRY_BASE_H diff --git a/src/geometry/box.h b/src/geometry/box.h index d2b41c97..889afa9d 100644 --- a/src/geometry/box.h +++ b/src/geometry/box.h @@ -77,4 +77,29 @@ class Box : public BaseGeometry { std::string toWkt() const override { return convertToWkt(*box_); } }; -#endif // DLUP_GEOMETRY_BOX_H +inline void declare_box(py::module &m) { + py::class_>(m, "Box") + .def(py::init<>()) + .def(py::init()) + .def(py::init &, const std::array &>()) + .def(py::init([](const std::shared_ptr &p) { + // Share the same C++ object, not creating a new one + return p; + })) + .def(py::init([](const Box &other) { + // Explicitly copy parameters when copying the Box + auto newBox = std::make_shared(*other.box_); + newBox->parameters_ = other.parameters_; // Copy the parameters + return newBox; + })) + .def("as_polygon", &Box::asPolygonPyObject, "Convert the box to a polygon") + .def("scale", &Box::scale, py::arg("scaling"), "Scale the box in-place by a factor") + + .def_property_readonly("coordinates", &Box::getCoordinates, + "Get the top-left coordinates of the box as an (x, y) tuple") + .def_property_readonly("size", &Box::getSize, "Get the size of the box as an (h, w) tuple") + .def_property_readonly("area", &Box::getArea) + .def_property_readonly("wkt", &Box::toWkt, "Get the WKT representation of the box"); +} + +#endif // DLUP_GEOMETRY_BOX_H \ No newline at end of file diff --git a/src/geometry/point.h b/src/geometry/point.h index 8affed43..f1f32475 100644 --- a/src/geometry/point.h +++ b/src/geometry/point.h @@ -45,4 +45,30 @@ class Point : public BaseGeometry { } }; -#endif // DLUP_GEOMETRY_POINT_H +inline void declare_point(py::module &m) { + py::class_>(m, "Point") + .def(py::init<>()) + .def(py::init()) + .def(py::init()) + .def(py::init([](const std::shared_ptr &p) { + // Share the same C++ object, not creating a new one + return p; + })) + .def(py::init([](const Point &other) { + // Explicitly copy parameters when copying the polygon + auto newPoint = std::make_shared(*other.point_); + newPoint->parameters_ = other.parameters_; // Copy the parameters + return newPoint; + })) + .def_property_readonly("coordinates", &Point::getCoordinates, + "Get the coordinates of the point as an (x, y) tuple") + .def_property_readonly("x", &Point::getX, "Get the X coordinate") + .def_property_readonly("y", &Point::getY, "Get the Y coordinate") + .def("distance_to", &Point::distanceTo, py::arg("other"), "Calculate the distance to another point") + .def("equals", &Point::equals, py::arg("other"), "Check if the point is equal to another point") + .def("within", &Point::within, py::arg("polygon"), "Check if the point is within a polygon") + .def("scale", &Point::scale, py::arg("scaling"), "Scale the point in-place point by a factor") + .def_property_readonly("wkt", &Point::toWkt, "Get the WKT representation of the point"); +} + +#endif // DLUP_GEOMETRY_POINT_H \ No newline at end of file diff --git a/src/geometry/polygon.h b/src/geometry/polygon.h index 2a4b6ad8..ffd43e91 100644 --- a/src/geometry/polygon.h +++ b/src/geometry/polygon.h @@ -171,4 +171,46 @@ void Polygon::setExterior(const std::vector> &coordina is_corrected_ = false; // Mark as not corrected. Correction reorients and closes } +inline void declare_polygon(py::module &m) { + py::class_>(m, "Polygon") + .def(py::init<>()) + .def(py::init()) + .def(py::init> &, + const std::vector>> &>()) + .def(py::init([](const std::shared_ptr &p) { + // Share the same C++ object, not creating a new one + return p; + })) + .def(py::init([](const Polygon &other) { + // Explicitly copy parameters when copying the polygon + auto newPolygon = std::make_shared(*other.polygon_); + newPolygon->parameters_ = other.parameters_; // Copy the parameters + return newPolygon; + })) + .def("set_exterior", &Polygon::setExterior) + .def("set_interiors", &Polygon::setInteriors) + .def("get_exterior", &Polygon::getExterior) + .def("get_exterior_iterator", + [](Polygon &self) { + return py::make_iterator(self.getExteriorAsIterator().begin(), self.getExteriorAsIterator().end()); + }) + .def("get_interiors_iterator", + [](Polygon &self) { + return py::make_iterator(self.getInteriorAsIterator().begin(), self.getInteriorAsIterator().end()); + }) + .def("scale", &Polygon::scale, py::arg("scaling")) + .def("get_interiors", &Polygon::getInteriors) + .def("correct_orientation", &Polygon::correctIfNeeded) + .def("simplify", &Polygon::simplifyPolygon) + .def("contains", &Polygon::contains, py::arg("other"), + "Check if the polygon fully contains another polygon. Does not check if the fields are equal") + .def("make_valid", &Polygon::makeValid, + "Make the polygon valid by removing self-intersections and duplicate points") + .def("equals", &Polygon::equals, py::arg("other"), + "Check if the polygon is equal to another polygon. Checks if the fields are equal.") + .def_property_readonly("wkt", &Polygon::toWkt) + .def_property_readonly("is_valid", &Polygon::isValid) + .def_property_readonly("area", &Polygon::getArea); +} + #endif // DLUP_GEOMETRY_POLYGON_H