Spatial K - A set of Kotlin Multiplatform Libraries for working with geospatial data https://maplibre.org/spatial-k/
  • Kotlin 95.4%
  • Swift 2.8%
  • Java 1.4%
  • Shell 0.3%
Find a file
dependabot[bot] 4f5fd01eb9
Bump com.facebook:ktfmt from 0.63 to 0.64 (#418)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-05 00:01:01 -07:00
.github Bump jdx/mise-action from 4.3.0 to 5.0.1 (#419) 2026-10-05 00:00:38 -07:00
.vscode chore: update tooling and configs (#325) 2026-06-02 18:10:59 -04:00
.zed chore: update tooling and configs (#325) 2026-06-02 18:10:59 -04:00
benchmark RTree spatial index (#283) 2025-11-10 17:05:41 -08:00
buildSrc Bump xmlutil from 0.91.3 to 1.0.0, Kotlin to 2.4.0 (#358) 2026-06-30 20:27:05 +02:00
docs feat(units): add text formats for lengths, areas, and rotations (#415) 2026-10-04 02:25:14 -07:00
geohash feat(geohash): add Geohash cells and OsmShortlink (#383) 2026-08-29 20:40:16 -07:00
geojson Add longitude helpers and fix extra-axis bounding boxes (#387) 2026-09-06 18:02:15 -07:00
gpx Bump xmlutil from 0.91.3 to 1.0.0, Kotlin to 2.4.0 (#358) 2026-06-30 20:27:05 +02:00
gradle Bump com.facebook:ktfmt from 0.63 to 0.64 (#418) 2026-10-05 00:01:01 -07:00
kotlin-js-store Bump kotlin from 2.4.10 to 2.4.20 (#391) 2026-10-03 23:35:02 -07:00
mise-tasks/publish Add PMTiles Swift package artifacts (#338) 2026-06-06 16:08:14 -07:00
pmtiles Bump xmlutil from 0.91.3 to 1.0.0, Kotlin to 2.4.0 (#358) 2026-06-30 20:27:05 +02:00
polyline-encoding remove unsupported apple x64 kotlin targets (#336) 2026-06-06 14:07:14 -07:00
testutil feat(units): add text formats for lengths, areas, and rotations (#415) 2026-10-04 02:25:14 -07:00
tools/units-generator feat(units)!: expand unit catalogs and codegen their definitions (#395) 2026-10-03 22:40:55 -07:00
turf feat(units)!: expand unit catalogs and codegen their definitions (#395) 2026-10-03 22:40:55 -07:00
units feat(units): add text formats for lengths, areas, and rotations (#415) 2026-10-04 02:25:14 -07:00
.coderabbit.yml chore: update tooling and configs (#325) 2026-06-02 18:10:59 -04:00
.gitattributes feat(units)!: expand unit catalogs and codegen their definitions (#395) 2026-10-03 22:40:55 -07:00
.gitignore Add PMTiles Swift package artifacts (#338) 2026-06-06 16:08:14 -07:00
AGENTS.md docs: simplify contributor and PR guidance (#399) 2026-10-03 16:11:37 -07:00
AI_POLICY.md docs: simplify contributor and PR guidance (#399) 2026-10-03 16:11:37 -07:00
BENCHMARK.md streamline toolchain: mise to install tools, hk to orchestrate linters, dprint to orchestrate formatters (#306) 2026-04-04 05:06:09 +02:00
build.gradle.kts feat(geohash): add Geohash cells and OsmShortlink (#383) 2026-08-29 20:40:16 -07:00
CLAUDE.md Link to MapLibre org AI policy (#317) 2026-04-22 20:54:47 -07:00
CODE-OF-CONDUCT.md Configure and run an auto formatter on all files (and enforce in CI) (#157) 2025-09-24 07:44:18 +00:00
CONTRIBUTING.md docs: simplify contributor and PR guidance (#399) 2026-10-03 16:11:37 -07:00
detekt.yml Flesh out turf KDoc (#264) 2025-10-12 22:17:08 -07:00
dprint.json Migrate docs to Starlight (#333) 2026-06-05 23:14:50 -07:00
gradle.properties [codex] Simplify publishing workflow (#337) 2026-06-06 14:03:19 -07:00
gradlew Bump gradle-wrapper from 9.5.1 to 9.6.0 (#352) 2026-06-22 17:05:16 +02:00
gradlew.bat Bump gradle-wrapper from 9.7.1 to 9.8.0 (#393) 2026-09-27 22:02:21 -07:00
hk.pkl Bump xmlutil from 0.91.3 to 1.0.0, Kotlin to 2.4.0 (#358) 2026-06-30 20:27:05 +02:00
LICENSE update code of conduct etc 2025-09-22 17:14:13 +02:00
mise.lock [codex] Simplify publishing workflow (#337) 2026-06-06 14:03:19 -07:00
mise.toml feat(units)!: expand unit catalogs and codegen their definitions (#395) 2026-10-03 22:40:55 -07:00
package.json Bump xmlutil from 0.91.3 to 1.0.0, Kotlin to 2.4.0 (#358) 2026-06-30 20:27:05 +02:00
pnpm-lock.yaml Migrate docs to Starlight (#333) 2026-06-05 23:14:50 -07:00
pnpm-workspace.yaml Migrate docs to Starlight (#333) 2026-06-05 23:14:50 -07:00
README.md feat(geohash): add Geohash cells and OsmShortlink (#383) 2026-08-29 20:40:16 -07:00
SECURITY.md streamline toolchain: mise to install tools, hk to orchestrate linters, dprint to orchestrate formatters (#306) 2026-04-04 05:06:09 +02:00
settings.gradle.kts feat(units)!: expand unit catalogs and codegen their definitions (#395) 2026-10-03 22:40:55 -07:00

Spatial K

Maven Central Version Snapshot Version License Kotlin Version Documentation API Reference Slack

Introduction

Spatial K is a set of libraries for working with geospatial data in Kotlin.

It includes:

  • GeoJSON implementation and DSL for building GeoJSON objects
  • Port of Turf.js geospatial analysis functions in pure Kotlin
  • Library for working with units of measure
  • GPX implementation
  • PMTiles v3 archive reader
  • Google Encoded Polyline Algorithm support
  • Geohash cells and OpenStreetMap shortlinks

Spatial K supports Kotlin Multiplatform and Java projects.

Getting Started

Add Spatial K to your project:

dependencies {
    implementation("org.maplibre.spatialk:geojson:VERSION")
    implementation("org.maplibre.spatialk:turf:VERSION")
    implementation("org.maplibre.spatialk:units:VERSION")
    implementation("org.maplibre.spatialk:gpx:VERSION")
    implementation("org.maplibre.spatialk:pmtiles:VERSION")
    implementation("org.maplibre.spatialk:polyline-encoding:VERSION")
    implementation("org.maplibre.spatialk:geohash:VERSION")
}

GeoJSON

val sf = buildFeature {
    geometry = Point(longitude = -122.4, latitude = 37.8)
    properties = buildJsonObject {
        put("name", "San Francisco")
    }
}

val json: String = sf.toJson()

Turf

val from = Position(longitude = -122.4, latitude = 37.8)
val to = Position(longitude = -74.0, latitude = 40.7)
val distance = distance(from, to)
val bearing = from.bearingTo(to)

Units

val distance = 5.kilometers
val inMeters = distance.inMeters     // 5000.0
val formatted = distance.toString()  // "5000 m"

GPX

val document = Document(
    metadata = Metadata(name = "My GPX File"),
    waypoints = listOf(
        Waypoint(latitude = 1.0, longitude = 2.0),
        Waypoint(latitude = 3.0, longitude = 4.0),
    ),
)
val gpxString = Gpx.encodeToString(document)

PMTiles

// Inside a suspend function or coroutine scope:
PmTiles.open(source).use { archive ->
    val header = archive.header
    val tile = archive.readDecompressedTile(z = 0, x = 0, y = 0)
}

Polyline Encoding

val positions = listOf(
    Position(longitude = -120.2, latitude = 38.5),
    Position(longitude = -120.95, latitude = 40.7),
)
val encoded = PolylineEncoding.encode(positions)
val decoded = PolylineEncoding.decode(encoded)

See the project site for more info.

Getting Involved

Join the #maplibre Slack channel at OSMUS (get an invite at https://slack.openstreetmap.us/).

Read the CONTRIBUTING.md guide to get familiar with how we do things around here.