Skip to content

Commit

Permalink
add: some predicates (#18)
Browse files Browse the repository at this point in the history
* add: some predicates

* Update predicates.cpp

* docstrings formating nit

* Add within and disjoint predicates

Add within and disjoint predicates to api.rst and .pyi

---------

Co-authored-by: Benoit Bovy <benbovy@gmail.com>
  • Loading branch information
ccalvocm and benbovy authored Mar 9, 2023
1 parent ef252c3 commit 0b7d3bb
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,5 @@ Predicates
equals
intersects
contains
within
disjoint
43 changes: 40 additions & 3 deletions src/predicates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,22 @@ bool contains(PyObjectGeography a, PyObjectGeography b) {
return s2geog::s2_contains(a_index, b_index, options);
}

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

S2BooleanOperation::Options options;
return s2geog::s2_contains(b_index, a_index, options);
}

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

S2BooleanOperation::Options options;
return !s2geog::s2_intersects(a_index, b_index, options);
}

void init_predicates(py::module& m) {
m.def("intersects", py::vectorize(&intersects), py::arg("a"), py::arg("b"),
R"pbdoc(
Expand Down Expand Up @@ -64,13 +80,34 @@ void init_predicates(py::module& m) {
R"pbdoc(
Returns True if B is completely inside A.
A contains B if no points of B lie in the exterior of A and at least
one point of the interior of B lies in the interior of A.
Parameters
----------
a, b : :py:class:`Geography` or array_like
Geography object(s)
)pbdoc");

m.def("within", py::vectorize(&within), py::arg("a"), py::arg("b"),
R"pbdoc(
Returns True if A is completely inside B.
Parameters
----------
a, b : :py:class:`Geography` or array_like
Geography object(s)
)pbdoc");
}

m.def("disjoint", py::vectorize(&disjoint), py::arg("a"), py::arg("b"),
R"pbdoc(
Returns True if A boundaries and interior does not intersect at all
with those of B.
Parameters
----------
a, b : :py:class:`Geography` or array_like
Geography object(s)
)pbdoc");

}
2 changes: 2 additions & 0 deletions src/spherely.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ destroy_prepared: _VFunc_Nin1_Nout1[Literal["destroy_prepared"], Geography, Any]
intersects: _VFunc_Nin2_Nout1[Literal["intersects"], bool, bool]
equals: _VFunc_Nin2_Nout1[Literal["intersects"], bool, bool]
contains: _VFunc_Nin2_Nout1[Literal["contains"], bool, bool]
within: _VFunc_Nin2_Nout1[Literal["within"], bool, bool]
disjoint: _VFunc_Nin2_Nout1[Literal["disjoint"], bool, bool]

# temp (remove)

Expand Down
39 changes: 39 additions & 0 deletions tests/test_predicates.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,42 @@ def test_contains():
a2 = spherely.LineString([(50, 8), (60, 8)])
b2 = spherely.Point(50, 8)
assert spherely.contains(a2, b2)

def test_within():
# test array + scalar
a = spherely.Point(40, 8)
b = np.array(
[
spherely.LineString([(40, 8), (60, 8)]),
spherely.LineString([(20, 0), (30, 0)]),
]
)

actual = spherely.within(a, b)
expected = np.array([True, False])
np.testing.assert_array_equal(actual, expected)

# two scalars
a2 = spherely.Point(50, 8)
b2 = spherely.LineString([(50, 8), (60, 8)])
assert spherely.within(a2, b2)

def test_disjoint():

a = spherely.Point(40, 9)
b = np.array(
[
spherely.LineString([(40, 8), (60, 8)]),
spherely.LineString([(20, 0), (30, 0)]),
]
)

actual = spherely.disjoint(a, b)
expected = np.array([True, True])
np.testing.assert_array_equal(actual, expected)

# two scalars
a2 = spherely.Point(50, 9)
b2 = spherely.LineString([(50, 8), (60, 8)])
assert spherely.disjoint(a2, b2)

0 comments on commit 0b7d3bb

Please sign in to comment.