Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Transformation - circle #139

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.github.dellisd.spatialk.turf

import io.github.dellisd.spatialk.geojson.LineString
import io.github.dellisd.spatialk.geojson.Point
import io.github.dellisd.spatialk.geojson.Polygon
import io.github.dellisd.spatialk.geojson.Position

/**
Expand All @@ -14,7 +16,7 @@ import io.github.dellisd.spatialk.geojson.Position
* @param sharpness a measure of how curvy the path should be between splines
* @return A [LineString] containing a curved line around the positions of the input line
*/
@OptIn(ExperimentalTurfApi::class)
@ExperimentalTurfApi
public fun bezierSpline(line: LineString, duration: Int = 10_000, sharpness: Double = 0.85): LineString =
LineString(bezierSpline(line.coordAll(), duration, sharpness))

Expand Down Expand Up @@ -134,3 +136,26 @@ public fun bezierSpline(coords: List<Position>, duration: Int = 10_000, sharpnes

return positions
}

/**
* Takes a [Point] and calculates the circle polygon given a radius in degrees, radians, miles, or kilometers; and steps
* for precision.
*
* @param center center point of circle
* @param radius radius of the circle defined in [units]
* @param steps number of steps, must be at least four. Default is 64
* @param units unit of [radius], default is [Units.Kilometers]
*/
@ExperimentalTurfApi
public fun circle(center: Point, radius: Double, steps: Int = 64, units: Units = Units.Kilometers): Polygon {
require(steps >= 4) { "circle needs to have four or more coordinates." }
require(radius > 0) { "radius must be a positive value" }
val coordinates = (0..steps).map { step ->
destination(center.coordinates, radius, (step * -360) / steps.toDouble(), units)
}
val ring = coordinates.plus(coordinates.first())
return Polygon(
coordinates = listOf(ring),
bbox = computeBbox(ring)
)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package io.github.dellisd.spatialk.turf

import io.github.dellisd.spatialk.geojson.Feature
import io.github.dellisd.spatialk.geojson.FeatureCollection
import io.github.dellisd.spatialk.geojson.LineString
import io.github.dellisd.spatialk.geojson.Point
import io.github.dellisd.spatialk.turf.utils.readResource
import kotlinx.serialization.json.double
import kotlinx.serialization.json.jsonPrimitive
import kotlin.test.Test
import kotlin.test.assertEquals

Expand Down Expand Up @@ -37,4 +41,19 @@ class TransformationTest {

assertEquals(expectedOut.geometry, bezierSpline(feature.geometry as LineString))
}

@Test
fun testCircle() {
val point = Feature.fromJson(readResource("transformation/circle/in/circle1.json"))
val expectedOut = FeatureCollection.fromJson(readResource("transformation/circle/out/circle1.json"))

val (_, expectedCircle) = expectedOut.features

val circle = circle(
center = point.geometry as Point,
radius = point.properties["radius"]?.jsonPrimitive?.double ?: 0.0,
)

assertEquals(expectedCircle.geometry, circle)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"type": "Feature",
"properties": {
"radius": 5
},
"geometry": {
"type": "Point",
"coordinates": [-75.343, 39.984]
}
}
299 changes: 299 additions & 0 deletions turf/src/commonTest/resources/transformation/circle/out/circle1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-75.343,
39.984
]
},
"properties": {
"radius": 5
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"bbox": [
-75.40168521055865,
39.93903398181377,
-75.28431478944134,
40.02896601818623
],
"coordinates": [
[
[
-75.343,
40.02896601818623
],
[
-75.34875592857028,
40.02874935221753
],
[
-75.35445631564411,
40.02810144502913
],
[
-75.36004615881171,
40.02702854848104
],
[
-75.36547152848289,
40.0255410148978
],
[
-75.37068009096993,
40.02365319660857
],
[
-75.37562161573996,
40.02138330670212
],
[
-75.38024846182591,
40.01875324237723
],
[
-75.38451603860885,
40.01578837263805
],
[
-75.38838323645888,
40.01251729243424
],
[
-75.39181282304071,
40.00897154567282
],
[
-75.39477180145282,
40.00518531983158
],
[
-75.39723172676842,
40.00119511517658
],
[
-75.3991689779784,
39.99703939182863
],
[
-75.40056498279498,
39.99275819813223
],
[
-75.40140639325509,
39.98839278395333
],
[
-75.40168521055865,
39.983985202669075
],
[
-75.40139885808249,
39.9795779057111
],
[
-75.40055020202162,
39.97521333358458
],
[
-75.39914751961999,
39.970933507307144
],
[
-75.3972044154561,
39.966779624195745
],
[
-75.39473968674338,
39.96279166187577
],
[
-75.39177713908293,
39.95900799429653
],
[
-75.38834535456607,
39.95546502341165
],
[
-75.38447741456031,
39.9521968300236
],
[
-75.38021057992215,
39.94923484710077
],
[
-75.37558593176193,
39.94660755865401
],
[
-75.37064797623403,
39.94434022701197
],
[
-75.36544421714193,
39.942454651060615
],
[
-75.36002470042686,
39.94096895771676
],
[
-75.35444153485052,
39.939897428590044
],
[
-75.34874839338673,
39.93925036345563
],
[
-75.343,
39.93903398181377
],
[
-75.33725160661326,
39.93925036345563
],
[
-75.33155846514948,
39.939897428590044
],
[
-75.32597529957314,
39.94096895771676
],
[
-75.32055578285807,
39.942454651060615
],
[
-75.31535202376598,
39.94434022701197
],
[
-75.31041406823807,
39.94660755865401
],
[
-75.30578942007786,
39.94923484710077
],
[
-75.3015225854397,
39.9521968300236
],
[
-75.29765464543392,
39.95546502341165
],
[
-75.29422286091707,
39.95900799429653
],
[
-75.29126031325661,
39.96279166187577
],
[
-75.2887955845439,
39.966779624195745
],
[
-75.28685248038002,
39.970933507307144
],
[
-75.28544979797837,
39.97521333358458
],
[
-75.2846011419175,
39.9795779057111
],
[
-75.28431478944134,
39.983985202669075
],
[
-75.28459360674492,
39.98839278395333
],
[
-75.28543501720503,
39.99275819813223
],
[
-75.2868310220216,
39.99703939182863
],
[
-75.28876827323158,
40.00119511517658
],
[
-75.29122819854717,
40.00518531983158
],
[
-75.29418717695928,
40.00897154567282
],
[
-75.29761676354111,
40.01251729243424
],
[
-75.30148396139116,
40.01578837263805
],
[
-75.30575153817409,
40.01875324237723
],
[
-75.31037838426005,
40.02138330670212
],
[
-75.31531990903008,
40.02365319660857
],
[
-75.32052847151711,
40.0255410148978
],
[
-75.32595384118828,
40.02702854848104
],
[
-75.33154368435589,
40.02810144502913
],
[
-75.33724407142972,
40.02874935221753
],
[
-75.343,
40.02896601818623
],
[
-75.343,
40.02896601818623
]
]
]
},
"properties": {}
}
]
}
Loading