-
Notifications
You must be signed in to change notification settings - Fork 992
Description
@smallsaucepan I'm opening this separate issue as you suggested in #2951 (comment).
In short: The change made in #2951 broke my code π
Consider the following example:
const lineCoords = [[0, 0], [1, 2], [0, 4]];
const line = turf.lineString(lineCoords);
const pointA = turf.point([-1, 0]);
const pointB = turf.point([1, 1]);
const pointC = turf.point([2, 2]);
const pointD = turf.point([1, 3]);
const pointE = turf.point([-1, 4]);
const nearA = turf.nearestPointOnLine(line, pointA);
const nearB = turf.nearestPointOnLine(line, pointB);
const nearC = turf.nearestPointOnLine(line, pointC);
const nearD = turf.nearestPointOnLine(line, pointD);
const nearE = turf.nearestPointOnLine(line, pointE);Visualization:
Here is a side-by-side comparison of the index properties (or segmentIndex as it's called since v7.3.2) returned by the nearestPointOnLine function between Turf version 7.3.1 and 7.3.2:
| Point position | index in Turf 7.3.1 |
index/segmentIndex in Turf 7.3.2 |
|
|---|---|---|---|
| nearA | exactly on lineCoords[0] |
0 | 0 |
| nearB | between lineCoords[0] and lineCoords[1] |
0 | 0 |
| nearC | exactly on lineCoords[1] |
1 | 1 |
| nearD | between lineCoords[1] and lineCoords[2] |
1 | 1 |
| nearE | exactly on lineCoords[2] |
2 | 1 |
As you can see, the index when the nearest point falls on the final line point changed in Turf 7.3.2. This way, it is no longer possible to tell whether the nearest point is on the last line segment or at the end of the last line segment.
I don't want to get into too much detail, but let me just say that for various reasons, it is important for me to be able to recognize when the nearest point is at the end of the input line (or at the end of one of the lines of an input MultiLineString to be exact).
Looking at the documentation, I admit that the new behavior in Turf 7.3.2 arguably makes more sense and adheres more closely to the property description:
| * segmentIndex - point was found on the nth segment of the above LineString. Previously `index` |
Since the above line consist of three points and two line segments, it makes sense that the only possible segmentIndex values are 0 and 1 (and never 2). I'm therefore not advocating for the change made in #2951 to be reverted. But I still would like Turf to handle this edge case a bit better.
As a simple fix, I would propose to add a boolean property to the point returned by the nearestPointOnLine function that is true if and only if the nearest point exactly falls on the last point of the input line. We could name it isLastLinePoint or something like that.
A more sophisticated solution would be to come up with a system that also handles the intermediate segment "join points" better. For instance, one could argue that the point nearC in the above example that sits exactly between the two line segments should have the segmentIndex 0 instead of 1 (or the user should have the choice which behavior they prefer).
But I'm also open to other ideas or considerations that I might be overlooking π