Library / SDK
locationtech/spatial4j avatar
locationtech/spatial4j

Spatial4j: Java shapes that work in flat and spherical models

LocationTech Spatial4j: A Geospatial Library for Java

963 stars175 forksJavaLicense varies

At a glance

What is it?
Spatial4j is the LocationTech library for spatial work in Java, and its reason to exist is that JTS only speaks Euclidean geometry and has no circle shape, while Spatial4j provides shapes in Euclidean, cylindrical and spherical models, geodesic distance calculations, and readers and writers for WKT and GeoJSON. It is a small, deliberately scoped library that a geohash or grid indexing scheme can sit on top of.
Who is it for?
Adopt Spatial4j when your Java code needs a circle, a lat-lon rectangle relationship or a geodesic distance that JTS cannot give you, especially in an indexing or retrieval system where a false match is preferable to a missed one. It is the wrong tool if you need full topological operations or arbitrary geometry editing, because that is JTS's job and Spatial4j wraps rather than replaces it.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 67 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Three capabilities, one library

Spatial4j is a general purpose spatial and geospatial Java library, and the README states its core capabilities in three parts. It provides common shapes that can work in Euclidean and geodesic, that is on the surface of a sphere, world models. It provides distance calculations and other math. And it reads and writes shapes from formats like WKT and GeoJSON.

That list sounds modest until you notice what is missing from it. There is no mention of topology, of overlay operations, of buffering a polygon, of the full planar geometry vocabulary. Spatial4j is not trying to be a geometry engine, and the README says as much in a section titled Why not use JTS, which is the most substantive part of the document.

The project is a project of the LocationTech Industry Working Group of the Eclipse Foundation, and the official home page is the LocationTech one, although the README notes that the repository carries the richer information. The licence is the Apache Software Licence, with the text in the repository as asl-v20.txt, although the repository's own licence field is recorded as unknown, so the file in the tree is the one to rely on.

The audience is stated in the README through a specific use case. If you are working with spatial grid-square indexing schemes, be it Geohash or something custom, you are likely to find especially high utility from Spatial4j. That is the shape of the project. It sits underneath a geohash implementation, a tile scheme or a spatial index, providing the geometry that such systems need to answer questions like which cells does this radius cover, and it deliberately leaves the indexing itself to somebody else.

The library is on Maven Central under org.locationtech.spatial4j, and the entry point is the SpatialContext class, which the README calls the facade to all of Spatial4j. It acts as a factory for shapes and holds references to most of the other classes you might use, with convenience methods on top.

Euclidean, cylindrical and spherical, and what each shape can do

The shape model is where the library earns its place, and the README gives the compatibility table directly.

Point, Rectangle and ShapeCollection work in all three models. Circle works in Euclidean and spherical but not cylindrical. LineString and the buffered line and buffered shape work in Euclidean only. Polygon works in Euclidean and cylindrical but not spherical.

The reason for the wrap-around behaviour is spelled out: most shapes are augmented to support a wrap-around at X minus 180 and plus 180 for compatibility with latitude and longitude, which is effectively a cylindrical model. The dateline is the awkward place for a flat plane, and the library handles it by treating the horizontal axis as a cylinder rather than a line.

The real bonus, in the README's words, is the circle, a point-radius shape that can operate on a surface-of-a-sphere model. The terminology is worth noting because it trips people up. The words geodetic, geodesic and geo are used in this project as synonyms for the spherical model, although technically those words have a broader meaning.

The rectangle in the spherical model exists as a lat-lon rectangle, and the README explains that its math is no different from the cylindrical case. Polygons are the exception: they do not support pole wrap, so there is no Antarctica polygon, but they do cross the dateline, and they are supported by wrapping the JTS Geometry class, which means most of the fundamental logic for that shape is implemented by JTS rather than here.

What a shape can do is the same list for every type. It can compute its lat-lon bounding box. It can compute an area, and for some shapes that is more of an estimate. It can compute whether it contains a provided point. And it can compute its relationship to a lat-lon rectangle, where the four relationships are CONTAINS, WITHIN, DISJOINT and INTERSECTS.

One detail in that list is worth pausing on, because it is a modelling decision rather than an oversight. Spatial4j has no notion of touching. Two shapes that share only a boundary are neither intersecting nor disjoint in the way a topology library would treat them, and code that assumes otherwise will get a different answer from Spatial4j than from JTS.

Formats, the custom extensions, and the three distance calculators

The format support is broader than the two headline formats, and the README points to a separate FORMATS.md for the details.

WKT reading and writing is there, with two additions beyond the standard. The ENVELOPE extension from CQL is included, and there is a Spatial4j custom BUFFER operation, where buffering a point gives you a Circle. That is a convenient bridge between a text format that has no circle and the shape that the library models natively.

GeoJSON is supported for reading and writing, along with a Polyshape format documented in FORMATS.md, and there is a Jackson-databind serialization route for reading and writing shapes through that framework.

For distance, the README lists three great-circle calculators: the law of cosines, the Haversine formula and the Vincenty method. Three implementations of the same quantity is not redundancy for its own sake. The law of cosines is the simplest and the least numerically stable for small distances, Haversine is the usual default and is stable except near the antipodes, and Vincenty is the accurate one for the ellipsoid. Which of them the library uses in a given call, and with what accuracy, is a decision an integrator has to make consciously.

For a project that only needs a rough distance, any of the three will do. For a project whose answers feed a compliance or billing decision, the choice matters, and the presence of all three means the library is not hiding that choice behind a single approximation.

The dependency story, which is unusually clean

Spatial4j runs on Java 8 or better, and the README makes a claim that is rare in a library of this size: all of the dependencies listed in the pom are either marked optional or are needed for testing.

The optional dependencies are three. JTS is needed if you use polygons, and obviously if you use any of the classes prefixed with Jts. Noggit, the JSON parsing library, is only needed for GeoJSON parsing, and the README specifies that it is not required for writing, which is a useful asymmetry, since a service that produces GeoJSON needs no JSON parser. Jackson-databind is needed only if you want the Jackson-databind feature for reading and writing shapes.

So the minimum footprint is a library with no runtime dependencies at all, and the extra machinery is opt-in per feature. For a service that only needs points, rectangles and a distance calculation, the deployment cost is a single jar.

That optionality also shapes the polygon story. Since the polygon implementation is JTS wrapped, the interesting geometry behaviour of Spatial4j for polygons is really JTS behaviour with a dateline-aware wrapper on top, and the value Spatial4j adds there is the wrap support rather than new geometry.

Why not JTS, and the inscribed polygon problem

The README explains the origin in one sentence: Spatial4j was born out of an unmet need from other open-source Java software.

JTS is the most popular spatial library in Java, and the README is explicit about what it lacks. JTS is powerful but only supports Euclidean geometry, with no geodesics, and it has no Circle shape.

So the two features Spatial4j leads with are a geodesic circle implementation, a point-radius on the surface of a sphere, and the wrapping of JTS geometries to add dateline-wrap support. The README also mentions that JTS broadened its licensing at one point, and that this was originally a major factor in the founding of Spatial4j.

The circle discussion is the most useful part of the document for anyone deciding between the two libraries, and it is unusually honest. A geodesic circle implementation is described as non-trivial, and the README points to the extensive testing as evidence. Then it makes the case against the obvious alternative. If you do not need a circle, many applications will use a polygon substitute, but the README warns that this is not only an approximation, it is the wrong kind of approximation, because common algorithms inscribe the circle in the polygon rather than circumscribing it. The result is a polygon that does not quite completely cover the intended shape, which can mean not finding the data you were looking for in an information retrieval setting, and the README states the preference directly: in indexing and search, for example in Apache Lucene, it is usually better to find a false match than not to find a positive match when making approximations.

That is the argument in a sentence. If your use is filtering or retrieval, an over-inclusive shape is safe and an under-inclusive one is a missed result, and an inscribed polygon is the wrong error to make.

Two implementation details are worth noting for anyone reading the source. The library goes to some lengths to be efficient by calculating the great-circle distance a minimum number of times in order to find the intersection relationship with a rectangle. And even computing the bounding box of the spherical circle was non-obvious, because the initial algorithm lifted from the web at a popular site turned out to be false.

That last sentence is a good argument for the test suite, and for reading a library's own notes before trusting its geometry.

Maintenance, testing and the release you can actually get

Testing is taken seriously in a way that the release history makes worth examining. The README says Spatial4j is well tested, and that continuous integration runs on GitHub Actions against Java 8, 11, 17 and 21, plus a Jenkins build hosted by Eclipse, with Codecov used for code coverage. Two build systems and four Java versions is a real matrix, and running the same code on both an Eclipse-hosted Jenkins and GitHub Actions also removes the risk of a build that only works on one provider.

The release situation is the one soft spot. The most recent release in the repository's release history is spatial4j-0.8, published on 2020-11-27, and it is the only one listed. The repository itself is not archived, and the last push was on 2026-08-17, so the source has moved on substantially since that tag.

That gap matters for a library that is not archived and whose documentation still looks actively maintained. A team pinning spatial4j-0.8 is pinning a 2020 snapshot, and a team building from the branch is picking up six years of changes with no release to compare against. The CHANGES.md file at the repository root is the record of what changed, and it is the file to read when you are deciding which line to use.

The rest of the repository is conventional and complete for a project of this kind: a pom.xml, the FORMATS.md document for the format support, a CONTRIBUTING.md for contributions, a CODE_OF_CONDUCT.md, a SECURITY.md, a devnotes.md for developers, an about.md, a notice.md and an eclipse directory.

The judgement is a good one for a library with a clear purpose. Spatial4j is not going to replace JTS, and it does not try to. It fills the gap JTS leaves, namely geodesics and the circle, and it fills it in a way that a retrieval system can use without changing its error tolerance. The cost is a smaller, quieter project, and the fact that the only visible release is from 2020 is the price of being that kind of project.

Editorial conclusion

Adopt Spatial4j when your Java code needs a circle, a lat-lon rectangle relationship or a geodesic distance that JTS cannot give you, especially in an indexing or retrieval system where a false match is preferable to a missed one. It is the wrong tool if you need full topological operations or arbitrary geometry editing, because that is JTS's job and Spatial4j wraps rather than replaces it. Before integrating, decide whether you need the optional JTS, Noggit or Jackson dependencies, since the polygon support and the GeoJSON reader depend on them, and check the release version you depend on, because the most recent published release in the repository dates from 2020 even though the source has moved on since.

Frequently asked questions

What is Spatial4j and what does it provide?

It is a general purpose spatial and geospatial Java library from the LocationTech working group of the Eclipse Foundation. It provides common shapes that work in Euclidean and geodesic world models, distance calculations and other math, and readers and writers for formats such as WKT and GeoJSON.

Why should I use Spatial4j instead of JTS?

The README is explicit that JTS only supports Euclidean geometry and has no Circle shape, while Spatial4j has a geodesic circle implementation and wraps JTS geometries to add dateline-wrap support. The README also warns that polygon substitutes commonly inscribe rather than circumscribe the circle, which can mean missed results in retrieval.

Which dependencies does Spatial4j need?

All of the dependencies in the pom are optional or for testing. JTS is needed for polygons and for the Jts-prefixed classes, Noggit is needed only for GeoJSON parsing and not for writing, and Jackson-databind is needed for the Jackson-based shape reading and writing.

Which world models do the Spatial4j shapes support?

Point, Rectangle and ShapeCollection work in Euclidean, cylindrical and spherical models, Circle works in Euclidean and spherical but not cylindrical, Polygon works in Euclidean and cylindrical but not spherical because there is no pole wrap, and LineString and the buffered shapes are Euclidean only.

How does Spatial4j calculate distance?

It ships three great-circle distance calculators: the law of cosines, the Haversine formula and the Vincenty method, so the caller can choose between a simple approximation, a numerically stable default and an accurate ellipsoidal method.

Official sources

  1. Issues
  2. locationtech/spatial4j on GitHub
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/locationtech-spatial4j.svg)](https://hysenlabs.com/projects/locationtech-spatial4j)

Was this useful?