Skip to content

Create a valid area even when it has too many vertices#5019

Merged
vesameskanen merged 10 commits into
opentripplanner:dev-2.xfrom
HSLdevcom:too-complex-area-fallback
Apr 25, 2023
Merged

Create a valid area even when it has too many vertices#5019
vesameskanen merged 10 commits into
opentripplanner:dev-2.xfrom
HSLdevcom:too-complex-area-fallback

Conversation

@vesameskanen
Copy link
Copy Markdown
Contributor

@vesameskanen vesameskanen commented Apr 1, 2023

Summary

Walkable area processing does not try to generate walking routes across the area, if the geometry is too complex. The complexity limit check terminated area processing so early that area data which is used in linking vertices inside the area was totally missing.

Now area processing initialises complex areas propely. Slow edge generation is mitigated by considering only maxAreaNodes subset from the visibility nodes.

Area complexity check terminated  area processin too early,
leaving the area data invalid for linking.
@vesameskanen vesameskanen requested a review from a team as a code owner April 1, 2023 08:10
@vesameskanen vesameskanen added the !Bug Apply to issues describing a bug and PRs witch fixes it. label Apr 1, 2023
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 1, 2023

Codecov Report

Patch coverage: 90.19% and project coverage change: +0.11 🎉

Comparison is base (d7f43ca) 64.49% compared to head (216f6fc) 64.60%.

Additional details and impacted files
@@              Coverage Diff              @@
##             dev-2.x    #5019      +/-   ##
=============================================
+ Coverage      64.49%   64.60%   +0.11%     
- Complexity     13863    13890      +27     
=============================================
  Files           1710     1710              
  Lines          67017    67054      +37     
  Branches        7203     7206       +3     
=============================================
+ Hits           43221    43322     +101     
+ Misses         21376    21312      -64     
  Partials        2420     2420              
Impacted Files Coverage Δ
.../graph_builder/module/osm/OpenStreetMapModule.java 90.92% <85.71%> (+0.53%) ⬆️
.../graph_builder/module/osm/WalkableAreaBuilder.java 89.53% <100.00%> (+8.33%) ⬆️
...opentripplanner/standalone/config/BuildConfig.java 98.46% <100.00%> (ø)

... and 13 files with indirect coverage changes

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Copy Markdown
Member

@leonardehrenfried leonardehrenfried left a comment

Choose a reason for hiding this comment

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

This is good work, thanks @vesameskanen .

However since this code breaks a lot I think we really should be add tests for this behaviour. Personally, I would be ok if we read in real OSM data from Lund, run the area builder and assert a result. (https://docs.opentripplanner.org/en/dev-2.x/Preparing-OSM/#filtering-osm-data)

Since it's a bug that Skanetrafiken wants fixed, could we ask @Bartosz-Kruba and @jtorin to contribute the tests?

@jtorin
Copy link
Copy Markdown
Contributor

jtorin commented Apr 3, 2023

This is good work, thanks @vesameskanen .

Indeed! Also, I have separately verified that it solves the problem we're seeing.

Since it's a bug that Skanetrafiken wants fixed, could we ask @Bartosz-Kruba and @jtorin to contribute the tests?

Lets discuss this on tomorrows dev-meeting.

@leonardehrenfried
Copy link
Copy Markdown
Member

@leonardehrenfried
Copy link
Copy Markdown
Member

leonardehrenfried commented Apr 4, 2023

@jtorin Here is an example of how to extract data from a larger OSM file: https://github.com/leonardehrenfried/otp2-setup/blob/main/Makefile#L219

http://geojson.io/

And here is an example for filtering out unneeded ways: https://docs.opentripplanner.org/en/dev-2.x/Preparing-OSM/#filtering-osm-data

int i = 0;
float sum_i = 0;
for (OSMNode nodeI : visibilityNodes) {
sum_i += skip_ratio;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice fix!

Just a note that summing floats like this can actually be a bit dangerous. If skip_ratio is sufficiently small (like 1e-8) the sum will never reach 1. It probably won't be issue in this case but you might want to write this logic using an integer counter instead

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Right. In this case, float increment is typically greater than 0.1, and in some truly exceptional cases > 0.01. Lower values would mean that street graph is useless for routing, and it won't matter if area edges will not get added.

@optionsome optionsome added the Digitransit Test Feature is under testing in Digitransit environment(s) label Apr 6, 2023
@jtorin
Copy link
Copy Markdown
Contributor

jtorin commented Apr 13, 2023

@vesameskanen I'm working on a test for WalkableAreaBuilder with data covering Lund station.

vesameskanen and others added 7 commits April 20, 2023 12:05
Area complexity check terminated  area processin too early,
leaving the area data invalid for linking.
…g OpenStreetMapModule.

Make Handler static, which means that it looses access to the fields in OSMModule.
Solve this by a mix of passing copies of private values to a new instance, as well
as funneling access to the data using Suppliers.

A number of tests needs to adapt to the new extended contructor.
Uses OSM data from an area around Lund station, Sweden.
Coverage as well as assertions are spotty and can be improved.

With help from Leonard Ehrenfried.
@t2gran t2gran added this to the 2.4 milestone Apr 24, 2023
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice that you got the tests in!

Just a comment about how we might be able to clean the code up a bit. But we could also just merge this as is as far as I'm concerned.

this.issueStore = issueStore;
this.areaVisibility = areaVisibility;
this.banDiscouragedWalking = banDiscouragedWalking;
this.banDiscouragedBiking = banDiscouragedBiking;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can't we add the staticParkAndRide, staticBikeParkAndRide, platformEntriesLinking, customNamer and maxAreaNodes to the constructor as well? Then we could avoid the Supplier-thing and we could make the fields private. IMO it's better to have an obscenely big constructor than exposing public mutable fields.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Unfortunately it's the other way around: the Supplier:s exists to couple the handler with the public fields in OpenStreetMapModule. I checked in each public field and it was only banDiscouragedWalking and banDiscouragedBiking that wasn't modified externally, thus made them private final (immutable) and passable to Handler.

Yes, this isn't especially pretty, but I tried to minimize the changes in the application code to avoid introducing bugs.

Since Handler is 1-to-1 instantiation-wise to the outer class OpenStreetMapModule maybe they should be merged, and Handler could be converted to an interface instead. Maybe WalkableAreaBuilder and some of the code in OpenStreetMapModule can be converted into smaller modules that are executed sequentially.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, it's true that the public fields are modified externally but from a quick glance it looked like all the modifications were made in tests that could trivially be changed to supply the values via constructor instead.

You're right that these classes would benefit from some refactoring :) But I guess that's out of scope for this PR.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think we all agree that these public mutable fields are terrible and we should get rid of it.

But frankly I feel like I've tortured @jtorin enough so I will not insist on it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The best solution IMO would be to replace the OSMModule constructor with a builder so that the default values area set appropriately. I might do that in the future.

import org.opentripplanner.street.model.edge.AreaEdge;
import org.opentripplanner.transit.model.framework.Deduplicator;

public class WalkableAreaBuilderTest {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a good test and the beginning of something new - thanks!

I've taken the liberty to remove a bit of duplication by using a parameterized test. It's not really a requirement to getting this merged as it comes down to personal preferences, but if you like it, you can also cherry-pick this commit: leonardehrenfried@6eed582

Copy link
Copy Markdown
Contributor

@jtorin jtorin left a comment

Choose a reason for hiding this comment

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

I'm approving the actual code changes, @habrahamsson-skanetrafiken has reviewed and approved my tests (as well).

@vesameskanen vesameskanen merged commit 3c59d1c into opentripplanner:dev-2.x Apr 25, 2023
@vesameskanen vesameskanen deleted the too-complex-area-fallback branch April 25, 2023 09:12
t2gran pushed a commit that referenced this pull request Apr 25, 2023
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. Digitransit Test Feature is under testing in Digitransit environment(s)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants