From 0fdbc05ef215a5ef549dab2da971d6bcd3889c36 Mon Sep 17 00:00:00 2001 From: Sebastian Heeschen Date: Fri, 3 May 2024 22:12:00 +0200 Subject: [PATCH 1/2] Add turf envelope function --- .../dellisd/spatialk/geojson/GeoJson.kt | 2 +- .../dellisd/spatialk/turf/Measurement.kt | 18 ++++++ .../spatialk/turf/TurfMeasurementTest.kt | 55 ++++++++++++++++++- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/geojson/src/commonMain/kotlin/io/github/dellisd/spatialk/geojson/GeoJson.kt b/geojson/src/commonMain/kotlin/io/github/dellisd/spatialk/geojson/GeoJson.kt index cb1acb43..f8d12b8e 100644 --- a/geojson/src/commonMain/kotlin/io/github/dellisd/spatialk/geojson/GeoJson.kt +++ b/geojson/src/commonMain/kotlin/io/github/dellisd/spatialk/geojson/GeoJson.kt @@ -5,7 +5,7 @@ package io.github.dellisd.spatialk.geojson * * @property bbox An optional bounding box used to represent the limits of the object's geometry. */ -interface GeoJson { +sealed interface GeoJson { val bbox: BoundingBox? /** diff --git a/turf/src/commonMain/kotlin/io/github/dellisd/spatialk/turf/Measurement.kt b/turf/src/commonMain/kotlin/io/github/dellisd/spatialk/turf/Measurement.kt index 817099a9..a6d795e9 100644 --- a/turf/src/commonMain/kotlin/io/github/dellisd/spatialk/turf/Measurement.kt +++ b/turf/src/commonMain/kotlin/io/github/dellisd/spatialk/turf/Measurement.kt @@ -6,6 +6,7 @@ package io.github.dellisd.spatialk.turf import io.github.dellisd.spatialk.geojson.BoundingBox import io.github.dellisd.spatialk.geojson.Feature import io.github.dellisd.spatialk.geojson.FeatureCollection +import io.github.dellisd.spatialk.geojson.GeoJson import io.github.dellisd.spatialk.geojson.Geometry import io.github.dellisd.spatialk.geojson.GeometryCollection import io.github.dellisd.spatialk.geojson.LineString @@ -652,3 +653,20 @@ fun greatCircle(start: Position, end: Position, pointCount: Int = 100, antimerid } } + +@ExperimentalTurfApi +fun envelope(geoJson: GeoJson): Feature { + val coordinates = when (geoJson) { + is Feature -> geoJson.coordAll() + is FeatureCollection -> geoJson.coordAll() + is GeometryCollection -> geoJson.coordAll() + is Geometry -> geoJson.coordAll() + }.orEmpty() + + val bbox = geoJson.bbox ?: computeBbox(coordinates) + + return Feature( + geometry = bboxPolygon(bbox), + bbox = bbox + ) +} diff --git a/turf/src/commonTest/kotlin/io/github/dellisd/spatialk/turf/TurfMeasurementTest.kt b/turf/src/commonTest/kotlin/io/github/dellisd/spatialk/turf/TurfMeasurementTest.kt index d17dd883..a97c4aa1 100644 --- a/turf/src/commonTest/kotlin/io/github/dellisd/spatialk/turf/TurfMeasurementTest.kt +++ b/turf/src/commonTest/kotlin/io/github/dellisd/spatialk/turf/TurfMeasurementTest.kt @@ -3,13 +3,16 @@ package io.github.dellisd.spatialk.turf import io.github.dellisd.spatialk.geojson.BoundingBox +import io.github.dellisd.spatialk.geojson.Feature import io.github.dellisd.spatialk.geojson.LineString import io.github.dellisd.spatialk.geojson.MultiLineString -import io.github.dellisd.spatialk.geojson.Feature import io.github.dellisd.spatialk.geojson.Point import io.github.dellisd.spatialk.geojson.Polygon import io.github.dellisd.spatialk.geojson.Position +import io.github.dellisd.spatialk.geojson.dsl.featureCollection import io.github.dellisd.spatialk.geojson.dsl.geometryCollection +import io.github.dellisd.spatialk.geojson.dsl.lineString +import io.github.dellisd.spatialk.geojson.dsl.point import io.github.dellisd.spatialk.geojson.dsl.polygon import io.github.dellisd.spatialk.turf.utils.assertDoubleEquals import io.github.dellisd.spatialk.turf.utils.readResource @@ -186,4 +189,54 @@ class TurfMeasurementTest { greatCircle(start, antipodal) } } + + @Test + fun envelopeProcessesFeatureCollection() { + val fc = featureCollection { + feature( + geometry = point(102.0, 0.5) + ) + feature( + geometry = lineString { + point(102.0, -10.0) + point(103.0, 1.0) + point(104.0, 0.0) + point(130.0, 4.0) + } + ) + feature( + geometry = polygon { + ring { + point(102.0, -10.0) + point(103.0, 1.0) + point(104.0, 0.0) + point(130.0, 4.0) + point(20.0, 0.0) + point(101.0, 0.0) + point(101.0, 1.0) + point(100.0, 1.0) + point(100.0, 0.0) + } + } + ) + } + + val enveloped = envelope(fc) + + assertIs(enveloped.geometry, "geometry type should be Polygon") + assertEquals( + listOf( + listOf( + Position(20.0, -10.0), + Position(130.0, -10.0), + Position(130.0, 4.0), + Position(20.0, 4.0), + Position(20.0, -10.0), + ) + ), + (enveloped.geometry as Polygon).coordinates, + "positions should be correct" + ) + } + } From 4e573ccfca868c0595acd4201a5e3ee013eaf988 Mon Sep 17 00:00:00 2001 From: Sebastian Heeschen Date: Mon, 6 May 2024 12:38:05 +0200 Subject: [PATCH 2/2] Add doc to envelope --- .../kotlin/io/github/dellisd/spatialk/turf/Measurement.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/turf/src/commonMain/kotlin/io/github/dellisd/spatialk/turf/Measurement.kt b/turf/src/commonMain/kotlin/io/github/dellisd/spatialk/turf/Measurement.kt index a6d795e9..3651cf30 100644 --- a/turf/src/commonMain/kotlin/io/github/dellisd/spatialk/turf/Measurement.kt +++ b/turf/src/commonMain/kotlin/io/github/dellisd/spatialk/turf/Measurement.kt @@ -654,6 +654,11 @@ fun greatCircle(start: Position, end: Position, pointCount: Int = 100, antimerid } +/** + * Takes any [GeoJson] and returns a [Feature] containing a rectangular [Polygon] that encompasses all vertices. + * @param geoJson input containing any coordinates + * @return a rectangular [Polygon] feature that encompasses all vertices + */ @ExperimentalTurfApi fun envelope(geoJson: GeoJson): Feature { val coordinates = when (geoJson) {