diff --git a/README.md b/README.md
index b47d56ed..ac08df76 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,7 @@ Turf.js | Turf for Swift
[turf-length#length](https://turfjs.org/docs/#length) | `LineString.distance(from:to:)`
[turf-line-intersect#lineIntersect](https://turfjs.org/docs/#lineIntersect) | `intersection(_:_:)`
[turf-line-slice#lineSlice](https://turfjs.org/docs/#lineSlice) | `LineString.sliced(from:to:)`
-[turf-line-slice-along#lineSliceAlong](https://turfjs.org/docs/#lineSliceAlong) | `LineString.trimmed(from:distance:)`
+[turf-line-slice-along#lineSliceAlong](https://turfjs.org/docs/#lineSliceAlong) | `LineString.trimmed(from:to:)`
[turf-midpoint#midpoint](https://turfjs.org/docs/#midpoint) | `mid(_:_:)`
[turf-nearest-point-on-line#nearestPointOnLine](https://turfjs.org/docs/#nearestPointOnLine) | `LineString.closestCoordinate(to:)`
[turf-polygon-to-line#polygonToLine](https://turfjs.org/docs/#polygonToLine) | `LineString(_:)`
`MultiLineString(_:)`
diff --git a/Sources/Turf/Geometries/LineString.swift b/Sources/Turf/Geometries/LineString.swift
index 5e6a3871..09afb02b 100644
--- a/Sources/Turf/Geometries/LineString.swift
+++ b/Sources/Turf/Geometries/LineString.swift
@@ -78,9 +78,65 @@ extension LineString {
}
/**
- Returns the portion of the line string that begins at the given coordinate and extends the given distance along the line string.
+ Returns the portion of the line string that begins at the given start distance and extends the given stop distance along the line string.
- This method is roughly equivalent to the [turf-line-slice-along](https://turfjs.org/docs/#lineSliceAlong) package of Turf.js ([source code](https://github.com/Turfjs/turf/tree/master/packages/turf-line-slice-along/)), except that it accepts a starting position instead of a starting distance along the line string.
+ This method is equivalent to the [turf-line-slice-along](https://turfjs.org/docs/#lineSliceAlong) package of Turf.js ([source code](https://github.com/Turfjs/turf/tree/master/packages/turf-line-slice-along/)).
+ */
+ public func trimmed(from startDistance: LocationDistance, to stopDistance: LocationDistance) -> LineString? {
+ // The method is porting from https://github.com/Turfjs/turf/blob/5375941072b90d489389db22b43bfe809d5e451e/packages/turf-line-slice-along/index.js
+ guard startDistance >= 0.0 && stopDistance >= startDistance else { return nil }
+ let coordinates = self.coordinates
+ var traveled: LocationDistance = 0
+ var slice = [LocationCoordinate2D]()
+
+ for i in 0..= traveled && i == coordinates.endIndex - 1 {
+ break
+ } else if traveled > startDistance && slice.isEmpty {
+ let overshoot = startDistance - traveled
+ if overshoot == 0.0 {
+ slice.append(coordinates[i])
+ return LineString(slice)
+ }
+ let direction = coordinates[i].direction(to: coordinates[i - 1]) - 180
+ let interpolated = coordinates[i].coordinate(at: overshoot, facing: direction)
+ slice.append(interpolated)
+ }
+
+ if traveled >= stopDistance {
+ let overshoot = stopDistance - traveled
+ if overshoot == 0.0 {
+ slice.append(coordinates[i])
+ return LineString(slice)
+ }
+ let direction = coordinates[i].direction(to: coordinates[i - 1]) - 180
+ let interpolated = coordinates[i].coordinate(at: overshoot, facing: direction)
+ slice.append(interpolated)
+ return LineString(slice)
+ }
+
+ if traveled >= startDistance {
+ slice.append(coordinates[i])
+ }
+
+ if i == coordinates.count - 1 {
+ return LineString(slice)
+ }
+
+ traveled += distance(from: coordinates[i], to: coordinates[i + 1]) ?? 0.0
+ }
+
+ if traveled < startDistance { return nil }
+
+ if let last = coordinates.last {
+ return LineString([last, last])
+ }
+
+ return nil
+ }
+
+ /**
+ Returns the portion of the line string that begins at the given coordinate and extends the given distance along the line string.
*/
public func trimmed(from coordinate: LocationCoordinate2D, distance: LocationDistance) -> LineString? {
let startVertex = closestCoordinate(to: coordinate)
diff --git a/Tests/TurfTests/LineStringTests.swift b/Tests/TurfTests/LineStringTests.swift
index 6c98a261..8446925b 100644
--- a/Tests/TurfTests/LineStringTests.swift
+++ b/Tests/TurfTests/LineStringTests.swift
@@ -350,4 +350,64 @@ class LineStringTests: XCTestCase {
XCTAssertEqual(slicedCoordinates?.count, 2, "no duplicated coords")
XCTAssertNotEqual(slicedCoordinates?.first, slicedCoordinates?.last, "vertical slice should not collapse to first coordinate")
}
+
+ func testTrimmed() {
+ // https://github.com/Turfjs/turf/blob/5375941072b90d489389db22b43bfe809d5e451e/packages/turf-line-slice-along/test.js
+
+ // turf-line-slice-along -- line1
+ let coordinates = [
+ [113.99414062499999, 22.350075806124867],
+ [116.76269531249999, 23.241346102386135],
+ [117.7734375, 24.367113562651276],
+ [118.828125, 25.20494115356912],
+ [119.794921875, 26.78484736105119],
+ [120.80566406250001, 28.110748760633534],
+ [121.59667968749999, 29.49698759653577],
+ [121.59667968749999, 31.12819929911196],
+ [120.84960937499999, 32.84267363195431],
+ [119.83886718750001, 34.125447565116126],
+ [118.69628906249999, 35.31736632923788],
+ [121.4208984375, 36.80928470205937],
+ [122.82714843749999, 37.37015718405753]
+ ]
+ let line1 = LineString(coordinates.map{
+ CLLocationCoordinate2D(latitude: $0.last!, longitude: $0.first!)
+ })
+
+ var startDistance = 804672.0
+ var stopDistance = 1207008.0
+
+ var startPoint = line1.coordinateFromStart(distance: startDistance)
+ var endPoint = line1.coordinateFromStart(distance: stopDistance)
+ var sliced = line1.trimmed(from: startDistance, to: stopDistance)
+ XCTAssertNotNil(sliced, "should return valid lineString")
+ XCTAssertEqual(sliced!.coordinates.first!, startPoint)
+ XCTAssertEqual(sliced!.coordinates.last!, endPoint)
+
+ stopDistance = 2414016.0
+ endPoint = line1.coordinateFromStart(distance: stopDistance)
+ sliced = line1.trimmed(from: startDistance, to: stopDistance)
+ XCTAssertNotNil(sliced, "should return valid lineString")
+ XCTAssertEqual(sliced!.coordinates.first!, startPoint)
+ XCTAssertEqual(sliced!.coordinates.last!, endPoint)
+
+ startDistance = 8046720
+ stopDistance = 12874752.0
+ sliced = line1.trimmed(from: startDistance, to: stopDistance)
+ XCTAssertNil(sliced, "should return nil")
+
+ startDistance = line1.distance()!
+ stopDistance = startDistance + 100.0
+ startPoint = line1.coordinateFromStart(distance: startDistance)
+ endPoint = line1.coordinateFromStart(distance: stopDistance)
+ sliced = line1.trimmed(from: startDistance, to: stopDistance)
+ XCTAssertNotNil(sliced, "should return valid lineString")
+ XCTAssertEqual(sliced!.coordinates.first!, startPoint)
+ XCTAssertEqual(sliced!.coordinates.last!, endPoint)
+
+ startDistance = -0.376
+ stopDistance = 543.0
+ sliced = line1.trimmed(from: startDistance, to: stopDistance)
+ XCTAssertNil(sliced, "should return nil")
+ }
}