Skip to content
Merged
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
32 changes: 28 additions & 4 deletions packages/turf-line-slice/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getCoords, getType } from "@turf/invariant";
import { Coord, lineString as linestring } from "@turf/helpers";
import { nearestPointOnLine } from "@turf/nearest-point-on-line";
import { Feature, LineString } from "geojson";
import type { Feature, LineString, Point } from "geojson";

/**
* Takes a {@link LineString|line}, a start {@link Point}, and a stop point
Expand Down Expand Up @@ -44,14 +44,20 @@ function lineSlice(

const startVertex = nearestPointOnLine(line, startPt);
const stopVertex = nearestPointOnLine(line, stopPt);

// Workaround until we can fix backwards incompatible nearestPointOnLine bug
// #3016
fixSegmentIndexBounds(line, startVertex);
fixSegmentIndexBounds(line, stopVertex);

const ends =
startVertex.properties.index <= stopVertex.properties.index
startVertex.properties.segmentIndex <= stopVertex.properties.segmentIndex
? [startVertex, stopVertex]
: [stopVertex, startVertex];
const clipCoords = [ends[0].geometry.coordinates];
for (
let i = ends[0].properties.index + 1;
i < ends[1].properties.index + 1;
let i = ends[0].properties.segmentIndex + 1;
i < ends[1].properties.segmentIndex + 1;
i++
) {
clipCoords.push(coords[i]);
Expand All @@ -60,5 +66,23 @@ function lineSlice(
return linestring(clipCoords, line.type === "Feature" ? line.properties : {});
}

function fixSegmentIndexBounds(
line: Feature<LineString> | LineString,
vertex: Feature<Point, { segmentIndex: number }>
) {
// There is a bug in nearestPointOnLine where the returned segmentIndex can
// refer to a non-existent segment (overflows). Until we can fix that bug
// (see https://github.com/Turfjs/turf/issues/3016) we adjust the
// segmentIndex here to make sure it's in range.

let geometry: LineString = line.type === "Feature" ? line.geometry : line;

if (vertex.properties.segmentIndex >= geometry.coordinates.length - 1) {
// segmentIndex refers to a non-existent segment beyond the end of the
// lineString. Override it.
vertex.properties.segmentIndex = geometry.coordinates.length - 2;
}
}

export { lineSlice };
export default lineSlice;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[3, 0],
[2, -1],
[2, 2]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [2, 0]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [2, 2]
}
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[3, 0],
[2, -1],
[2, 2]
]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [2, 0]
}
},
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [2, 2]
}
},
{
"type": "Feature",
"properties": {
"stroke": "#f0f",
"stroke-width": 6
},
"geometry": {
"type": "LineString",
"coordinates": [
[2, 0],
[2, 2]
]
}
}
]
}
9 changes: 3 additions & 6 deletions packages/turf-nearest-point-on-line/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
}

const coords: any = getCoords(line);
const maxSegmentIndex = coords.length - 2;

for (let i = 0; i < coords.length - 1; i++) {
//start - start of current line section
Expand Down Expand Up @@ -144,11 +143,9 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
const segmentDistance = distance(start, intersectPos, options);
closestPt = point(intersectPos, {
lineStringIndex: lineStringIndex,
// Legacy behaviour where index progresses to next segment if we
// went with the end point this iteration. Though make sure we
// only progress to the beginning of the next segment if one
// actually exists.
segmentIndex: wasEnd && i + 1 <= maxSegmentIndex ? i + 1 : i,
// Legacy behaviour where index progresses to next segment # if we
// went with the end point this iteration.
segmentIndex: wasEnd ? i + 1 : i,
totalDistance: totalDistance + segmentDistance,
lineDistance: lineDistance + segmentDistance,
segmentDistance: segmentDistance,
Expand Down
2 changes: 1 addition & 1 deletion packages/turf-nearest-point-on-line/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ test("turf-nearest-point-on-line - segmentIndex and pointDistance", (t) => {
const pt = point([-92.110576, 41.040649]);
const snapped = truncate(nearestPointOnLine(line, pt));

t.equal(snapped.properties.segmentIndex, 7, "properties.segmentIndex");
t.equal(snapped.properties.segmentIndex, 8, "properties.segmentIndex");
t.equal(
Number(snapped.properties.pointDistance.toFixed(6)),
0.823802,
Expand Down
30 changes: 0 additions & 30 deletions packages/turf-nearest-point-on-line/test/in/end-point-1.geojson

This file was deleted.

29 changes: 0 additions & 29 deletions packages/turf-nearest-point-on-line/test/in/end-point-2.geojson

This file was deleted.

53 changes: 0 additions & 53 deletions packages/turf-nearest-point-on-line/test/out/end-point-1.geojson

This file was deleted.

52 changes: 0 additions & 52 deletions packages/turf-nearest-point-on-line/test/out/end-point-2.geojson

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@
"type": "Feature",
"properties": {
"lineStringIndex": 1,
"segmentIndex": 20,
"segmentIndex": 21,
"totalDistance": 9479.011715,
"lineDistance": 4800.716022,
"segmentDistance": 173.221741,
"pointDistance": 114.725451,
"dist": 114.725451,
"multiFeatureIndex": 1,
"location": 9479.011715,
"index": 20,
"index": 21,
"marker-color": "#F0F"
},
"geometry": {
Expand Down