pybind: Add S2Cell bindings#4
Conversation
c2cd642 to
e212df1
Compare
9e7ace4 to
a9a433c
Compare
a9a433c to
1fc4db2
Compare
32b3ab8 to
96ba727
Compare
1fc4db2 to
31d1af1
Compare
Binds S2Cell's constructors, factory methods, geometric accessors (vertex, edge, center, area), boundary helpers, containment and intersection predicates, and subdivide. Adds 43 unit tests. Distance methods and the S2Cap/S2LatLngRect-returning region methods are deferred with a TODO; they depend on S1ChordAngle/S2Cap/S2LatLngRect bindings which are not yet in place. (Stacked on deustis/s2cell_id_bindings / PR google#593.)
- Drop MaybeThrowNotValidCellId from S2Cell(S2CellId) constructor; all S2CellId objects reachable from Python are already validated - Remove instance average_area(); keep only static average_area_for_level() - Add S2CellId::kMaxPosition constant and validate pos in from_face_pos_level for both S2CellId and S2Cell bindings - Switch constants to cls.attr() pattern in both S2CellId and S2Cell bindings; update README to document this style - Fix BUILD: add absl/strings dep to s2cell_id_bindings - Remove misleading encode/decode comment from s2cell_bindings.cc - Fix magic constant 1<<30 -> 1<<S2CellId.MAX_LEVEL in s2cell_test.py
Consistent with other MaybeThrow* helpers in both binding files.
31d1af1 to
677224f
Compare
- Fix s2cell deps comment in module.cc to include s1chord_angle - Clarify orientation docstring (bitmask, values 0-3) - Drop _raw variants (vertex_raw, edge_raw, center_raw): Python callers don't feed unnormalized vectors into exact C++ predicates
| # Orientation is in [0, 3]. | ||
| for f in range(6): | ||
| orient = s2.S2Cell.from_face(f).orientation | ||
| self.assertIn(orient, range(4)) |
There was a problem hiding this comment.
Assert exact (or floating point approx) values in tests
There was a problem hiding this comment.
Done — test now asserts face cells have orientation 0, with a range check on a non-face cell.
| self.assertAlmostEqual(v0.y, v4.y) | ||
| self.assertAlmostEqual(v0.z, v4.z) | ||
|
|
||
| def test_vertex_raw(self): |
There was a problem hiding this comment.
I thought we removed these _raw variants
| # Face cell in (i,j) spans [0, 2^30]. | ||
| bottom = face.ij_coord_of_edge(s2.S2Cell.BOTTOM_EDGE) | ||
| top = face.ij_coord_of_edge(s2.S2Cell.TOP_EDGE) | ||
| self.assertIn(bottom, (0, 1 << 30)) |
There was a problem hiding this comment.
Done — now asserts BOTTOM=0, TOP=2^30, LEFT=0, RIGHT=2^30.
| with self.assertRaises(ValueError): | ||
| s2.S2Cell.average_area_for_level(-1) | ||
|
|
||
| def test_approx_area_positive(self): |
There was a problem hiding this comment.
this test is not useful, assert an approximate value within the error tolerance
There was a problem hiding this comment.
Done — now checks the face cell area is within 3% of 4π/6.
| .def("may_intersect", &S2Cell::MayIntersect, py::arg("cell"), | ||
| "Return true if this cell may intersect the given cell") | ||
|
|
||
| // Traversal |
There was a problem hiding this comment.
Let's get rid of traversal section and move this to geometric operations (also in tests)
There was a problem hiding this comment.
Done — Traversal section removed, subdivide moved into Geometric operations.
| // Deps: s1angle, s2point, s2latlng, r2point, r2rect | ||
| bind_s2cell_id(m); | ||
|
|
||
| // Deps: s2cell_id, s2point, s2latlng, s1chord_angle, r2rect |
There was a problem hiding this comment.
make the deps order match the declaration order above
There was a problem hiding this comment.
Fixed — now r2rect, s1chord_angle, s2cell_id, s2latlng, s2point.
|
Superseded by google#631. |
Adds pybind11 bindings for
S2Cell, covering constructors, factory methods, properties, geometric operations, containment/intersection tests, distance queries, and traversal.The
is_distance_less/is_distance_less_or_equalfamily is omitted — callers can useget_distance(...) < limitdirectly.Naming:
GetDistanceis overloaded in C++ forS2Point, edge(a, b), andS2Cellarguments. Per the binding interface notes, the short name (get_distance) is used for theS2Pointoverload, and longer names (get_distance_to_edge,get_distance_to_cell) for the others.get_max_distancefollows the same pattern._rawvariants omitted:vertex_raw,edge_raw, andcenter_rawreturn unnormalized vectors intended for feeding into exact C++ predicates. Python callers won't do that, so these are dropped in favor of the normalized versions.subdivide()returns a 4-tuple ofS2Cellrather than an output array.get_cap_boundandget_rect_boundare deferred untilS2CapandS2LatLngRectare bound.Encode/Decodeare intentionally omitted per the serialization policy in the pybind README.Test plan
bazel test //python/...— all suites pass.