Skip to content

Commit

Permalink
Exposed options from Predicate Functor and added a specialization for…
Browse files Browse the repository at this point in the history
… touches
  • Loading branch information
JoelJaeschke committed Nov 1, 2024
1 parent eadc2bd commit 4c1276e
Showing 1 changed file with 50 additions and 32 deletions.
82 changes: 50 additions & 32 deletions src/predicates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ class Predicate {
template <class F>
Predicate(F&& func) : m_func(std::forward<F>(func)) {}

template <class F>
Predicate(F&& func, const S2BooleanOperation::Options& options)
: m_func(std::forward<F>(func)), m_options(options) {}

bool operator()(PyObjectGeography a, PyObjectGeography b) const {
const auto& a_index = a.as_geog_ptr()->geog_index();
const auto& b_index = b.as_geog_ptr()->geog_index();
Expand All @@ -33,6 +37,33 @@ class Predicate {
S2BooleanOperation::Options m_options;
};

/*
** A specialization of the `Predicate` class for the touches operation,
** as two `S2BooleanOpteration::Options` objects are necessary.
*/
class TouchesPredicate {
public:
TouchesPredicate() : m_closed_options(), m_open_options() {
m_closed_options.set_polyline_model(S2BooleanOperation::PolylineModel::CLOSED);
m_closed_options.set_polygon_model(S2BooleanOperation::PolygonModel::CLOSED);

m_open_options.set_polyline_model(S2BooleanOperation::PolylineModel::OPEN);
m_open_options.set_polygon_model(S2BooleanOperation::PolygonModel::OPEN);
}

bool operator()(PyObjectGeography a, PyObjectGeography b) const {
const auto& a_index = a.as_geog_ptr()->geog_index();
const auto& b_index = b.as_geog_ptr()->geog_index();

return s2geog::s2_intersects(a_index, b_index, m_closed_options) &&
!s2geog::s2_intersects(a_index, b_index, m_open_options);
}

private:
S2BooleanOperation::Options m_closed_options;
S2BooleanOperation::Options m_open_options;
};

void init_predicates(py::module& m) {
m.def("intersects",
py::vectorize(Predicate(s2geog::s2_intersects)),
Expand Down Expand Up @@ -119,20 +150,7 @@ void init_predicates(py::module& m) {
)pbdoc");

m.def("touches",
py::vectorize(Predicate([](const s2geog::ShapeIndexGeography& a_index,
const s2geog::ShapeIndexGeography& b_index,
const S2BooleanOperation::Options& options) {
S2BooleanOperation::Options closedOptions = options;
closedOptions.set_polygon_model(S2BooleanOperation::PolygonModel::CLOSED);
closedOptions.set_polyline_model(S2BooleanOperation::PolylineModel::CLOSED);

S2BooleanOperation::Options openOptions = options;
openOptions.set_polygon_model(S2BooleanOperation::PolygonModel::OPEN);
openOptions.set_polyline_model(S2BooleanOperation::PolylineModel::OPEN);

return s2geog::s2_intersects(a_index, b_index, closedOptions) &&
!s2geog::s2_intersects(a_index, b_index, openOptions);
})),
py::vectorize(TouchesPredicate()),
py::arg("a"),
py::arg("b"),
R"pbdoc(
Expand All @@ -147,16 +165,18 @@ void init_predicates(py::module& m) {
)pbdoc");

m.def("covers",
py::vectorize(Predicate([](const s2geog::ShapeIndexGeography& a_index,
const s2geog::ShapeIndexGeography& b_index,
const S2BooleanOperation::Options& options) {
S2BooleanOperation::Options closedOptions = options;
closedOptions.set_polyline_model(S2BooleanOperation::PolylineModel::CLOSED);
closedOptions.set_polygon_model(S2BooleanOperation::PolygonModel::CLOSED);
S2BooleanOperation::Options closed_options;
closed_options.set_polyline_model(S2BooleanOperation::PolylineModel::CLOSED);
closed_options.set_polygon_model(S2BooleanOperation::PolygonModel::CLOSED);

return s2geog::s2_contains(a_index, b_index, closedOptions);
})),
m.def("covers",
py::vectorize(Predicate(
[](const s2geog::ShapeIndexGeography& a_index,
const s2geog::ShapeIndexGeography& b_index,
const S2BooleanOperation::Options& options) {
return s2geog::s2_contains(a_index, b_index, options);
},
closed_options)),
py::arg("a"),
py::arg("b"),
R"pbdoc(
Expand All @@ -170,15 +190,13 @@ void init_predicates(py::module& m) {
)pbdoc");

m.def("covered_by",
py::vectorize(Predicate([](const s2geog::ShapeIndexGeography& a_index,
const s2geog::ShapeIndexGeography& b_index,
const S2BooleanOperation::Options& options) {
S2BooleanOperation::Options closedOptions = options;
closedOptions.set_polyline_model(S2BooleanOperation::PolylineModel::CLOSED);
closedOptions.set_polygon_model(S2BooleanOperation::PolygonModel::CLOSED);

return s2geog::s2_contains(b_index, a_index, closedOptions);
})),
py::vectorize(Predicate(
[](const s2geog::ShapeIndexGeography& a_index,
const s2geog::ShapeIndexGeography& b_index,
const S2BooleanOperation::Options& options) {
return s2geog::s2_contains(b_index, a_index, options);
},
closed_options)),
py::arg("a"),
py::arg("b"),
R"pbdoc(
Expand Down

0 comments on commit 4c1276e

Please sign in to comment.