Skip to content

From version 7.3.2 the nearestPointOnLine function returns a different segmentIndex when the nearest point is at end of the input lineΒ #3008

@EmilJunker

Description

@EmilJunker

@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:

Image

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 πŸ™‚

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions