Using Java Topology Suite (JTS) for Spatial Geometry Operations and Fast Point‑in‑Polygon Checks
This article introduces the Java Topology Suite (JTS), explains its core geometry models, WKT format, spatial relations, and operations, and demonstrates how to efficiently determine whether a point lies within service coverage polygons using MBR filtering, spatial indexes such as R‑tree and Quadtree, and geometry repair techniques.
1 Introduction
In on‑site service scenarios, the coverage area is defined by an electronic fence on a map, which requires geometric operations and spatial relationship judgments to determine whether a location is within the service area. This article introduces JTS and shows how to solve these problems using its spatial capabilities.
2 JTS Overview
JTS (Java Topology Suite) is a Java library for creating and manipulating vector geometries, providing abstractions for geometry models and a rich set of spatial operations and relationship tests.
2.1 Adding JAR Packages
Only the core modules are used:
jts-core – geometry model abstraction, spatial operations, relationship algorithms.
jts-io-common – I/O for formats such as WKT and WKB.
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.19.0</version>
</dependency>
<dependency>
<groupId>org.locationtech.jts.io</groupId>
<artifactId>jts-io-common</artifactId>
<version>1.19.0</version>
</dependency>2.2 Basic Geometry Models
JTS provides common geometry types:
Model
Definition
Typical Use
Point
A single location represented by an (x, y) coordinate.
Points of interest, event locations.
MultiPoint
Multiple independent points.
Distribution of multiple locations such as chain stores.
LineString
A sequence of points forming a one‑dimensional geometry.
Roads, rivers.
MultiLineString
Several disconnected LineString objects.
Complex road networks, contour lines.
Polygon
Closed planar area possibly with interior holes.
Administrative boundaries, building footprints.
MultiPolygon
Multiple independent polygons.
Islands, complex administrative regions.
GeometryCollection
Collection of arbitrary geometry types.
Complex spatial scenes containing mixed features.
In practice, the most frequently used models are Point and Polygon (or MultiPolygon) for representing service coverage.
2.3 Geometry Description Formats
WKT (Well‑Known Text) is a textual format for describing 2‑D/3‑D geometries. The basic syntax is GeometryType (coordinates) . Examples:
POINT (282 455)
LINESTRING (260 250, 485 248, 520 380)
POLYGON ((320 390, 370 330, 470 360, 460 430, 375 432, 320 390))JTS reads and writes WKT via WKTReader and WKTWriter :
// Read WKT strings
WKTReader wktReader = new WKTReader();
Geometry point = wktReader.read("POINT (282 455)");
Geometry line = wktReader.read("LINESTRING (260 250, 485 248, 520 380)");
Geometry polygon = wktReader.read("POLYGON ((320 390, 370 330, 470 360, 460 430, 375 432, 320 390))");
// Write geometries back to WKT
WKTWriter wktWriter = new WKTWriter();
System.out.println(wktWriter.write(point));
System.out.println(wktWriter.write(line));
System.out.println(wktWriter.write(polygon));2.4 Spatial Relationships
JTS defines spatial relationships based on the DE‑9IM model. Common relations include:
Relation
Definition
Equals
Topologically equal geometries.
Disjoint
No common points.
Intersects
At least one common point.
Within
Geometry A is completely inside Geometry B.
Contains
Geometry A completely contains Geometry B.
Example of relationship checks between two polygons:
WKTReader wktReader = new WKTReader();
Geometry geometryA = wktReader.read("POLYGON ((320 390, 370 330, 470 360, 460 430, 375 432, 320 390))");
Geometry geometryB = wktReader.read("POLYGON ((500 420, 430 360, 530 260, 500 420))");
System.out.println("Equal: " + geometryA.equals(geometryB));
System.out.println("Disjoint: " + geometryA.disjoint(geometryB));
System.out.println("Intersects: " + geometryA.intersects(geometryB));
System.out.println("Within: " + geometryA.within(geometryB));
System.out.println("Contains: " + geometryA.contains(geometryB));For on‑site service, the key question is whether a point lies inside a polygon (PIP).
WKTReader wktReader = new WKTReader();
Geometry geometryA = wktReader.read("POLYGON ((320 390, 370 330, 470 360, 460 430, 375 432, 320 390))");
Geometry geometryB = wktReader.read("POLYGON ((500 420, 430 360, 530 260, 500 420))");
Geometry point = wktReader.read("POINT (390 380)");
System.out.println("point in geometryA: " + geometryA.contains(point));
System.out.println("point in geometryB: " + geometryB.contains(point));2.5 Spatial Operations
JTS offers operations such as Intersection, Union, and Difference:
Operation
Definition
Intersection
Common part of two geometries.
Union
Merge of two or more geometries.
Difference
Subtract one geometry from another.
WKTReader wktReader = new WKTReader();
Geometry geometryA = wktReader.read("POLYGON ((320 390, 370 330, 470 360, 460 430, 375 432, 320 390))");
Geometry geometryB = wktReader.read("POLYGON ((500 420, 430 360, 530 260, 500 420))");
System.out.println("Intersection: " + wktWriter.write(geometryA.intersection(geometryB)));
System.out.println("Union: " + wktWriter.write(geometryA.union(geometryB)));
System.out.println("Difference: " + wktWriter.write(geometryA.difference(geometryB)));3 Fast Determination of Service Eligibility
To quickly decide whether a user’s location is within the service area, the problem reduces to a Point‑in‑Polygon (PIP) test. Scanning all polygons naïvely yields O(N) complexity, which is inefficient for large N.
3.1 Minimum Bounding Rectangle (MBR)
An MBR is the smallest rectangle that completely contains a geometry. If a point is outside the MBR, it cannot be inside the polygon, allowing fast exclusion.
mbr.getLngMin() <= point.getLng() &&
mbr.getLngMax() >= point.getLng() &&
mbr.getLatMin() <= point.getLat() &&
mbr.getLatMax() >= point.getLat()JTS represents an MBR with the Envelope class:
WKTReader wktReader = new WKTReader();
Geometry geometryA = wktReader.read("POLYGON ((320 390, 370 330, 470 360, 460 430, 375 432, 320 390))");
Envelope envelope = geometryA.getEnvelopeInternal();
System.out.println(envelope.getMaxX());
System.out.println(envelope.getMaxY());
System.out.println(envelope.getMinX());
System.out.println(envelope.getMinY());3.2 Spatial Indexes
Beyond simple MBR filtering, JTS provides more sophisticated spatial indexes such as R‑tree (STRtree) and Quadtree, which recursively partition space to accelerate queries.
WKTReader wktReader = new WKTReader();
Geometry geometryA = wktReader.read("POLYGON ((320 390, 370 330, 470 360, 460 430, 375 432, 320 390))");
Geometry geometryB = wktReader.read("POLYGON ((500 420, 430 360, 530 260, 500 420))");
STRtree rtree = new STRtree();
rtree.insert(geometryA.getEnvelopeInternal(), "Polygon-A");
rtree.insert(geometryB.getEnvelopeInternal(), "Polygon-B");
rtree.build();
System.out.println(rtree.query(wktReader.read("POINT (337 391)").getEnvelopeInternal())); // only Polygon-A
System.out.println(rtree.query(wktReader.read("POINT (496 390)").getEnvelopeInternal())); // only Polygon-B
System.out.println(rtree.query(wktReader.read("POINT (452 367)").getEnvelopeInternal())); // both3.3 Overall Solution Flow
Build a spatial index (e.g., STRtree) for all polygon MBRs.
Use the index to quickly filter polygons that may contain the point.
Perform precise spatial relationship checks (e.g., contains ) on the filtered set.
To keep the index up‑to‑date without excessive rebuilding, it can be refreshed periodically (e.g., every 10 minutes) and store only polygon IDs in the index, loading full geometry data lazily when needed.
4 Geometry Repair Techniques
In real‑world operations, drawn geometries may contain anomalies such as overlapping points, tiny gaps, or self‑intersections. Two common repair methods are:
Buffer operation – creates a buffer around a geometry to fix self‑intersection and small gaps.
Snap operation – snaps vertices to nearby vertices or edges to correct minor topological errors.
Example of repairing a self‑intersecting polygon using a zero‑distance buffer:
WKTReader wktReader = new WKTReader();
Geometry geometryA = wktReader.read("POLYGON ((340 490, 370 330, 730 350, 700 270, 340 490))");
WKTWriter wktWriter = new WKTWriter();
wktWriter.setPrecisionModel(new PrecisionModel(0));
System.out.println(wktWriter.write(geometryA.buffer(0)));5 Conclusion
Java Topology Suite (JTS) is a powerful spatial data processing library that provides developers with extensive tools for handling complex geometric problems. This article presented a simple application of JTS for on‑site service coverage checks; further exploration can unlock more advanced capabilities.
6 References
Java Topology Suite (JTS): https://github.com/locationtech/jts
OSGeo China: https://www.osgeo.cn/
Zhuanzhuan Tech
A platform for Zhuanzhuan R&D and industry peers to learn and exchange technology, regularly sharing frontline experience and cutting‑edge topics. We welcome practical discussions and sharing; contact waterystone with any questions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.