Skip to content

Conversation

@EmilJunker
Copy link
Contributor

@EmilJunker EmilJunker commented Apr 7, 2025

This adds a multiFeatureLocation property to the points returned by the nearestPointOnLine function. If there is just one LineString, then this will be the same as the existing location property. But if you pass a MultiLineString, this will tell you the distance along the line between the start of the MultiLineString where the closest point was found and the closest point itself. See #2753 for an example why this is useful.

This PR adds the following new properties to the returned nearest point:

lineStringIndex: same as current multiFeatureIndex property
segmentIndex: same as current index property
totalDistance: same as current location property
lineDistance: new property I requested in #2753
segmentDistance: new property suggested in #2867 (comment)
pointDistance: same as current dist property

The original properties are kept for backwards compatibility, but they can be easily removed later.

Closes #2753.

Please provide the following when creating a PR:

  • Meaningful title, including the name of the package being modified.
  • Summary of the changes.
  • Heads up if this is a breaking change.
  • Any issues this resolves.
  • Confirmation you've read the steps for preparing a pull request.

@EmilJunker
Copy link
Contributor Author

@smallsaucepan I just resolved a merge conflict so this PR can be cleanly merged again. I would appreciate if this was included in the next release. Please let me know if anything is missing from it or holding it back.

@EmilJunker EmilJunker force-pushed the nearest-point-on-line-multi-feature-location branch from fb75782 to 1f0c122 Compare November 17, 2025 08:43
@EmilJunker
Copy link
Contributor Author

@smallsaucepan I have again resolved any merge conflicts of this PR. It would be great if this feature could be included in the upcoming 7.3.0 release.

@smallsaucepan
Copy link
Member

Oh @EmilJunker! Missed the release by just a few minutes. Will review and make sure we get into the next version 👍

@smallsaucepan
Copy link
Member

Have been reviewing your PR (looks good!) and I think I gave you bad advice earlier. I'm not sure any more multiFeatureLOCATION is the best choice. Other functions use distance or a variation when describing how far along a line you've gone (see along).

I started wondering if any other existing properties don't make sense ...

  • index: closest point was found on nth line part
  • multiFeatureIndex: closest point was found on the nth line of the MultiLineString
  • dist: distance between pt and the closest point
  • location: distance along the line between start and the closest point

If we could start fresh, do you think the options below would be more clear or meaningful?

  • multiFeatureIndex: unchanged closest point was found on the nth line of the MultiLineString
  • index: unchanged closest point was found on nth line part
  • multiFeatureDistance: renamed what location currently provides, distance from the absolute start of the multilinestring
  • distance: new your parameter, distance from the start of the current linestring
  • ptDistance: renamed what dist currently provides, distance to the input point

Trying to establish a plan before we go further, and would appreciate your thoughts on it.

@EmilJunker
Copy link
Contributor Author

Thank you for the review. I agree with you that the current naming of the properties doesn't really make sense and that this would be a good opportunity to fix that. The fact that the location describes the distance along the line while dist is the distance to the closest point really confused me when I started using the nearestPointOnLine function.

I also mostly agree with your suggested new names. I also agree with you that (going by my current implementation) multiFeatureLocation and location should basically switch roles since the former is probably more useful in practice than the latter.

However, I think I would prefer "pointDistance" over "ptDistance" as a new name for "dist", because I'm generally not too fond of acronyms in source code. We aren't writing C++ here 😉 .

Maybe the function parameter name could also be changed from "pt" to "point" while we are at it. But turf functions seem to be a bit inconsistent in that regard, e.g. pointToPolygonDistance has a "point" param while pointToLineDistance has a "pt" param.

To make it even clearer that the distance is measured along the line, we could also call the other properties "lineDistance" and "multiFeatureLineDistance".

In conclusion, I think the closest point should have the following properties:

  • multiFeatureIndex: closest point was found on the nth line of the MultiLineString
  • index: closest point was found on the nth line part
  • multiFeatureLineDistance: distance along the line from the absolute start of the MultiLineString
  • lineDistance: distance along the line from the start of the line where the closest point was found
  • pointDistance: distance to the input point

I'd be happy to make the necessary naming changes as part of this pull request. My only concern is that this would be a breaking change, thus possibly deferring the release of this feature. Can you guarantee that it would still be included in the next turf release even with this breaking change?

@smallsaucepan
Copy link
Member

Oh it would totally be a breaking change. What we can do here though is come up with an end goal, and the plan for a smooth transition. This PR could be the first non-breaking step, and then we deprecate and phase out at a major release with later PRs. From the looks of it we'd be able to introduce new properties without changing the behaviour of existing ones.

Going back to a totally clean slate, what does each parameter really refer to?

  • multiFeatureIndex is the lineStringIndex (the index into the possible MultiLineString input, always 0 for a simple LineString)
  • index is the segmentIndex of the linestring feature (referred to by featureIndex)
  • location is the multiLineStringDistance (same as below for a single LineString input)
  • your new prop is the lineStringDistance (or the distance along the segment identified by lineStringIndex)
  • another theoretical prop could then be segmentDistance (or the distance along the segment identified by segmentIndex. Not suggesting adding it, just that the naming scheme leaves room for it)

This naming is a departure from the way it's been done so far, though here's my thinking - the index is named after the type of item it points to, rather than the name of the container.

team of people -> personIndex
bag of apples -> appleIndex
multiLineString of lineStrings -> lineStringIndex

To visualise:

issue-2867-terminology

Agree it would be good to have some consistency around pt / point too. Considerations might be elements where we pass in multiple points, and possible clashes with the point() function. Nothing else I can think of better describes the intent here though - target point? Origin point?

@EmilJunker
Copy link
Contributor Author

I see you've put a lot of thought into this. I like your idea to name the index after the type of item instead of the container. At the moment, the property names are a bit confusing because the function accepts both LineStrings and MultiLineStrings, so some of the properties are called multiXXX. But this is of course confusing for users who call the function with just a LineString and then still see multiXXX properties. Your suggestions for lineStringIndex and segmentIndex would definitely help to clear up that confusion because they make sense regardless of how many LineStrings there are (one or many).

By the same logic, maybe the old location property could be renamed to totalLineStringDistance instead of multiLineStringDistance. Not sure, just an idea. Do you think that would be better?

I'm not strongly advocating for the parameter to be called point instead of pt. My main point (no pun intended) was that I think pointDistance would be a better name than ptDistance for the old dist property.

I would be happy to adapt this pull request in any way you see fit. Just tell me how to proceed and I'll do my best to get it done quickly.

@smallsaucepan
Copy link
Member

Thanks @EmilJunker. Proposing the mashup below. Might ask @JamesLMilner and @mfedderly to review as well.

tl;dr feel we could do better naming the properties in the return object from nearestPointOnLine. Suggesting we take the opportunity with this PR to introduce new property names, and deprecate the old ones somewhere down the track. Existing properties would continue to work (be duplicated in the response) until at least the next major release.

Current New Description
multiFeatureIndex lineStringIndex closest point was found on the nth line of the MultiLineString
index segmentIndex closest point was found on nth line segment of above
location totalDistance what location currently provides, distance from the absolute start of the multilinestring
lineDistance new parameter, distance from the start of the current linestring
segmentDistance another new parameter if we want to, distance from the start of the current segment
dist pointDistance distance from the nearest point to the original input point

There's no overlap so it wouldn't change the behaviour of existing code. Do these seem internally consistent, and also in line with terminology in other functions?

@mfedderly
Copy link
Collaborator

Re pt vs point: If I had to guess, we probably just never considered parameter names as part of the public api and so they wound up inconsistent. Changing them won't even be an API break unless its a key inside an object, so that's low regret to make those a bit more explicit, since they are part of the way we document things.

Re return property names: I agree the existing ones are inconsistent, and I've found them confusing. The proposed names seem reasonable to me. If I can get greedy I'd love for the implementation to change to putting the proposed new properties into the object, and then a second block below that copying to the old names, with a comment above that block saying that it is deprecated.

@EmilJunker EmilJunker force-pushed the nearest-point-on-line-multi-feature-location branch from 0bdf59a to 23a4ca8 Compare December 2, 2025 13:54
@EmilJunker EmilJunker force-pushed the nearest-point-on-line-multi-feature-location branch from 23a4ca8 to 7f36fea Compare December 2, 2025 14:06
@EmilJunker EmilJunker changed the title Compute multiFeatureLocation in addition to location property in @turf/nearest-point-on-line Rename and extend resulting point properties in @turf/nearest-point-on-line Dec 2, 2025
@EmilJunker EmilJunker changed the title Rename and extend resulting point properties in @turf/nearest-point-on-line Refactor and extend properties of returned nearest point in @turf/nearest-point-on-line Dec 2, 2025
@EmilJunker
Copy link
Contributor Author

@smallsaucepan @mfedderly Thank you for your input. I have implemented and pushed the necessary changes. Everything looks good from my side. Please let me know if this is what you had in mind.

I added the six new properties as discussed above, including segmentDistance. The old properties remain unchanged for now, but they can be easily removed later.

I also renamed the pt parameter to inputPoint.

@EmilJunker
Copy link
Contributor Author

If necessary, I could explicitly mark the old properties as deprecated using TypeScript's @deprecated tag:

// deprecated properties START
/** @deprecated use `lineStringIndex` instead */
multiFeatureIndex: number;
/** @deprecated use `segmentIndex` instead */
index: number;
/** @deprecated use `totalDistance` instead */
location: number;
/** @deprecated use `pointDistance` instead */
dist: number;
// deprecated properties END

Compatible editors like VS Code would then cross out those properties in the code suggestions:

{8F2AA8F6-7F3A-4EA4-AD15-77721612EE0F}

And wherever one of those properties is accessed in the source code, it would also be crossed out:

{740C1019-5C6B-4D17-B917-E3B9D237A9CF}

But that's probably something for a future release and should not be part of this pull request.

@mfedderly
Copy link
Collaborator

This all lgtm, I'd be in favor of adding the @deprecated tags now. Can you also run pnpm docs to regenerate that README.md file from the new jsdoc that got updated? I thought that was supposed to happen automatically but perhaps you didn't get the pre-commit hooks installed by default.

@EmilJunker
Copy link
Contributor Author

EmilJunker commented Dec 4, 2025

Alright, I added the deprecation annotations and updated the README.

Generating the README with pnpm run docs didn't quite work for me though. I had to make some edits to the generate-readmes script to make it even do something. And afterwards I had to manually put some line breaks back into the README that got removed for some reason.

Furthermore, it tried to add weird sections to the README based on the /** @deprecated */ comments in the code. I also manually removed them, I hope that's not a problem.

Anyway, it's all good to go now from my side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

nearestPointOnLine unexpectedly sums up lengths of multiLineStrings for location property

3 participants