LocationTech Spatial4j: A Geospatial Library for Java
(note: Spatial4j’s official home page is at LocationTech: https://projects.eclipse.org/projects/locationtech.spatial4j
but this README has richer information)
Spatial4j is a general purpose spatial / geospatial ASL licensed open-source Java library. It’s core capabilities are 3-fold: to provide common shapes that can work in Euclidean and geodesic (surface of sphere) world models, to provide distance calculations and other math, and to read & write shapes from formats like WKT and GeoJSON. Spatial4j is a project of the LocationTech Industry Working Group of the Eclipse Foundation.
If you are working with spatial grid-square indexing schemes, be it Geohash or something custom, then you are likely to find especially high utility from Spatial4j.
Spatial4j is well tested; it’s monitored via Travis-CI continuous integration (plus another Hudson build) and we use Codecov for code coverage.
If you are interested in contributing to Spatial4j please review the contribution guidelines.
The main part of Spatial4j is its collection of shapes. Shapes in Spatial4j have these features:
Spatial4j has a variety of shapes that operate in Euclidean-space – i.e. a flat 2D plane. Most shapes are augmented to support a wrap-around at X
-180/+180 for compatibility with latitude & longitudes, which is effectively a cylindrical model. But the real bonus is its circle (i.e. point-radius shape that can operate on a surface-of-a-sphere model. See below for further info. The term “geodetic” or “geodesic” or “geo” is used here as synonymous with that model but technically those words have a more broad meaning.
Shape | Euclidean | Cylindrical | Spherical |
---|---|---|---|
Point | Y | Y | Y |
Rectangle | Y | Y | Y |
Circle | Y | N | Y |
LineString | Y | N | N |
Buffered L/S | Y | N | N |
Polygon | Y | Y | N |
ShapeCollection | Y | Y | Y |
Geometry
, which is to say that most of the fundamental logic for that shape is implemented by JTS.For more information on the formats supported, see FORMATS.md.
Spatial4j runs on Java 8 (v1.8) or better. Otherwise, all dependencies listed in the maven pom.xml are either marked optional or are for testing. The optional dependencies are:
Spatial4j was born out of an unmet need from other open-source Java software.
JTS is the most popular spatial library in Java.
JTS is powerful but it only supports Euclidean geometry (no geodesics) and it has no Circle shape.
Spatial4j has a geodesic circle implementation, and it wraps JTS geometries to add dateline-wrap support (no pole wrap yet).
JTS recently broadened it’s licensing but originally this was a major factor contributing to the founding of Spatial4j.
A geodesic circle implementation (i.e. point-radius on surface of a sphere), has been non-trivial; see for yourself and look at the extensive testing. Presumably many applications will use a polygon substitute for a circle, however note that not only is it an approximation, but common algorithms inscribe instead of circumscribe the circle. The result is a polygon that doesn’t quite completely cover the intended shape, potentially resulting in not finding desired data when applied to the information-retrieval domain (e.g. indexing/search in Apache Lucene) where it is usually better to find a false match versus not find a positive match when making approximations. Also, Spatial4j’s implementation goes to some lengths to be efficient by only calculating the great-circle-distance a minimum number of times in order to find the intersection relationship with a rectangle. Even computing the bounding-box of this shape was non-obvious, as the initial algorithm lifted from the web at a popular site turned out to be false.
The facade to all of Spatial4j is the SpatialContext
.
It acts as a factory for shapes and it holds references to most other classes you might use and/or it has convenience methods for them.
For example you can get a DistanceCalculator
but if you just want to calculate the distance then the context has a method for that.
To get a SpatialContext (or just “context” for short), you could use a global singleton SpatialContext.GEO
or JtsSpatialContext.GEO
which both use geodesic surface-of-sphere calculations (when available); the JTS one principally adds Polygon support.
If you want a non-geodesic implementation or you want to customize one of many options, then instantiate a SpatialContextFactory
(or JtsSpatialContextFactory
), set the options, then invoke newSpatialContext()
.
If you have a set of name-value string pairs, perhaps from a java properties file, then instead use the static makeSpatialContext(map, classLoader)
method which adds a lot of flexibility to the configuration initialization versus hard-coding it.
You should generally avoid calling constructors for anything in Spatial4j except for the SpatialContextFactory
. Constructors aren’t strictly forbidden but the factories are there to provide an extension point / abstraction, so don’t side-step them unless there’s a deliberate reason.
Discuss Spatial4j on our mailing list (note: old list is here).
View metadata about the project as generated by Maven: maven site.
Spatial4j has been ported to .NET (C#) where it is appropriately named Spatial4n.
Before Spatial4j, there was Lucene Spatial Playground (LSP) and
from this work a generic core spatial library emerged, independent of Lucene: Spatial4j.
The other parts of LSP were either merged into Lucene / Solr itself or were migrated to
Spatial Solr Sandbox.
On February 26th 2016, with release 0.6, Spatial4j became a LocationTech project (a part of Eclipse) following a long
incubation period.