diff --git a/packages/turf-line-slice/test.ts b/packages/turf-line-slice/test.ts index b52db05549..07d10a1489 100644 --- a/packages/turf-line-slice/test.ts +++ b/packages/turf-line-slice/test.ts @@ -59,3 +59,31 @@ test("turf-nearest-point-on-line -- issue 2023", (t) => { ); t.end(); }); + +test("issue 2946 - lineSlice didn't introduce duplicate points", (t) => { + // Test case copied from https://github.com/Turfjs/turf/issues/2946 + // Values rounded to lower precision for realism. Same behaviour as + // originally reported though. + const startPt = point([2, 0]); + const endPt = point([2, 2]); + const line = lineString([ + [2.999848, 0.000152], + [2, -1], + [2, 2], + ]); + + const r1 = lineSlice(startPt, endPt, line); + t.equal( + r1.geometry.coordinates.length, + 2, + "Two points only in the linestring" + ); + + // This part of the issue report should have already been fixed by the + // recent PR #2940. + t.doesNotThrow(() => { + const r2 = lineSlice(startPt, endPt, r1); + }, "Does not throw when called again on first result"); + + t.end(); +}); diff --git a/packages/turf-line-slice/test/out/route2.geojson b/packages/turf-line-slice/test/out/route2.geojson index d86ab51f36..174265e6c1 100644 --- a/packages/turf-line-slice/test/out/route2.geojson +++ b/packages/turf-line-slice/test/out/route2.geojson @@ -6355,7 +6355,6 @@ [-112.622281, 45.973317], [-112.622078, 45.970234], [-112.619831, 45.970225], - [-112.614288, 45.970203], [-112.614288, 45.970203] ] } diff --git a/packages/turf-nearest-point-on-line/index.ts b/packages/turf-nearest-point-on-line/index.ts index 231517e71c..3fdd161e0b 100644 --- a/packages/turf-nearest-point-on-line/index.ts +++ b/packages/turf-nearest-point-on-line/index.ts @@ -75,6 +75,7 @@ function nearestPointOnLine( lines, function (line: any, _featureIndex: number, multiFeatureIndex: number) { 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 @@ -117,9 +118,11 @@ function nearestPointOnLine( ...intersectPt, properties: { ...intersectPt.properties, - // Legacy behaviour where index progresses to next segment # if we - // went with the end point this iteration. - index: wasEnd ? i + 1 : i, + // 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. + index: wasEnd && i + 1 <= maxSegmentIndex ? i + 1 : i, }, }; } diff --git a/packages/turf-nearest-point-on-line/test.ts b/packages/turf-nearest-point-on-line/test.ts index 9dec50f98b..7fe8459414 100644 --- a/packages/turf-nearest-point-on-line/test.ts +++ b/packages/turf-nearest-point-on-line/test.ts @@ -48,7 +48,7 @@ test("turf-nearest-point-on-line", (t) => { if (process.env.REGEN) writeJsonFileSync(directories.out + filename, results); - t.deepEqual(loadJsonFileSync(directories.out + filename), results, name); + t.deepEqual(results, loadJsonFileSync(directories.out + filename), name); } t.end(); }); @@ -320,7 +320,7 @@ test("turf-nearest-point-on-line - check dist and index", (t) => { const pt = point([-92.110576, 41.040649]); const snapped = truncate(nearestPointOnLine(line, pt)); - t.equal(snapped.properties.index, 8, "properties.index"); + t.equal(snapped.properties.index, 7, "properties.index"); t.equal( Number(snapped.properties.dist.toFixed(6)), 0.823802, diff --git a/packages/turf-nearest-point-on-line/test/in/end-point-1.geojson b/packages/turf-nearest-point-on-line/test/in/end-point-1.geojson new file mode 100644 index 0000000000..670195d226 --- /dev/null +++ b/packages/turf-nearest-point-on-line/test/in/end-point-1.geojson @@ -0,0 +1,30 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "description": "Result index should be 2 as there is a third segment and matches to an endpoint bump to the start of the next segment" + }, + "geometry": { + "coordinates": [ + [151.12342, -29.776038], + [151.112785, -29.783069], + [151.119935, -29.764135], + [151.107173, -29.768495] + ], + "type": "LineString" + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "green" + }, + "geometry": { + "coordinates": [151.12207, -29.761332], + "type": "Point" + } + } + ] +} diff --git a/packages/turf-nearest-point-on-line/test/in/end-point-2.geojson b/packages/turf-nearest-point-on-line/test/in/end-point-2.geojson new file mode 100644 index 0000000000..74e27532a9 --- /dev/null +++ b/packages/turf-nearest-point-on-line/test/in/end-point-2.geojson @@ -0,0 +1,29 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "description": "Result index should be 1 as there is no later segment to bump the index to." + }, + "geometry": { + "coordinates": [ + [151.12342, -29.776038], + [151.112785, -29.783069], + [151.119935, -29.764135] + ], + "type": "LineString" + } + }, + { + "type": "Feature", + "properties": { + "marker-color": "green" + }, + "geometry": { + "coordinates": [151.12207, -29.761332], + "type": "Point" + } + } + ] +} diff --git a/packages/turf-nearest-point-on-line/test/out/end-point-1.geojson b/packages/turf-nearest-point-on-line/test/out/end-point-1.geojson new file mode 100644 index 0000000000..1174378897 --- /dev/null +++ b/packages/turf-nearest-point-on-line/test/out/end-point-1.geojson @@ -0,0 +1,47 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "description": "Result index should be 2 as there is a third segment and matches to an endpoint bump to the start of the next segment" + }, + "geometry": { + "coordinates": [ + [151.12342, -29.776038], + [151.112785, -29.783069], + [151.119935, -29.764135], + [151.107173, -29.768495] + ], + "type": "LineString" + } + }, + { + "type": "Feature", + "properties": { "stroke": "#F00", "stroke-width": 6 }, + "geometry": { + "type": "LineString", + "coordinates": [ + [151.119935, -29.764135], + [151.12207, -29.761332] + ] + } + }, + { + "type": "Feature", + "properties": { "marker-color": "green" }, + "geometry": { "coordinates": [151.12207, -29.761332], "type": "Point" } + }, + { + "type": "Feature", + "properties": { + "dist": 0.373652, + "multiFeatureIndex": 0, + "location": 3.505821, + "index": 2, + "marker-color": "#F0F" + }, + "geometry": { "type": "Point", "coordinates": [151.119935, -29.764135] } + } + ] +} diff --git a/packages/turf-nearest-point-on-line/test/out/end-point-2.geojson b/packages/turf-nearest-point-on-line/test/out/end-point-2.geojson new file mode 100644 index 0000000000..224c211819 --- /dev/null +++ b/packages/turf-nearest-point-on-line/test/out/end-point-2.geojson @@ -0,0 +1,46 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "description": "Result index should be 1 as there is no later segment to bump the index to." + }, + "geometry": { + "coordinates": [ + [151.12342, -29.776038], + [151.112785, -29.783069], + [151.119935, -29.764135] + ], + "type": "LineString" + } + }, + { + "type": "Feature", + "properties": { "stroke": "#F00", "stroke-width": 6 }, + "geometry": { + "type": "LineString", + "coordinates": [ + [151.119935, -29.764135], + [151.12207, -29.761332] + ] + } + }, + { + "type": "Feature", + "properties": { "marker-color": "green" }, + "geometry": { "coordinates": [151.12207, -29.761332], "type": "Point" } + }, + { + "type": "Feature", + "properties": { + "dist": 0.373652, + "multiFeatureIndex": 0, + "location": 3.505821, + "index": 1, + "marker-color": "#F0F" + }, + "geometry": { "type": "Point", "coordinates": [151.119935, -29.764135] } + } + ] +} diff --git a/packages/turf-nearest-point-on-line/test/out/multiLine1.geojson b/packages/turf-nearest-point-on-line/test/out/multiLine1.geojson index b6765f1fe4..bafcee3087 100644 --- a/packages/turf-nearest-point-on-line/test/out/multiLine1.geojson +++ b/packages/turf-nearest-point-on-line/test/out/multiLine1.geojson @@ -68,7 +68,7 @@ "type": "Feature", "properties": { "dist": 114.725451, - "index": 21, + "index": 20, "multiFeatureIndex": 1, "location": 9479.011715, "marker-color": "#F0F"