google/s2geometry: spherical geometry and S2 cell indexing in C++
Computational geometry and spatial indexing on the sphere
At a glance
- What is it?
- S2 is a C++ library for shapes on a sphere, not on a flat map, with a Python binding that the README itself calls unstable. Here is how it builds, what it costs, and when a planar index is the better answer.
- Who is it for?
- Adopt google/s2geometry if your data is genuinely global and you need exact predicates over spherical caps, polygons and cells; a planar index such as a geohash prefix tree will distort near the poles and across the antimeridian, which is exactly the case S2 was built for.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem S2 solves: geometry that does not lie flat
Most spatial libraries treat latitude and longitude as a pair of Cartesian coordinates. That works until you ask a question whose answer depends on the curvature of the Earth: is this point inside that polygon, how far apart are these two shapes, which cells cover this region. Planar approximations break down near the poles and along the antimeridian, where a naive bounding box wraps from +180 to -180 degrees.
S2 takes the other route. The README states that the library is "primarily designed to work with spherical geometry, i.e., shapes drawn on a sphere rather than on a planar 2D map", and that this makes it "especially suitable for working with geographic data". The intended audience is anyone building a spatial index over global data: map rendering pipelines, geofencing services, and anything that needs to compare regions rather than points. The repository is written in C++ and published under Apache-2.0.
How the S2 cell hierarchy and the shape index fit together
The mechanism is a hierarchical decomposition of the sphere into cells, plus an index over shapes placed in that hierarchy. The README points new readers at a basic-types introduction rather than explaining the scheme itself, so the specifics of the projection and the cell numbering live on s2geometry.io, not in the repository README. What the README does establish is the shape of the library: it is a package for manipulating geometric shapes on a sphere, with a C++ core and optional bindings.
The build layout mirrors that split. The C++ sources live under src/, and the top-level CMakeLists.txt drives the native build. The Python interface is generated through SWIG, and the repository carries both a pyproject.toml and a setup.py that wires CMake into the Python build backend via cmake_build_extension. If you are evaluating the library, read that as a statement about where the engineering effort sits: the C++ side is the product, and the Python side is a binding layer with its own build path and its own stability caveats.
Installing google/s2geometry with CMake and a first build
The README gives two build routes. Bazel 8 or newer is required for the Bazel path, and the README says builds were tested using C++20 as set in .bazelrc. From within s2geometry/src, the test and build commands are:
bazel test "//:*"
bazel build //:s2The CMake path has stricter prerequisites. CMake must be 3.22 or newer, the compiler needs C++17 support (g++ >= 7.5 or clang >= 14.0.0 per the README), and Abseil LTS 20260526 is required at that exact version. On Ubuntu, the README installs the system packages with:
sudo apt-get install cmake libssl-devAbseil may have to be built from source if no LTS release is packaged for your platform, and the README notes it must be configured with -DCMAKE_POSITION_INDEPENDENT_CODE=ON. It also warns that s2geometry must be configured to use the same C++ version as Abseil, and that the easiest way to achieve this is to pass -DCMAKE_CXX_STANDARD=17 to cmake for both. A configure and build from the build directory looks like this:
mkdir build
cd build
cmake -DBUILD_TESTS=yes -DCMAKE_PREFIX_PATH=/path/to/absl/install -DCMAKE_CXX_STANDARD=17 ..
make -j $(nproc)
make test ARGS="-j$(nproc)"
sudo make installIf you want the Python interface, the README says to configure with -DWITH_PYTHON=ON and to install SWIG 4 and python3-dev, with Python 3.10 required. The pyproject.toml confirms this on the packaging side: requires-python is ">=3.10" and the cibuildwheel section builds only cp310-* because of the limited API. Building a wheel is a two-step process the README documents as creating a virtual environment, installing build, and running python -m build, with the wheel landing in dist.
Where google/s2geometry will cost you: 0.x APIs, a pinned Abseil, and M1 test failures
Three constraints deserve attention before you commit.
First, stability. The README is blunt: all releases are version 0.x, so there are "no API or ABI stability guarantees". The project says that starting with 1.0 it will adhere to SemVer and follow the Google OSS breaking change policy. Until then, a minor version bump can change signatures. The Python API is called out separately as "particularly unstable", with a stated plan to replace the SWIGged API with a pybind11 version that has more Pythonic names and more complete functionality. Anyone building a long-lived service on the Python binding should treat the binding as a moving target.
Second, dependency pinning. The README does not say "a recent Abseil"; it says Abseil LTS 20260526 and adds that "this exact version must be used". That is a real operational cost for teams that already carry an Abseil version for other C++ dependencies, because you may end up maintaining two.
Third, platform. The README's status section states that all tests enumerated in BUILD.bazel pass on x86 machines, but that on Apple M1 s2loop_measures_test fails due to a 6% excess accumulated error, and that the issue may require revision of boringssl or exactfloat. That is a documented, unresolved failure on a common development machine, not a rumour.
S2 geometry vs geohash: what actually differs
The comparison people reach for is geohash. Both encode location into a hierarchical string or integer, and both let you answer proximity questions by comparing prefixes. The difference is the surface they subdivide. A geohash grid is defined over latitude and longitude, so cell shapes and areas vary with latitude, and the grid has a seam at the antimeridian where adjacent cells are not adjacent in the encoding. S2's hierarchy is defined on the sphere itself, which is why the library can offer exact predicates over spherical caps and polygons rather than approximations inherited from a lat/lon grid.
If your data is confined to one country and your queries are point-in-box lookups, a geohash or an R-tree over projected coordinates is simpler, has no pinned Abseil, and will not surprise you at the poles. S2 earns its complexity when the region is global, when polygon containment must be exact, or when you need a single integer that identifies a cell at a chosen level of detail. The README's own framing supports this: spherical geometry is the point, and geographic data is the motivating case.
Licence, maintenance and upgrade cost
The repository is licensed Apache-2.0. The pyproject.toml declares license = "Apache-2.0" and lists LICENSE, NOTICE and AUTHORS under license-files, which means the NOTICE and AUTHORS files travel with redistributions. That is a normal Apache-2.0 arrangement, but it is worth checking with whoever handles your attribution obligations rather than assuming the LICENSE file alone is enough. Nothing here is legal advice.
On maintenance, the last push to the default branch was on 2026-09-15, and the most recent tagged release is v0.14.0 from 2026-04-23, following v0.13.0 and v0.13.1 in December 2025. The repository is not archived. The README does not document a rollback procedure, and it explicitly notes there is no uninstall target, though install_manifest.txt may be helpful. Plan your upgrade path around the 0.x versioning rather than around a deprecation policy, because the README says the deprecation policy only starts at 1.0.
Editorial conclusion
Adopt google/s2geometry if your data is genuinely global and you need exact predicates over spherical caps, polygons and cells; a planar index such as a geohash prefix tree will distort near the poles and across the antimeridian, which is exactly the case S2 was built for. Do not adopt it if you need a stable API surface today: the README states that all releases are version 0.x with no API or ABI stability guarantees, and the Python API is described as particularly unstable with a planned replacement of the SWIG binding by a pybind11 version. Before committing, verify three things: that your toolchain can supply Abseil LTS 20260526 exactly, since the README says this exact version must be used; that your Abseil and s2geometry builds share the same CMAKE_CXX_STANDARD value, because the README warns they must match; and whether your target platform is Apple M1, where the README records that s2loop_measures_test fails due to a 6% excess accumulated error.
Frequently asked questions
What are S2 cells in google/s2geometry?
They are the units of the library's hierarchical decomposition of the sphere, which is what lets S2 index shapes on a spherical surface rather than on a flat map. The README points readers to the basic types introduction on s2geometry.io for the details of the scheme.
What is s2 geometry in google/s2geometry?
It is a package for manipulating geometric shapes that is primarily designed to work with spherical geometry, meaning shapes drawn on a sphere rather than on a planar 2D map. The README says this makes it especially suitable for working with geographic data.
How does s2 geometry compare with geohash?
Both give you a hierarchical location encoding, but S2's hierarchy is defined on the sphere while a geohash grid is defined over latitude and longitude. That is the difference that matters for exact predicates and for regions near the poles or the antimeridian.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/google-s2geometry)