Fundamentals 17 min read

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.

Zhuanzhuan Tech
Zhuanzhuan Tech
Zhuanzhuan Tech
Using Java Topology Suite (JTS) for Spatial Geometry Operations and Fast Point‑in‑Polygon Checks

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())); // both

3.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/

Javapoint-in-polygonGeometry RepairJTSSpatial GeometrySpatial Index
Zhuanzhuan Tech
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.