Skip to content

Conversation

@leonardehrenfried
Copy link
Member

@leonardehrenfried leonardehrenfried commented Aug 18, 2025

Summary

It restores the ability to use the id of a multi-modal station or a group of station for the start and end point of routing requests.

It does it by clarifying responsibilities:

  • TransitService resolves site ids into their child stops
  • StreetIndex only has references to stop vertices through their ID but doesn't know anything about stations, group of stations...
  • TemporaryVerticesContainer is the glue that takes the various data sources and returns the correct vertices.

Renaming

TemporaryVerticesContainer is not a good name anymore and I would like to rename it. Not sure if I should do it in this PR.

Issue

Fixes #6804

Unit tests

Lots added.

Documentation

Lots of methods clarified, Javadocs adde and method grouping improved in the various files.

@leonardehrenfried leonardehrenfried requested a review from a team as a code owner August 18, 2025 09:55
@leonardehrenfried leonardehrenfried added the !Bug Apply to issues describing a bug and PRs witch fixes it. label Aug 18, 2025
@leonardehrenfried leonardehrenfried changed the title Fix lookup of multi-modal stations and group of stations Restore lookup of multi-modal stations and group of stations Aug 18, 2025
@codecov
Copy link

codecov bot commented Aug 18, 2025

Codecov Report

❌ Patch coverage is 92.10526% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 72.00%. Comparing base (3bae1a1) to head (fb3832a).
⚠️ Report is 369 commits behind head on dev-2.x.

Files with missing lines Patch % Lines
...planner/routing/graphfinder/StreetGraphFinder.java 0.00% 1 Missing ⚠️
...nner/street/search/TemporaryVerticesContainer.java 95.23% 0 Missing and 1 partial ⚠️
...rg/opentripplanner/visualizer/GraphVisualizer.java 0.00% 1 Missing ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             dev-2.x    #6805      +/-   ##
=============================================
+ Coverage      71.76%   72.00%   +0.24%     
- Complexity     19330    19437     +107     
=============================================
  Files           2090     2101      +11     
  Lines          78771    78774       +3     
  Branches        8027     7963      -64     
=============================================
+ Hits           56529    56724     +195     
+ Misses         19384    19242     -142     
+ Partials        2858     2808      -50     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@optionsome optionsome requested review from habrahamsson-skanetrafiken and optionsome and removed request for optionsome August 18, 2025 10:11
@leonardehrenfried
Copy link
Member Author

@habrahamsson-skanetrafiken This one touches the station centroid feature and I'm not sure I've taken all the required subtleties into account. Can you test this with your data set, please?

Copy link
Contributor

Choose a reason for hiding this comment

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

This looks fine to me. I'll verify the centroid stuff in our test environment.

There will be conflicts with #6704 i guess.

Copy link
Contributor

Choose a reason for hiding this comment

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

These changes look good to me and I agree that the restructuring is a good one.

* return the child stops of that station.
*/
public Set<TransitStopVertex> getFromStopVertices() {
if (from.stopId == null) {

Choose a reason for hiding this comment

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

I had a look at the getFromVertices() and getFromStopVertices() methods etc. They look good to me. I understand that the naming is very similar and a bit confusing.

The thing I did with centroid coordinates is basically to be able to have separate vertices for the street search part and the transit search part.

So if you use a station with a centroid coordinate we will do the street search (and access/egress walking etc) using the centroid coordinate but still do the transit search using the child stop coordinates.

Do you think it would be easier to understand if we renamed the methods to getFromStreetVertices() and getFromStopOrChildStopVertices() perhaps?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think it's fine the way it is. I was just wondering if the street vertex methods should return the centroid vertex or not. Sounds like they should not.

Choose a reason for hiding this comment

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

The stop vertex methods should not, but the street vertex methods should. And this PR seems to keep that behaviour so it looks fine.

@t2gran t2gran added the Entur Test This is currently being tested at Entur label Aug 19, 2025
@t2gran t2gran added this to the 2.8 (next release) milestone Aug 19, 2025
@eibakke eibakke removed the Entur Test This is currently being tested at Entur label Aug 20, 2025
* <p>
* It also facilitates the lookup of site ids to the correct vertices.
* <p>
* It implements
Copy link
Member

Choose a reason for hiding this comment

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

I created this class to take care of disposing temporary changes to the graph[v,e] . It is a framework "thing", and should not contain business rules (decide between centroid/coordinates/ids). I will approve this PR, since it is only patching the existing features - but this should be refactored, so this class get back to its original responsibility.

Copy link
Member Author

Choose a reason for hiding this comment

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

Where would you put this logic?

Comment on lines +177 to 196
// check if there is a stop by the given id
var stopVertex = graph.findStopVertex(location.stopId);
if (stopVertex.isPresent()) {
return Set.of(stopVertex.get());
}

// station centroids may be used instead of child stop vertices for stations
var centroidVertex = graph.findStationCentroidVertex(location.stopId);
if (centroidVertex.isPresent()) {
return Set.of(centroidVertex.get());
}

// in the regular case you want to resolve a (multi-modal) station into its child stops
var childVertices = findStopOrChildStopVertices(location.stopId);
if (!childVertices.isEmpty()) {
return childVertices
.stream()
.map(Vertex.class::cast)
.collect(Collectors.toUnmodifiableSet());
}
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this could be pushed into the Graph - at least the Graphs responsibilities matches better than this class.

Copy link
Member Author

Choose a reason for hiding this comment

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

The vertex part would be a good fit but should the Graph know about resolving stations to stops?

Copy link
Member Author

Choose a reason for hiding this comment

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

Also @habrahamsson-skanetrafiken might want to chime in because he asked me to move out of the graph to this class.

Copy link
Member

Choose a reason for hiding this comment

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

I think we should look at this together in the design meeting, with at least all three of us present.

Copy link
Member Author

Choose a reason for hiding this comment

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

I agree, but didn't you want something sooner so that you can release to prod?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess the question is if we want the Graph to know about the hierarchy between stops/stations/multi-modal stations etc. If we don't want the Graph to know about that stuff then this code needs to go somewhere else.

If we want to keep the TemporaryVerticesContainer small, maybe we could extract this id -> vertex resolving logic to a separate class that depends on both Graph and TransitService.

We can look at it in a design meeting.

@t2gran t2gran added the Entur Test This is currently being tested at Entur label Aug 29, 2025
@leonardehrenfried
Copy link
Member Author

I can work on this feature this week if there is a consensus what I should be doing.

@t2gran t2gran modified the milestones: 2.8, 2.9 (next release) Sep 10, 2025
@t2gran
Copy link
Member

t2gran commented Sep 11, 2025

This is now blocking #6791 - there is a merge conflict. Can we merge this, and refactor in a separate PR?

Copy link
Member

@t2gran t2gran left a comment

Choose a reason for hiding this comment

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

This PR should be followed up with a PR fixing the problem with the TemporaryVerticesContainer (discussed above). But, the bugfix is a blocker - so we want this to be merged.

@leonardehrenfried
Copy link
Member Author

@habrahamsson-skanetrafiken already approved previously so I will merge this and refactor later.

@leonardehrenfried leonardehrenfried merged commit 1ea783b into opentripplanner:dev-2.x Sep 11, 2025
7 checks passed
@leonardehrenfried leonardehrenfried deleted the fix-multimodal branch September 11, 2025 11:11
t2gran pushed a commit that referenced this pull request Sep 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

!Bug Apply to issues describing a bug and PRs witch fixes it. Entur Test This is currently being tested at Entur

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for Multimodal Stops not working

4 participants