Skip to content

Releases: maplibre/spatial-k

v0.5.0

25 Oct 08:12
8259a8c

Choose a tag to compare

What's Changed

Full Changelog: v0.4.0...v0.5.0

v0.4.0

14 Oct 05:50
a4cd0de

Choose a tag to compare

This release represents a revival and overhaul of the library with adoption into the MapLibre org and significant breaking changes for better type safety, a more idiomatic Kotlin API, and improved Java interoperability.

Contributors

@sargunv @jgillich @westnordost @elcolto @CommanderStorm @dellisd @Fabi755

Special thanks to @dellisd for originally creating and maintaining Spatial K.

Overview

Warning

Nearly the entire public API surface has been revised with significant breaking changes from v0.3.0, so the breaking changes aren't called out explicitly in this list.

  • New Maven coordinates from io.github.dellisd to org.maplibre
  • Package restructuring from io.github.dellisd to org.maplibre
  • Expanded Kotlin Multiplatform support including WASM targets and all native platforms
  • Improvements to GeoJSON type safety with generics and union types
  • GeoJSON DSL overhaul with builder-style API and Java-compatible builders
  • New units module for type-safe measures and unit conversions
  • Turf module API revised to be more Kotlin idiomatic with extension functions and new naming conventions and signatures.
  • Additional Turf.js functions ported.

Changes

Maven Coordinates

The library has moved from io.github.dellisd to org.maplibre:

// Before (v0.3.0)
dependencies {
    implementation("io.github.dellisd.spatialk:geojson:0.3.0")
    implementation("io.github.dellisd.spatialk:turf:0.3.0")
}

// After (v0.4.0)
dependencies {
    implementation("org.maplibre.spatialk:geojson:0.4.0")
    implementation("org.maplibre.spatialk:turf:0.4.0")
    implementation("org.maplibre.spatialk:units:0.4.0")  // new module
}

Package Restructuring

All packages have been renamed from io.github.dellisd.spatialk to org.maplibre.spatialk:

// Before (v0.3.0)
import io.github.dellisd.spatialk.geojson.*
import io.github.dellisd.spatialk.turf.*

// After (v0.4.0)
import org.maplibre.spatialk.geojson.*
import org.maplibre.spatialk.turf.*

Additional Kotlin Multiplatform Support

Spatial K now supports all Kotlin Multiplatform targets:

JavaScript & WebAssembly:

  • JavaScript (Browser and Node.js)
  • (NEW) WebAssembly/JS (Browser, Node.js, and D8)
  • (NEW) WebAssembly/WASI (Node.js)

Native Platforms:

  • Tier 1: macOS (ARM64), iOS (ARM64 and Simulator ARM64)
  • Tier 2: macOS (x64), iOS (x64), Linux (x64 and ARM64), watchOS (Simulator ARM64, x64, ARM32, and ARM64), tvOS (Simulator ARM64, x64, and ARM64)
  • (NEW) Tier 3: Windows (x64 via mingw), Android Native (ARM32, ARM64, x86, and x64), watchOS Device (ARM64)

GeoJSON DSL Overhaul

The GeoJSON DSL has been completely redesigned with a builder-style API (#253):

// Before (v0.3.0)
val feature = feature(
    geometry = lineString {
        +lngLat(0.0, 0.0)
        +lngLat(1.0, 1.0)
    }
) {
    put("name", "Example")
}

// After (v0.4.0)
val feature = buildFeature {
    geometry = lineStringOf(
        Position(0.0, 0.0),
        Position(1.0, 1.0),
    )
    properties = buildJsonObject {
        put("name", "Example")
    }
}

The underlying builders are now also usable in Java:

FeatureBuilder<LineString, JsonObject> builder = 
    new FeatureBuilder<>(
        new LineString(new Position(0.0, 0.0), new Position(1.0, 1.0)),
        null
    );
Feature<LineString, JsonObject> feature = builder.build();

Units System Replaced

The old Units enum has been replaced with a type-safe units module inspired by kotlin.time.Duration (#185):

// Before (v0.3.0)
val distance = distance(point1, point2, Units.KILOMETERS)

// After (v0.4.0)
val distance: Length = distance(point1, point2)
val km = distance.inKilometers

Length, Area, Rotation, and Bearing are Kotlin value classes, so they're not available in Java. Java users can use the convert helper from Utils to convert between units as double values:

double distanceKm = Utils.convert(
    Measurement.distance(point1, point2, Meters),
    Meters,
    Kilometers
);

Turf API Changes

  • Many Turf functions are now extension functions
  • Many Turf functions have been renamed to follow Kotlin naming conventions
  • Input and output formats have been standardized to prefer the simplest type that serves the purpose of the function. In practice, this means most functions operate directly on Geometry, not Feature.
  • Some new functions have been added to aid in conversions between GeoJSON types.
  • Functions have been reorganized by package.

In Java, Turf functions are organized as static methods by package (e.g., Measurement.distance(), Transformation.circle()).

// Before (v0.3.0)
val center = center(featureCollection)
val bbox = bbox(geometry)

// After (v0.4.0)
val center = featureCollection.center()
val bbox = geometry.computeBbox()

New Turf Functions

Many new geospatial analysis functions have been ported from Turf.js:

Measurement:

  • envelope - Calculate bounding envelope (#134)
  • rhumbDistance - Calculate rhumb line distance (#148)

Transformation:

  • circle - Generate circle polygons (#139)
  • simplify - Simplify geometries (#149)

Feature Conversion:

  • combine - Combine geometries (#242)
  • explode - Explode features into points (#243)
  • Conversion functions: lineToPolygon, polygonToLine (#254)

Miscellaneous:

  • pointsWithinPolygon - Spatial join operations (#257)
  • nearestPoint - Find nearest points (#256)
  • lineSliceAlong - Slice LineStrings by distance (#255)

Generic Geometry Support

GeoJSON types GeometryCollection, FeatureCollection, and Feature are now generic on the type of geometry they contain. FeatureCollection and Feature are also generic on the type of their properties object.

For dynamically typed properties, use JsonObject?:

val feature = Feature.fromJson<Geometry?, JsonObject?>(json)

Full Changelog

For a complete list of changes, see: v0.3.0...v0.4.0

0.3.0

19 Feb 21:58

Choose a tag to compare

What's Changed

Full Changelog: 0.2.1...0.3.0

0.2.1

16 Apr 22:51

Choose a tag to compare

Changes

  • Make fromJson(JsonObject) functions consistently public (some were marked internal).
  • Fixed issues with tabs on project site
  • Use Dokka HTML documentation format

0.2.0

16 Apr 04:01

Choose a tag to compare

Breaking Changes

  • New serialization APIs
    toFeature and toGeometryOrNull functions replaced with fromJson and fromJsonOrNull functions.
// Old (0.1.1):
val feature: Feature = "{...}".toFeature()
println(feature.json)

val point = "{not a point}".toGeometryOrNull<Point>()

// New (0.2.0):
val feature: Feature = Feature.fromJson("{...}")
println(feature.json())

val point = Point.fromJsonOrNull("{not a point}")
  • Geometry DSLs simplified to reduce how often the unary plus operator is used
// Old (0.1.1):
multiLineString {
  +lineString {
    +lngLat(45.0, 45.0)
    +lngLat(0.0, 0.0)
    +lngLat(74.0, -43.2)
  }
  +someOtherLineString
}

// New (0.2.0):
multiLineString {
  lineString {
    point(45.0, 45.0)
    point(0.0, 0.0)
    +lngLat(74.0, -43.2) // unary plus can still be used, but no longer required
  }
  +someOtherLineString
}
  • Feature DSL simplified
// Old (0.1.1)
feature {
  geometry = point(0.0, 0.0)
  id = "sample"
  properties {
    "name" to "Sample"
    "size" to 6.2
  }
}

// New (0.2.0)
feature(geometry = point(0.0, 0.0), id = "sample") { // this: PropertiesBuilder
  put("name", "Sample")
  put("size", 6.2)
}

Performance Improvements

Serialization performance has been significantly improved. A new "fast" serialization method is now available when encoding GeoJSON objects directly to a JSON string through the GeoJson.json() function. Serializing through kotlinx.serialization as normal is also now much faster.

This table outlines the improvements based on benchmarks taken before and after the serialization changes when serializing a FeatureCollection with 15,000 features:

Encoding (ms/op, lower is better)

Target Old (0.1.0) New (kotlinx, 0.2.0) New (fast, 0.2.0)
JVM 834.176 250.776 71.450
JS 3287.40 986.504 178.458
Native (linuxX64) 5624.209 1073.703 326.828

Decoding (ms/op, lower is better)

Target Old (0.1.0) New (0.2.0)
JVM 77.700 88.444
JS 423.472 383.339
Native (linuxX64) 993.008 652.600

See BENCHMARK for more details.

New Turf Ports

0.1.1

03 Jun 04:36

Choose a tag to compare

Fixes a publishing issue.

0.1.0

03 Jun 04:09

Choose a tag to compare

Initial (non-snapshot) release of Spatial K.
Full documentation available on the project site.

GeoJson

Includes an implementation of GeoJson in Kotlin, with serialization support via kotlinx.serialization, along with a Kotlin DSL for constructing geometry, features, and feature collections.

With only a couple of exceptions, the API for the GeoJson implementation is considered stable.

Turf

A set of Turf functions ported for Kotlin Multiplatform are available in an experimental state.

The following functions are available in this release:

  • along
  • area
  • bbox
  • bboxPolygon
  • bearing
  • destination
  • distance
  • length
  • midpoint
  • lineIntersect (Partially implemented)
  • lineSlice
  • nearestPointOnLine
  • bearingToAzimuth
  • convertArea
  • convertLength
  • lengthToRadians
  • lengthToDegrees
  • radiansToLength

Turf helper functions (for constructing geometry/features) are available as the GeoJson DSL.

For full documentation on the available functions, see the project site.