Skip to content

Conversation

@tsweckard
Copy link

Summary

  • If a path falls on a section of road that doesn't match the specified direction of the entire roadway, our direction filter can filter out the incorrect path since for example, both paths would be going E/W instead of N/S, it's really a toss up for which path get's returned.
  • Instead of prioritizing unnamed to unnamed edge traversal over unnamed to named edges in our unnamed fallback login (used for ramp path generation), we should keep them the same priority and choose the edge that is the straightest continuation. We ran into a problem where the path was going from a ramp to an unnamed service road instead of choosing the next named road that was straight off the ramp.

Solution

  • Abstract DirectionFilterHelper methods from BufferResource for better testing and code cleanup
  • If the difference in latitude or longitude (whichever is being compared) is less that 1/2 the thresholdDistance in degrees, default to the primary path as the paths can be considered too horizontal or vertical to be accurate. This is with the assumption that the difference between the farthest terminals of both paths is roughly 2 times the thresholdDistance. There are some cases where the roads turn which is why I reduced it to 1/2 the threshold distance.
  • If the previous edge was unnamed, find the straightest edge from next named and unnamed edges instead of just unnamed.

@tsweckard tsweckard changed the title GraphHopper Refinements Directional Filter and Unnamed Fallback Refinements Jan 27, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines buffer path selection by improving direction-based filtering and adjusting unnamed-road fallback behavior, while extracting the direction logic into a dedicated helper for better testability.

Changes:

  • Introduces DirectionFilterHelper and unit tests (including a regression case) for direction-based path filtering.
  • Updates direction filtering behavior to default to the primary path when path terminal deltas are below a threshold-derived cutoff.
  • Adjusts unnamed fallback traversal to choose the straightest continuation among both named and unnamed candidate edges.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
web-bundle/src/main/java/com/graphhopper/util/DirectionFilterHelper.java New helper encapsulating direction filtering logic, including new threshold behavior.
web-bundle/src/main/java/com/graphhopper/resources/BufferResource.java Uses DirectionFilterHelper and refines unnamed fallback edge selection toward straightest continuation.
web-bundle/src/test/java/com/graphhopper/util/DirectionFilterHelperTest.java Adds unit and regression tests for the extracted helper logic.
web-bundle/src/test/resources/test-examples/regression-direction-filter-test.json Adds GeoJSON input for the regression test case.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@tsweckard tsweckard requested a review from mdorford January 29, 2026 21:20
* Filters a list of LineStrings based on the specified cardinal or intercardinal direction.
* Compares the furthest points of the first and last LineStrings to determine which aligns
* best with the desired direction, returning only the selected LineString.
* @param lineStrings list of LineStrings to filter

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: is this assuming only 2 lineString values? would it be more clear to pass them in as path1/2 instead?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah I see we have a case for both of them...maybejust update the param description to indicate we're expecting 2 and don't compare across an entire list

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The normal case is to have two LineStrings. It is actually possible to have just one LineString but the code still works with one LineString (although it is doing unnecessary work with one LineString).
It used to be the case that it was always two and never one.
It is never possible to have more than two. It would make sense to have a check for 'just one' and to simply take the one and not call filterPathsByDirection if it was just one. If that were done, then it would be safe to use the indices to specify first and second inside filterPathsByDirection but it would not be safe IF it was still possible to call the method with just one.
Important note is that the final return there:
return createGeoJsonResponse(filteredLineStrings, stopWatch);
DOES need to accept a List of LineString because filterPathsByDirection will return two LineStrings if it receives two LineStrings AND ALSO has a direction of 'BOTH'.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated!

Copy link

@payneBrandon payneBrandon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking great! Just the couple small comments

Copy link

@payneBrandon payneBrandon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm!

Copy link
Collaborator

@chansbtran chansbtran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@chansbtran chansbtran merged commit b325a48 into master Feb 2, 2026
4 checks passed
@chansbtran chansbtran deleted the revert-master-commits-2 branch February 2, 2026 22:21
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.

5 participants