-
Notifications
You must be signed in to change notification settings - Fork 1.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
If configured, add subway station entrances from OSM to walk steps #6076
Changes from 1 commit
1d19a05
67f4b1b
9d18269
3b88288
0a62bf8
528ab55
3e4ae96
401a405
438bc31
97c2de6
d844561
02a07ea
5dc74dd
5d55646
d1067c6
5c97ad1
e10e0a2
34761fe
c84b7cf
2ea8a52
39b0db3
3b6bf3f
36be3dc
c9df52d
7a9a8f6
c9139e3
7b21024
ce7719c
b737411
f547e07
18b84f0
2060016
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package org.opentripplanner.apis.gtfs.datafetchers; | ||
|
||
import graphql.schema.DataFetcher; | ||
import graphql.schema.DataFetchingEnvironment; | ||
import org.opentripplanner.apis.gtfs.GraphQLUtils; | ||
import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; | ||
import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; | ||
import org.opentripplanner.transit.model.site.Entrance; | ||
|
||
public class EntranceImpl implements GraphQLDataFetchers.GraphQLEntrance { | ||
|
||
@Override | ||
public DataFetcher<String> code() { | ||
return environment -> { | ||
Entrance entrance = getEntrance(environment); | ||
return entrance != null && entrance.getCode() != null ? entrance.getCode() : null; | ||
}; | ||
} | ||
|
||
@Override | ||
public DataFetcher<String> gtfsId() { | ||
return environment -> { | ||
Entrance entrance = getEntrance(environment); | ||
return entrance != null && entrance.getId() != null ? entrance.getId().toString() : null; | ||
}; | ||
} | ||
|
||
@Override | ||
public DataFetcher<String> name() { | ||
return environment -> { | ||
Entrance entrance = getEntrance(environment); | ||
return entrance != null && entrance.getName() != null ? entrance.getName().toString() : null; | ||
}; | ||
} | ||
|
||
@Override | ||
public DataFetcher<GraphQLTypes.GraphQLWheelchairBoarding> wheelchairAccessible() { | ||
return environment -> { | ||
Entrance entrance = getEntrance(environment); | ||
return entrance != null | ||
? GraphQLUtils.toGraphQL(entrance.getWheelchairAccessibility()) | ||
: null; | ||
}; | ||
} | ||
|
||
/** | ||
* Helper method to retrieve the Entrance object from the DataFetchingEnvironment. | ||
*/ | ||
private Entrance getEntrance(DataFetchingEnvironment environment) { | ||
Object source = environment.getSource(); | ||
return source instanceof Entrance ? (Entrance) source : null; | ||
} | ||
} |
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,9 +8,9 @@ | |
import org.opentripplanner.framework.i18n.I18NString; | ||
import org.opentripplanner.framework.lang.DoubleUtils; | ||
import org.opentripplanner.framework.tostring.ToStringBuilder; | ||
import org.opentripplanner.model.plan.StepEntity; | ||
import org.opentripplanner.street.model.edge.Edge; | ||
import org.opentripplanner.street.model.note.StreetNote; | ||
import org.opentripplanner.transit.model.site.Entrance; | ||
|
||
/** | ||
* Represents one instruction in walking directions. Three examples from New York City: | ||
|
@@ -45,7 +45,7 @@ public final class WalkStep { | |
private final boolean walkingBike; | ||
|
||
private final String exit; | ||
private final StepEntity entity; | ||
private final Entrance entrance; | ||
private final ElevationProfile elevationProfile; | ||
private final boolean stayOn; | ||
|
||
|
@@ -58,7 +58,7 @@ public final class WalkStep { | |
I18NString directionText, | ||
Set<StreetNote> streetNotes, | ||
String exit, | ||
StepEntity entity, | ||
Entrance entrance, | ||
ElevationProfile elevationProfile, | ||
boolean bogusName, | ||
boolean walkingBike, | ||
|
@@ -79,7 +79,7 @@ public final class WalkStep { | |
this.walkingBike = walkingBike; | ||
this.area = area; | ||
this.exit = exit; | ||
this.entity = entity; | ||
this.entrance = entrance; | ||
this.elevationProfile = elevationProfile; | ||
this.stayOn = stayOn; | ||
this.edges = List.copyOf(Objects.requireNonNull(edges)); | ||
|
@@ -135,10 +135,10 @@ public String getExit() { | |
} | ||
|
||
/** | ||
* Entity related to a step e.g. building entrance/exit. | ||
* Get information about building entrance or exit. | ||
*/ | ||
public Object getEntity() { | ||
return entity; | ||
public Entrance getEntrance() { | ||
return entrance; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would like to se a diagram with boxes - forget about the class design for a moment and just draw the things we want to add in the future (next 1- 2 years). Then we can discuss how to group them and map the relationship. Return an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I drew some sort of a process diagram with boxes together with @HenrikSundell. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this method should probably still return StepEntity instead of Object but I think the step impl must return an Object for the entity which is then handled by StepEntityTypeResolver. It's possible that instead of doing the instanceof checks that are currently done to return correct schema types, we could cast the object to a StepEntity and then check if entrance field is non-null, or escalator field is non-null etc., but I'm not sure how much cleaner that solution is. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just quickly tested and seems like it's possible to define a class that is used for an union from GraphQL (through codegen configuration). So with this current setup where the different entity types would have a shared base class, you could use that for the union. However, if they don't, then you need to return an Object from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,6 @@ | |
import org.opentripplanner.framework.geometry.WgsCoordinate; | ||
import org.opentripplanner.framework.i18n.I18NString; | ||
import org.opentripplanner.model.plan.ElevationProfile; | ||
import org.opentripplanner.model.plan.Entrance; | ||
import org.opentripplanner.model.plan.RelativeDirection; | ||
import org.opentripplanner.model.plan.WalkStep; | ||
import org.opentripplanner.model.plan.WalkStepBuilder; | ||
|
@@ -30,6 +29,8 @@ | |
import org.opentripplanner.street.model.vertex.Vertex; | ||
import org.opentripplanner.street.search.TraverseMode; | ||
import org.opentripplanner.street.search.state.State; | ||
import org.opentripplanner.transit.model.basic.Accessibility; | ||
import org.opentripplanner.transit.model.site.Entrance; | ||
|
||
/** | ||
* Process a list of states into a list of walking/driving instructions for a street leg. | ||
|
@@ -528,10 +529,20 @@ private WalkStepBuilder createStationEntranceWalkStep( | |
// don't care what came before or comes after | ||
var step = createWalkStep(forwardState, backState); | ||
|
||
step.withRelativeDirection(RelativeDirection.CONTINUE); | ||
step.withRelativeDirection(RelativeDirection.ENTER_OR_EXIT_STATION); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could add a comment here to explain that figuring out if something is an entrance or exit is difficult here. |
||
|
||
StationEntranceVertex vertex = (StationEntranceVertex) backState.getVertex(); | ||
step.withEntrance(Entrance.withCodeAndAccessible(vertex.getCode(), vertex.isAccessible())); | ||
|
||
Entrance entrance = Entrance | ||
.of(null) | ||
.withCode(vertex.getCode()) | ||
.withCoordinate(new WgsCoordinate(vertex.getCoordinate())) | ||
.withWheelchairAccessibility( | ||
vertex.isAccessible() ? Accessibility.POSSIBLE : Accessibility.NOT_POSSIBLE | ||
) | ||
.build(); | ||
|
||
step.withEntrance(entrance); | ||
return step; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,9 +73,6 @@ interface PlaceInterface { | |
"Entity related to an alert" | ||
union AlertEntity = Agency | Pattern | Route | RouteType | Stop | StopOnRoute | StopOnTrip | Trip | Unknown | ||
|
||
"Entity to a step" | ||
union StepEntity = Entrance | ||
|
||
union StopPosition = PositionAtStop | PositionBetweenStops | ||
|
||
"A public transport agency" | ||
|
@@ -449,14 +446,14 @@ type Emissions { | |
|
||
"Station entrance or exit." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could clarify here that this can originate either from GTFS or from OSM. |
||
type Entrance { | ||
"True if the entrance is wheelchair accessible." | ||
accessible: Boolean | ||
"Short text or a number that identifies the entrance or exit for passengers. For example, `A` or `B`." | ||
code: String | ||
"ID of the entrance in the format of `FeedId:EntranceId`." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, you could mention that if the feed is |
||
gtfsId: String | ||
"Name of the entrance or exit." | ||
name: String | ||
"Whether the entrance or exit is accessible by wheelchair" | ||
wheelchairAccessible: WheelchairBoarding | ||
} | ||
|
||
"A 'medium' that a fare product applies to, for example cash, 'Oyster Card' or 'DB Navigator App'." | ||
|
@@ -2660,8 +2657,8 @@ type step { | |
distance: Float | ||
"The elevation profile as a list of { distance, elevation } values." | ||
elevationProfile: [elevationProfileComponent] | ||
"Step entity, e.g. an entrance." | ||
entity: StepEntity | ||
"Information about an station entrance or exit" | ||
entrance: Entrance | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless I'm totally mistaken, I think on this API level we still want to have the entity field which returns an entity union. |
||
"When exiting a highway or traffic circle, the exit name/number." | ||
exit: String | ||
"The latitude of the start of the step." | ||
|
@@ -3329,6 +3326,7 @@ enum RelativeDirection { | |
CONTINUE | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add description for this enum value. Maybe we could add descriptions for some other values in this enum as well as not all of them are clear. |
||
DEPART | ||
ELEVATOR | ||
ENTER_OR_EXIT_STATION | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't want to expose this enum value to users, it should be mapped to CONTINUE. |
||
ENTER_STATION | ||
EXIT_STATION | ||
FOLLOW_SIGNS | ||
|
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.
Maybe we should say "subway stations's entrance" instead of building here. Also since there is already
getExit
here, maybe rename this and the highway exit rename methods so it's really clear that one is for highways, and the other is for stations.