LineSliceAlong fails when start and end are 0
const turf = require('@turf/turf');
const line = turf.lineString([[145,-37], [150, -37]]);
turf.lineSliceAlong(line, 0, 0);
Throws error Error: coordinates must be an array of two or more positions
https://runkit.com/stevebennett/turf-lineslicealong-line-0-0-fails
Maybe it's trivial, but my use case was progressively extending a line from 0% to 100% of an existing line feature. It blew up on the 0%.
@stevage Thanks for reporting. This is a tricky case, but I believe it is working as intended. A zero length linestring is not a valid simple feature geometry.
Hmm, I don't see anything in the GeoJSON spec prohibiting LineStrings consisting of the same position twice. Or maybe I misunderstood your meaning.
I think our lineSliceAlong implementation is only passing in a single coord in to turf.lineString() rather than a duplicate set of coords which is where the problem is. @stevage is correct in that I think a linestring with 2 duplicate points is valid, although the reality is that such a geometry is probably likely to cause issues in subsequent operations on it...
Turf additionally requires geometry to be simple feature compliant, which is more than the GeoJSON spec currently requires. This is due to limitations in some of the downstream geometry engines (JSTS), which do not support self intersections or overlapping ring vertices.
I did look at the OGC simple feature spec and was surprised when I didn't see anything about duplicate coords on a linestring. But yep take that a line with 0 length is likely to cause issues in a range of places.
I'm not sure that's a strong argument against ever returning a zero-length linestring. It's just up to the user to not pass that result to other places where it might cause problems. Just like any function that sometimes returns undefined, you could run into problems if you passed that undefined to some other function.
note: Reopening issue for debate.
We should look into how JSTS will handle this data. My original argument was:
which do not support self intersections or overlapping ring vertices.
... which I have given some more thought and realized that this would not apply to this case, since:
- LineStrings do allow self intersections.
- This is not about linear rings, and overlapping vertices are needed in cases, such as representing a traffic circle or a winding GPS path.
Throws error
Error: coordinates must be an array of two or more positions
The error message is correct, however, this points to abnormal behavior under the hood. This function should return a linestring with two duplicate coordinates.
Related reading:
https://github.com/locationtech/jts/pull/346
Here is a use case that I was debugging for quite a while today: I query some data from PostgreSQL into a NextJS app where I use turf. I added some simplification to the query to reduce the data. This simplification created a linestring with start and end being the same value, which is basically a point. According to LLMs that is valid behavior when using simplification in PostGIS(?)
My code is looking for the point in the center of the line which return the second 0 (because the line is 0 m long).
const l = turf.lineString([[-122.3116, 47.6623], [-122.3116, 47.6623]]);
const wayToHalf = turf.lineSliceAlong(l.geometry, 0, 0, { units: 'meters' })
console.log(wayToHalf)
// Error: coordinates must be an array of two or more positions