Skip to content

Commit 85b5c74

Browse files
committed
Reverted backward incompatible fix to nearestPointOnLine introduced by PR #2951, while still keeping lineSlice issue #2946 resolved with a temporary workaround.
1 parent 2669e6a commit 85b5c74

File tree

10 files changed

+114
-177
lines changed

10 files changed

+114
-177
lines changed

packages/turf-line-slice/index.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { getCoords, getType } from "@turf/invariant";
22
import { Coord, lineString as linestring } from "@turf/helpers";
33
import { nearestPointOnLine } from "@turf/nearest-point-on-line";
4-
import { Feature, LineString } from "geojson";
4+
import type { Feature, LineString, Point } from "geojson";
55

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

4545
const startVertex = nearestPointOnLine(line, startPt);
4646
const stopVertex = nearestPointOnLine(line, stopPt);
47+
48+
// Workaround until we can fix backwards incompatible nearestPointOnLine bug
49+
// #3016
50+
fixSegmentIndexBounds(line, startVertex);
51+
fixSegmentIndexBounds(line, stopVertex);
52+
4753
const ends =
48-
startVertex.properties.index <= stopVertex.properties.index
54+
startVertex.properties.segmentIndex <= stopVertex.properties.segmentIndex
4955
? [startVertex, stopVertex]
5056
: [stopVertex, startVertex];
5157
const clipCoords = [ends[0].geometry.coordinates];
5258
for (
53-
let i = ends[0].properties.index + 1;
54-
i < ends[1].properties.index + 1;
59+
let i = ends[0].properties.segmentIndex + 1;
60+
i < ends[1].properties.segmentIndex + 1;
5561
i++
5662
) {
5763
clipCoords.push(coords[i]);
@@ -60,5 +66,23 @@ function lineSlice(
6066
return linestring(clipCoords, line.type === "Feature" ? line.properties : {});
6167
}
6268

69+
function fixSegmentIndexBounds(
70+
line: Feature<LineString> | LineString,
71+
vertex: Feature<Point, { segmentIndex: number }>
72+
) {
73+
// There is a bug in nearestPointOnLine where the returned segmentIndex can
74+
// refer to a non-existent segment (overflows). Until we can fix that bug
75+
// (see https://github.com/Turfjs/turf/issues/3016) we adjust the
76+
// segmentIndex here to make sure it's in range.
77+
78+
let geometry: LineString = line.type === "Feature" ? line.geometry : line;
79+
80+
if (vertex.properties.segmentIndex >= geometry.coordinates.length - 1) {
81+
// segmentIndex refers to a non-existent segment beyond the end of the
82+
// lineString. Override it.
83+
vertex.properties.segmentIndex = geometry.coordinates.length - 2;
84+
}
85+
}
86+
6387
export { lineSlice };
6488
export default lineSlice;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"type": "FeatureCollection",
3+
"features": [
4+
{
5+
"type": "Feature",
6+
"properties": {},
7+
"geometry": {
8+
"type": "LineString",
9+
"coordinates": [
10+
[3, 0],
11+
[2, -1],
12+
[2, 2]
13+
]
14+
}
15+
},
16+
{
17+
"type": "Feature",
18+
"properties": {},
19+
"geometry": {
20+
"type": "Point",
21+
"coordinates": [2, 0]
22+
}
23+
},
24+
{
25+
"type": "Feature",
26+
"properties": {},
27+
"geometry": {
28+
"type": "Point",
29+
"coordinates": [2, 2]
30+
}
31+
}
32+
]
33+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"type": "FeatureCollection",
3+
"features": [
4+
{
5+
"type": "Feature",
6+
"properties": {},
7+
"geometry": {
8+
"type": "LineString",
9+
"coordinates": [
10+
[3, 0],
11+
[2, -1],
12+
[2, 2]
13+
]
14+
}
15+
},
16+
{
17+
"type": "Feature",
18+
"properties": {},
19+
"geometry": {
20+
"type": "Point",
21+
"coordinates": [2, 0]
22+
}
23+
},
24+
{
25+
"type": "Feature",
26+
"properties": {},
27+
"geometry": {
28+
"type": "Point",
29+
"coordinates": [2, 2]
30+
}
31+
},
32+
{
33+
"type": "Feature",
34+
"properties": {
35+
"stroke": "#f0f",
36+
"stroke-width": 6
37+
},
38+
"geometry": {
39+
"type": "LineString",
40+
"coordinates": [
41+
[2, 0],
42+
[2, 2]
43+
]
44+
}
45+
}
46+
]
47+
}

packages/turf-nearest-point-on-line/index.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
106106
}
107107

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

111110
for (let i = 0; i < coords.length - 1; i++) {
112111
//start - start of current line section
@@ -144,11 +143,9 @@ function nearestPointOnLine<G extends LineString | MultiLineString>(
144143
const segmentDistance = distance(start, intersectPos, options);
145144
closestPt = point(intersectPos, {
146145
lineStringIndex: lineStringIndex,
147-
// Legacy behaviour where index progresses to next segment if we
148-
// went with the end point this iteration. Though make sure we
149-
// only progress to the beginning of the next segment if one
150-
// actually exists.
151-
segmentIndex: wasEnd && i + 1 <= maxSegmentIndex ? i + 1 : i,
146+
// Legacy behaviour where index progresses to next segment # if we
147+
// went with the end point this iteration.
148+
segmentIndex: wasEnd ? i + 1 : i,
152149
totalDistance: totalDistance + segmentDistance,
153150
lineDistance: lineDistance + segmentDistance,
154151
segmentDistance: segmentDistance,

packages/turf-nearest-point-on-line/test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ test("turf-nearest-point-on-line - segmentIndex and pointDistance", (t) => {
333333
const pt = point([-92.110576, 41.040649]);
334334
const snapped = truncate(nearestPointOnLine(line, pt));
335335

336-
t.equal(snapped.properties.segmentIndex, 7, "properties.segmentIndex");
336+
t.equal(snapped.properties.segmentIndex, 8, "properties.segmentIndex");
337337
t.equal(
338338
Number(snapped.properties.pointDistance.toFixed(6)),
339339
0.823802,

packages/turf-nearest-point-on-line/test/in/end-point-1.geojson

Lines changed: 0 additions & 30 deletions
This file was deleted.

packages/turf-nearest-point-on-line/test/in/end-point-2.geojson

Lines changed: 0 additions & 29 deletions
This file was deleted.

packages/turf-nearest-point-on-line/test/out/end-point-1.geojson

Lines changed: 0 additions & 53 deletions
This file was deleted.

packages/turf-nearest-point-on-line/test/out/end-point-2.geojson

Lines changed: 0 additions & 52 deletions
This file was deleted.

packages/turf-nearest-point-on-line/test/out/multiLine1.geojson

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@
6868
"type": "Feature",
6969
"properties": {
7070
"lineStringIndex": 1,
71-
"segmentIndex": 20,
71+
"segmentIndex": 21,
7272
"totalDistance": 9479.011715,
7373
"lineDistance": 4800.716022,
7474
"segmentDistance": 173.221741,
7575
"pointDistance": 114.725451,
7676
"dist": 114.725451,
7777
"multiFeatureIndex": 1,
7878
"location": 9479.011715,
79-
"index": 20,
79+
"index": 21,
8080
"marker-color": "#F0F"
8181
},
8282
"geometry": {

0 commit comments

Comments
 (0)