The JTS Topology Suite is a library for creating and manipulating vector geometry.
This project is a faithful language port of JTS 1.20.0 from
Java to Kotlin Multiplatform. It is not a fork or a redesign: the goal is behaviour identical to
upstream JTS, with the same public types and the same org.locationtech.jts.* package names, so
that existing JTS knowledge and documentation carry over directly.
For everything conceptual — what the library does, the geometry model, algorithms, the FAQ, and the API reference — please see the original project: https://github.com/locationtech/jts. This README covers only what is specific to the Kotlin port: how to depend on it, and where its API deviates from upstream.
Supported targets: JVM (Java 8+), JS (Node/browser), Wasm/JS, and Kotlin/Native (macOS, iOS, Linux, Windows).
How this port was made. The Java→Kotlin conversion was carried out almost autonomously by Anthropic's Claude Code (Claude Opus), under the direction of the maintainer, who set the strategy and made the key decisions. The translation was kept faithful by compiling the Kotlin against JTS's own unmodified Java test suite at every step — the same 2100+ tests upstream uses — so the ported code is validated against the original as its reference.
Artifacts are published under group de.mpmediasoft.kts, version 1.20.0.0 (the 4th component is
the port revision against JTS 1.20.0). The library is modular — depend only on what you need:
| Gradle project | Artifact | Contents |
|---|---|---|
| core | kts-core |
Geometry model, spatial predicates, overlay, buffer, algorithms, WKT/WKB writers |
| WKT/WKB IO | kts-io-wkt |
WKTReader, WKBReader, WKBWriter |
| GML IO | kts-io-gml |
GMLReader, GMLWriter |
| KML IO | kts-io-kml |
KMLReader, KMLWriter |
| GeoJSON IO | kts-io-geojson |
GeoJsonReader, GeoJsonWriter (via kotlinx-serialization) |
| File IO | kts-io-files |
WKTFileReader, WKBHexFileReader (via kotlinx-io) |
Kotlin Multiplatform / Gradle — depend on the root artifact; Gradle Module Metadata resolves the right per-target variant automatically:
dependencies {
implementation("de.mpmediasoft.kts:kts-core:1.20.0.0")
implementation("de.mpmediasoft.kts:kts-io-wkt:1.20.0.0") // optional, for WKT/WKB parsing
}Plain JVM (Gradle or Maven) — use the -jvm artifacts (kts-core-jvm, kts-io-wkt-jvm, …).
The artifacts are published to Maven Central — just make sure
mavenCentral()is in yourrepositories { }. (To build against an unreleased local change instead, run./gradlew publishToMavenLocaland addmavenLocal().)
Release notes & API docs. See the v1.20.0.0 GitHub release for the changelog and a downloadable bundle of the aggregated Dokka API documentation (
kts-1.20.0.0-docs.zip).
Example (Kotlin):
import org.locationtech.jts.io.WKTReader
import org.locationtech.jts.io.WKTWriter
val geom = WKTReader().read("POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))")
// The ported types keep JTS's explicit Java getters (getArea(), getCentroid(), …):
println(geom.getArea()) // 1.0
println(WKTWriter().write(geom.getCentroid())) // POINT (0.5 0.5)
println(WKTWriter().write(geom.buffer(0.25))) // POLYGON ((...))
// …and an additive extension-property layer restores the Kotlin `.property` idiom you'd get from the
// Java JTS artifacts. Import it (`import org.locationtech.jts.geom.*`) and write:
println(geom.area) // 1.0
println(WKTWriter().write(geom.centroid)) // POINT (0.5 0.5)The port is faithful, but making the code multiplatform (removing the JDK dependency) required a small number of deliberate, documented changes. The notable ones for consumers:
- IO is split into separate modules. In upstream JTS the readers/writers live in
jts-core. Here, the WKT/WKB writers stay inkts-core, but the readers and the GML/KML/file IO move to the à-la-cartekts-io-*modules above, so a geometry-only user pulls zero IO dependencies. - Java serialization is removed. No type implements
java.io.Serializable; there are noserialVersionUIDfields. Use WKT/WKB for persistence. Cloneable/clone()is removed from the multiplatform surface. Use the existing runtime-type-preservingcopy()methods instead (clone()was already deprecated upstream).- Stream-based (
java.io) IO is JVM-only. The common API reads/writesStringandByteArray; theReader/Writer/InputStreamoverloads are provided as JVM-only extension functions (e.g.WKTReaderExtensions.read(reader)), sincejava.iotypes cannot exist in common code. - GML: breaking SAX API change.
GMLHandleris no longer a SAXDefaultHandler, andGMLReader.readthrowsParseExceptioninstead ofSAXException/ParserConfigurationException. - GeoJSON: JSON backend swapped. The reader/writer are built on
kotlinx-serialization-jsoninstead of the JVM-onlyorg.json.simple. The public API (GeoJsonReader/GeoJsonWriter) is unchanged; exact JSON output matches upstream on the JVM, whereGeoJsonWriter.formatOrdinaterenders ordinates viaDouble.toString(whole-number rendering can differ on JS/native). - Dropped, JVM-desktop-only pieces: the
org.locationtech.jts.awtpackage (AWTShapeconversion) and the internal dev/debug helpers (Debug,TestBuilderProxy). - Removed configuration hooks: the
jts.overlay/jts.relatesystem-property switches (the default implementations are used unconditionally). - Coordinates & names: artifacts use group
de.mpmediasoft.ktsandkts-*artifact ids to avoid any clash with the upstreamorg.locationtech.jtsJava artifacts. Source package names are unchanged (org.locationtech.jts.*).
The complete, itemised list — including internal changes and the rationale for each — is in
doc/kotlin/KOTLIN-MP-COMPATIBILITY.md.
Like upstream JTS, this port is dual-licensed under:
- Eclipse Public License 2.0 — see
LICENSE_EPLv2.txt - Eclipse Distribution License 1.0 (a BSD-style license) — see
LICENSE_EDLv1.txt
