-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create own parking preferences for bike and car in the internal model #5521
Create own parking preferences for bike and car in the internal model #5521
Conversation
public Duration parkTime() { | ||
return parkTime; | ||
} | ||
|
||
/** Cost of parking a bike. */ | ||
public Cost parkCost() { | ||
return parkCost; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we expose (or even use) Cost and Duration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The preferences is part of the API - the purpose is to make it easy to use and safe - avoid mistakes. So, indeed we should use the type-safe wrapper types. The API is not about the internal model. When we do routing in AStar and Raptor we should copy/map the values into the AStar Request(does not exist) and into the Raptor Request. The Raptor and AStar requests should be consered with performance. In this way we make a nice user friendly API witch should hide the implementation details from the APIs. We can reuse types and structures - the mapping into Raptor and AStar can use the same source (walkReluctance, boardingCost ...).
Short: Use the typesafe version of Cost and Reluctance here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. Whatever call site needs something more efficient needs to create their own model.
.of("unpreferredVehicleParkingTagCost") | ||
.since(V2_3) | ||
.summary("What cost to add if a parking facility doesn't contain a preferred tag.") | ||
.description("See `preferredVehicleParkingTags`.") | ||
.asInt(VehicleParkingPreferences.DEFAULT.unpreferredVehicleParkingTagCost().toSeconds()) | ||
) | ||
.withBannedVehicleParkingTags( | ||
c | ||
.of("bannedVehicleParkingTags") | ||
.since(V2_1) | ||
.summary( | ||
"Tags with which a vehicle parking will not be used. If empty, no tags are banned." | ||
) | ||
.asStringSet(List.of()) | ||
) | ||
.withRequiredVehicleParkingTags( | ||
c | ||
.of("requiredVehicleParkingTags") | ||
.since(V2_1) | ||
.summary( | ||
"Tags without which a vehicle parking will not be used. If empty, no tags are required." | ||
) | ||
.asStringSet(List.of()) | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we remove these and instead create versions of these that are specific to car and bike?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that is the correct way to do it. Remember that if you use the same type within each mode then you only need to write one config for it as well.
Q: Tag
is very generic, it does not say witch context it comes from. Is it a network
, a OSM tag, or tag from somewhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'll postpone the router-config refactoring to a follow up pr. Otherwise I would need to do it in two phases and this is a new feature anyway that no one is wanting to use yet.
The tag can originate from different places depending on the origin of the parking. I think mostly it's generated off some OSM tags but in Finland we load the tags from a custom format from a realtime updater. I think the network/feed is never a tag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the explanation, a hint on this in the doc would be useful:
The tag can originate from different places depending on the origin of the parking(OSM or RT feed).
Codecov ReportAttention:
Additional details and impacted files@@ Coverage Diff @@
## dev-2.x #5521 +/- ##
=============================================
+ Coverage 66.93% 67.18% +0.25%
- Complexity 15700 16106 +406
=============================================
Files 1819 1856 +37
Lines 70248 71391 +1143
Branches 7392 7474 +82
=============================================
+ Hits 47022 47967 +945
- Misses 20772 20922 +150
- Partials 2454 2502 +48 ☔ View full report in Codecov by Sentry. |
src/test/java/org/opentripplanner/apis/gtfs/mapping/RouteRequestMapperTest.java
Outdated
Show resolved
Hide resolved
.withParking(it -> | ||
it | ||
.withUnpreferredVehicleParkingTagCost( | ||
c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first 3 items are identical with the ones below. Can you make them bike/car specific or extract a re-usable method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'll create a reusable method if possible, I'll check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'll do it in a follow up pr because some of the parameter names are not generic now (they will be in in the future).
? s0.getRequest().preferences().car().parking() | ||
: s0.getRequest().preferences().bike().parking(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you create a utility method for this somewhere in the preferences?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about it too but wasn't sure where to put it. I'll try to find a place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created a method under the root preferences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned on todays meeting, we are passing in the API request/preferences into AStar without a mapping it. One of the effects is that we then need to do mapping everywhere it is used instead of in one place - I do not expect you tro refactor this, but I just wanted to highlight the pain. If it is interesting, we could take one feature like the parking and refactor AStar with just that. Then the job is not so big, and it can be done in iterations. Also, when a pattern is established it become easier to take do the rest - just follow the recipe. In this case the AStar "preference" should have a method to return a AStar specific VehiclePariking based on the s0.currentMode()
.
src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a few requests. Most importantly, please bring back the test for the GraphQL request mapper.
public ToStringBuilder addBool(String name, Boolean value, Boolean ignoreValue) { | ||
return addIfNotIgnored(name, value, ignoreValue, Object::toString); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer the addBoolIfTrue
over this. For example useAvailabilityInformation=false
is not as readable as skipAvailabilityInfo
. We try to keep toStrings short and readable. You would need to repeat the default value in the toString inside the class to do this, but I prefer that for the extra readability.
Consider adding JavaDoc recommending the addBoolIfTrue
or converting the usage of this. Note! That the addBoolIfTrue
fits well with things that are off by default, and not so good with things that are on. Note also that the consequences of flipping the value in the toString is very small - it is just confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not important!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up renaming the parameter ignoreRealtimeAvailability
. I was considering using the excludeRealtimeUpdates
naming we used the plan pr but this paramete doesn't really exclude all realtime updates as the parks itself are added through realtime updates, it just ignores the realtime availability. I only did the renaming in the preferences, the REST API parameter stays as is.
/** | ||
* Get parking preferences for the traverse mode. Note, only car and bike are supported. | ||
*/ | ||
public VehicleParkingPreferences parking(TraverseMode mode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note! The TraverseMode
is not part of the api, and using it here create a circular dependency - this is nothing new, so I am not requesting you to change it - but this is adding a string to the spagetti.
@@ -11,7 +12,7 @@ | |||
* A request object that checks if parking faclities match certain conditions for | |||
* inclusion/exclusion or preference/unpreference. | |||
*/ | |||
public class VehicleParkingFilterRequest { | |||
public class VehicleParkingFilterRequest implements Serializable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI: I plan to split the filter logic from the select parameters/data. The current filters can not be reused in different places because it depends on the internal model - it is applied to one set of model classes, but in other use-cases we would like to use the same filters to filter other things. E.g. not filter Scheduled trips, but FLEX or transit-priority-groups.
This PR is ok, it is neutral when it comes to moving in a direction here. The select()
/not()
is good, but the returned Filter is not.
src/test/java/org/opentripplanner/framework/tostring/ToStringBuilderTest.java
Outdated
Show resolved
Hide resolved
...t/java/org/opentripplanner/routing/api/request/preference/VehicleParkingPreferencesTest.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It mostly looks OK, some comments and "frustrations", but your work is good.
* Parking containing select filters must only be usable and parking containing with not filters | ||
* cannot be used. | ||
*/ | ||
public VehicleParkingFilterRequest filter() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is no longer part of the request, so it need a new name. I suggest just dropping the Request
, and we will deal with the naming when splitting the data from the filtering implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Issue is that this class contains VehicleParkingFilter objects already so can't use that name unless we first rename it. I couldn't really think of a good name for this. We can come up with a solution in the dev meeting.
This is now ready for review again |
src/main/java/org/opentripplanner/street/model/edge/VehicleParkingEdge.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please have a look at my request.
I realized I have made a mistake here on the realtime usage. The default used to be the opposite of what it is now. I've converted this to be draft so we can discuss what to do with this next week. |
I've removed support for |
There was also an issue with copying over preferences when doing remodification. I've fixed that too. |
Summary
This refactors parking preferences so that in the internal model the same preferences are not used for all types of parking but it is now possible to set them different for car and bike parking. This pr is done in preparation to #5185
This also removes support for useVehicleParkingAvailabilityInformation that was only usable through REST API
Issue
This is related to #4803
Unit tests
Updated and added tests.
Documentation
Minor automatic updates.
Changelog
From title