From 1d19a052a8bf2523c3af537edfc92fe9a72e8c62 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Wed, 18 Sep 2024 17:22:19 +0300 Subject: [PATCH 01/36] Add subway station entrances to walk steps --- .../apis/gtfs/datafetchers/stepImpl.java | 5 +++++ .../gtfs/generated/GraphQLDataFetchers.java | 11 +++++++++++ .../apis/gtfs/generated/GraphQLTypes.java | 1 + .../module/osm/VertexGenerator.java | 9 +++++++++ .../opentripplanner/model/plan/WalkStep.java | 10 ++++++++++ .../model/plan/WalkStepBuilder.java | 7 +++++++ .../openstreetmap/model/OSMNode.java | 9 +++++++++ .../mapping/StatesToWalkStepsMapper.java | 18 ++++++++++++++++++ .../model/vertex/StationEntranceVertex.java | 19 +++++++++++++++++++ .../street/model/vertex/VertexFactory.java | 9 +++++++++ .../opentripplanner/apis/gtfs/schema.graphqls | 2 ++ 11 files changed, 100 insertions(+) create mode 100644 src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index 6bd51ae5f29..d79e224e51e 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -53,6 +53,11 @@ public DataFetcher exit() { return environment -> getSource(environment).getExit(); } + @Override + public DataFetcher entrance() { + return environment -> getSource(environment).getEntrance(); + } + @Override public DataFetcher lat() { return environment -> getSource(environment).getStartLocation().latitude(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 67944543580..3c162b14112 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -1,9 +1,11 @@ //THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. package org.opentripplanner.apis.gtfs.generated; +import graphql.relay.Connection; import graphql.relay.Connection; import graphql.relay.DefaultEdge; import graphql.relay.Edge; +import graphql.relay.Edge; import graphql.schema.DataFetcher; import graphql.schema.TypeResolver; import java.util.Currency; @@ -24,8 +26,12 @@ import org.opentripplanner.apis.gtfs.model.FeedPublisher; import org.opentripplanner.apis.gtfs.model.PlanPageInfo; import org.opentripplanner.apis.gtfs.model.RideHailingProvider; +import org.opentripplanner.apis.gtfs.model.RouteTypeModel; +import org.opentripplanner.apis.gtfs.model.StopOnRouteModel; +import org.opentripplanner.apis.gtfs.model.StopOnTripModel; import org.opentripplanner.apis.gtfs.model.StopPosition; import org.opentripplanner.apis.gtfs.model.TripOccupancy; +import org.opentripplanner.apis.gtfs.model.UnknownModel; import org.opentripplanner.ext.fares.model.FareRuleSet; import org.opentripplanner.ext.ridehailing.model.RideEstimate; import org.opentripplanner.model.StopTimesInPattern; @@ -48,6 +54,8 @@ import org.opentripplanner.routing.graphfinder.PatternAtStop; import org.opentripplanner.routing.graphfinder.PlaceAtDistance; import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.routing.vehicle_parking.VehicleParking; +import org.opentripplanner.routing.vehicle_parking.VehicleParking; import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; @@ -58,6 +66,7 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris; +import org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris; import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem; import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; import org.opentripplanner.transit.model.basic.Money; @@ -1419,6 +1428,8 @@ public interface GraphQLStep { public DataFetcher> elevationProfile(); + public DataFetcher entrance(); + public DataFetcher exit(); public DataFetcher lat(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index 67051444cdf..8edc0cce870 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -1,6 +1,7 @@ // THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. package org.opentripplanner.apis.gtfs.generated; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java b/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java index 14489777dd4..df9c4376871 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java @@ -95,6 +95,15 @@ IntersectionVertex getVertexForOsmNode(OSMNode node, OSMWithTags way) { iv = bv; } + if (node.isSubwayEntrance()) { + String ref = node.getTag("ref"); + if (ref != null) { + iv = vertexFactory.stationEntrance(nid, coordinate, ref); + } else { + iv = vertexFactory.stationEntrance(nid, coordinate, "MAIN_ENTRANCE"); + } + } + if (iv == null) { iv = vertexFactory.osm( diff --git a/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/src/main/java/org/opentripplanner/model/plan/WalkStep.java index 13249d5da52..9a650ecef3e 100644 --- a/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -44,6 +44,7 @@ public final class WalkStep { private final boolean walkingBike; private final String exit; + private final String entrance; private final ElevationProfile elevationProfile; private final boolean stayOn; @@ -56,6 +57,7 @@ public final class WalkStep { I18NString directionText, Set streetNotes, String exit, + String entrance, ElevationProfile elevationProfile, boolean bogusName, boolean walkingBike, @@ -76,6 +78,7 @@ public final class WalkStep { this.walkingBike = walkingBike; this.area = area; this.exit = exit; + this.entrance = entrance; this.elevationProfile = elevationProfile; this.stayOn = stayOn; this.edges = List.copyOf(Objects.requireNonNull(edges)); @@ -130,6 +133,13 @@ public String getExit() { return exit; } + /** + * When entering or exiting a public transport station, the entrance name + */ + public String getEntrance() { + return entrance; + } + /** * Indicates whether a street changes direction at an intersection. */ diff --git a/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java b/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java index 25c6ee25b6b..8b5d2cedb11 100644 --- a/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java +++ b/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java @@ -25,6 +25,7 @@ public class WalkStepBuilder { private RelativeDirection relativeDirection; private ElevationProfile elevationProfile; private String exit; + private String entrance; private boolean stayOn = false; /** * Distance used for appending elevation profiles @@ -74,6 +75,11 @@ public WalkStepBuilder withExit(String exit) { return this; } + public WalkStepBuilder withEntrance(String entrance) { + this.entrance = entrance; + return this; + } + public WalkStepBuilder withStayOn(boolean stayOn) { this.stayOn = stayOn; return this; @@ -156,6 +162,7 @@ public WalkStep build() { directionText, streetNotes, exit, + entrance, elevationProfile, bogusName, walkingBike, diff --git a/src/main/java/org/opentripplanner/openstreetmap/model/OSMNode.java b/src/main/java/org/opentripplanner/openstreetmap/model/OSMNode.java index d181cde4564..371751d5e4a 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/model/OSMNode.java +++ b/src/main/java/org/opentripplanner/openstreetmap/model/OSMNode.java @@ -63,6 +63,15 @@ public boolean isBarrier() { ); } + /** + * Checks if this node is an subway station entrance + * + * @return true if it does + */ + public boolean isSubwayEntrance() { + return hasTag("railway") && "subway_entrance".equals(getTag("railway")); + } + /** * Consider barrier tag in permissions. Leave the rest for the super class. */ diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 94905bb840a..d49755bb548 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -26,6 +26,7 @@ import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.StreetTransitEntranceLink; import org.opentripplanner.street.model.vertex.ExitVertex; +import org.opentripplanner.street.model.vertex.StationEntranceVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.state.State; @@ -258,6 +259,8 @@ private void processState(State backState, State forwardState) { setMotorwayExit(backState); + setStationEntrance(backState); + if (createdNewStep && !modeTransition) { // check last three steps for zag int lastIndex = steps.size() - 1; @@ -380,6 +383,21 @@ private void setMotorwayExit(State backState) { } } + /** + * Update the walk step with the name of the station entrance if set from OSM + */ + private void setStationEntrance(State backState) { + State entranceState = backState; + Edge entranceEdge = entranceState.getBackEdge(); + while (entranceEdge instanceof FreeEdge) { + entranceState = entranceState.getBackState(); + entranceEdge = entranceState.getBackEdge(); + } + if (entranceState.getVertex() instanceof StationEntranceVertex) { + current.withEntrance(((StationEntranceVertex) entranceState.getVertex()).getEntranceName()); + } + } + /** * Is it possible to turn to another street from this previous state */ diff --git a/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java b/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java new file mode 100644 index 00000000000..af1e824a7bd --- /dev/null +++ b/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java @@ -0,0 +1,19 @@ +package org.opentripplanner.street.model.vertex; + +public class StationEntranceVertex extends OsmVertex { + + private final String entranceName; + + public StationEntranceVertex(double x, double y, long nodeId, String entranceName) { + super(x, y, nodeId); + this.entranceName = entranceName; + } + + public String getEntranceName() { + return entranceName; + } + + public String toString() { + return "StationEntranceVertex(" + super.toString() + ")"; + } +} diff --git a/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java b/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java index c7e38ca0032..3fe201070d4 100644 --- a/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java +++ b/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java @@ -103,6 +103,15 @@ public ExitVertex exit(long nid, Coordinate coordinate, String exitName) { return addToGraph(new ExitVertex(coordinate.x, coordinate.y, nid, exitName)); } + @Nonnull + public StationEntranceVertex stationEntrance( + long nid, + Coordinate coordinate, + String entranceName + ) { + return addToGraph(new StationEntranceVertex(coordinate.x, coordinate.y, nid, entranceName)); + } + @Nonnull public OsmVertex osm( Coordinate coordinate, diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 927af19f8b1..12decc1e3d5 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -2628,6 +2628,8 @@ type step { elevationProfile: [elevationProfileComponent] "When exiting a highway or traffic circle, the exit name/number." exit: String + "Name of entrance to a public transport station" + entrance: String "The latitude of the start of the step." lat: Float "The longitude of the start of the step." From 67f4b1b54ef64b40c0853bfd8e5d10a172534e72 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Wed, 2 Oct 2024 16:03:23 +0300 Subject: [PATCH 02/36] Add entity to walk steps --- .../apis/gtfs/GtfsGraphQLIndex.java | 2 ++ .../apis/gtfs/datafetchers/stepImpl.java | 4 ++-- .../gtfs/generated/GraphQLDataFetchers.java | 10 +++++++++- .../apis/gtfs/model/StepEntity.java | 19 +++++++++++++++++++ .../opentripplanner/model/plan/WalkStep.java | 13 +++++++------ .../model/plan/WalkStepBuilder.java | 10 ++++++---- .../mapping/StatesToWalkStepsMapper.java | 5 ++++- .../opentripplanner/apis/gtfs/schema.graphqls | 13 +++++++++++-- 8 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index 43a8399e70c..ed3242b5823 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -81,6 +81,7 @@ import org.opentripplanner.apis.gtfs.datafetchers.serviceTimeRangeImpl; import org.opentripplanner.apis.gtfs.datafetchers.stepImpl; import org.opentripplanner.apis.gtfs.datafetchers.stopAtDistanceImpl; +import org.opentripplanner.apis.gtfs.model.StepEntity; import org.opentripplanner.apis.gtfs.model.StopPosition; import org.opentripplanner.apis.support.graphql.LoggingDataFetcherExceptionHandler; import org.opentripplanner.ext.actuator.MicrometerGraphQLInstrumentation; @@ -124,6 +125,7 @@ protected static GraphQLSchema buildSchema() { .type("Node", type -> type.typeResolver(new NodeTypeResolver())) .type("PlaceInterface", type -> type.typeResolver(new PlaceInterfaceTypeResolver())) .type("StopPosition", type -> type.typeResolver(new StopPosition() {})) + .type("StepEntity", type -> type.typeResolver(new StepEntity() {})) .type("FareProduct", type -> type.typeResolver(new FareProductTypeResolver())) .type("AlertEntity", type -> type.typeResolver(new AlertEntityTypeResolver())) .type(typeWiring.build(AgencyImpl.class)) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index d79e224e51e..658f2d321ad 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -54,8 +54,8 @@ public DataFetcher exit() { } @Override - public DataFetcher entrance() { - return environment -> getSource(environment).getEntrance(); + public DataFetcher entity() { + return environment -> getSource(environment).getEntity(); } @Override diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 3c162b14112..efc59f72d42 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -365,6 +365,11 @@ public interface GraphQLEmissions { public DataFetcher co2(); } + /** Station entrance/exit */ + public interface GraphQLEntrance { + public DataFetcher name(); + } + /** A 'medium' that a fare product applies to, for example cash, 'Oyster Card' or 'DB Navigator App'. */ public interface GraphQLFareMedium { public DataFetcher id(); @@ -977,6 +982,9 @@ public interface GraphQLRoutingError { public DataFetcher inputField(); } + /** Entity to a step */ + public interface GraphQLStepEntity extends TypeResolver {} + /** * Stop can represent either a single public transport stop, where passengers can * board and/or disembark vehicles, or a station, which contains multiple stops. @@ -1428,7 +1436,7 @@ public interface GraphQLStep { public DataFetcher> elevationProfile(); - public DataFetcher entrance(); + public DataFetcher entity(); public DataFetcher exit(); diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java b/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java new file mode 100644 index 00000000000..5e10f4e08a6 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java @@ -0,0 +1,19 @@ +package org.opentripplanner.apis.gtfs.model; + +import graphql.TypeResolutionEnvironment; +import graphql.schema.GraphQLObjectType; +import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; + +public interface StepEntity extends GraphQLDataFetchers.GraphQLStepEntity { + record Entrance(String name) implements StepEntity {} + + @Override + default GraphQLObjectType getType(TypeResolutionEnvironment env) { + var schema = env.getSchema(); + Object o = env.getObject(); + if (o instanceof Entrance) { + return schema.getObjectType("Entrance"); + } + return null; + } +} diff --git a/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/src/main/java/org/opentripplanner/model/plan/WalkStep.java index 9a650ecef3e..3e9e9fe14dc 100644 --- a/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -4,6 +4,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import org.opentripplanner.apis.gtfs.model.StepEntity; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.lang.DoubleUtils; @@ -44,7 +45,7 @@ public final class WalkStep { private final boolean walkingBike; private final String exit; - private final String entrance; + private final StepEntity entity; private final ElevationProfile elevationProfile; private final boolean stayOn; @@ -57,7 +58,7 @@ public final class WalkStep { I18NString directionText, Set streetNotes, String exit, - String entrance, + StepEntity entity, ElevationProfile elevationProfile, boolean bogusName, boolean walkingBike, @@ -78,7 +79,7 @@ public final class WalkStep { this.walkingBike = walkingBike; this.area = area; this.exit = exit; - this.entrance = entrance; + this.entity = entity; this.elevationProfile = elevationProfile; this.stayOn = stayOn; this.edges = List.copyOf(Objects.requireNonNull(edges)); @@ -134,10 +135,10 @@ public String getExit() { } /** - * When entering or exiting a public transport station, the entrance name + * Entity related to a step e.g. building entrance/exit. */ - public String getEntrance() { - return entrance; + public Object getEntity() { + return entity; } /** diff --git a/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java b/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java index 8b5d2cedb11..d020f8d0113 100644 --- a/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java +++ b/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java @@ -5,6 +5,8 @@ import java.util.List; import java.util.Set; import javax.annotation.Nullable; +import org.opentripplanner.apis.gtfs.model.StepEntity; +import org.opentripplanner.apis.gtfs.model.StepEntity.Entrance; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.lang.DoubleUtils; @@ -25,7 +27,7 @@ public class WalkStepBuilder { private RelativeDirection relativeDirection; private ElevationProfile elevationProfile; private String exit; - private String entrance; + private StepEntity entity; private boolean stayOn = false; /** * Distance used for appending elevation profiles @@ -75,8 +77,8 @@ public WalkStepBuilder withExit(String exit) { return this; } - public WalkStepBuilder withEntrance(String entrance) { - this.entrance = entrance; + public WalkStepBuilder withEntrance(Entrance entrance) { + this.entity = entrance; return this; } @@ -162,7 +164,7 @@ public WalkStep build() { directionText, streetNotes, exit, - entrance, + entity, elevationProfile, bogusName, walkingBike, diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index d49755bb548..7e0ff3696ca 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -10,6 +10,7 @@ import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; +import org.opentripplanner.apis.gtfs.model.StepEntity.Entrance; import org.opentripplanner.framework.geometry.DirectionUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; @@ -394,7 +395,9 @@ private void setStationEntrance(State backState) { entranceEdge = entranceState.getBackEdge(); } if (entranceState.getVertex() instanceof StationEntranceVertex) { - current.withEntrance(((StationEntranceVertex) entranceState.getVertex()).getEntranceName()); + current.withEntrance( + new Entrance(((StationEntranceVertex) entranceState.getVertex()).getEntranceName()) + ); } } diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 12decc1e3d5..b9b3fddb6e4 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -2607,6 +2607,15 @@ type serviceTimeRange { start: Long } +"Station entrance/exit" +type Entrance { + "Name of a station entrance/exit" + name: String +} + +"Entity to a step" +union StepEntity = Entrance + type step { "The cardinal (compass) direction (e.g. north, northeast) taken when engaging this step." absoluteDirection: AbsoluteDirection @@ -2628,8 +2637,6 @@ type step { elevationProfile: [elevationProfileComponent] "When exiting a highway or traffic circle, the exit name/number." exit: String - "Name of entrance to a public transport station" - entrance: String "The latitude of the start of the step." lat: Float "The longitude of the start of the step." @@ -2642,6 +2649,8 @@ type step { streetName: String "Is this step walking with a bike?" walkingBike: Boolean + "Step entity e.g. an entrance" + entity: StepEntity } type stopAtDistance implements Node { From 9d18269db5311d5802b79e0410ece8fd24e6583b Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Thu, 3 Oct 2024 14:52:42 +0300 Subject: [PATCH 03/36] Add more parameters to Entrance --- .../apis/gtfs/generated/GraphQLDataFetchers.java | 4 ++++ .../org/opentripplanner/apis/gtfs/model/StepEntity.java | 6 +++++- .../routing/algorithm/mapping/StatesToWalkStepsMapper.java | 6 ++++-- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 6 +++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index efc59f72d42..dfe2527715f 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -367,6 +367,10 @@ public interface GraphQLEmissions { /** Station entrance/exit */ public interface GraphQLEntrance { + public DataFetcher code(); + + public DataFetcher gtfsId(); + public DataFetcher name(); } diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java b/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java index 5e10f4e08a6..e1f53cf6842 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java @@ -5,7 +5,11 @@ import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; public interface StepEntity extends GraphQLDataFetchers.GraphQLStepEntity { - record Entrance(String name) implements StepEntity {} + record Entrance(String code, String name, String gtfsId) implements StepEntity { + public static Entrance withCode(String code) { + return new Entrance(code, null, null); + } + } @Override default GraphQLObjectType getType(TypeResolutionEnvironment env) { diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 7e0ff3696ca..eeb091125aa 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -10,7 +10,7 @@ import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.apis.gtfs.model.StepEntity.Entrance; +import org.opentripplanner.apis.gtfs.model.StepEntity; import org.opentripplanner.framework.geometry.DirectionUtils; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; @@ -396,7 +396,9 @@ private void setStationEntrance(State backState) { } if (entranceState.getVertex() instanceof StationEntranceVertex) { current.withEntrance( - new Entrance(((StationEntranceVertex) entranceState.getVertex()).getEntranceName()) + StepEntity.Entrance.withCode( + ((StationEntranceVertex) entranceState.getVertex()).getEntranceName() + ) ); } } diff --git a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index b9b3fddb6e4..9fef54c3965 100644 --- a/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -2609,8 +2609,12 @@ type serviceTimeRange { "Station entrance/exit" type Entrance { - "Name of a station entrance/exit" + "Code of entrance/exit eg A or B" + code: String + "Name of entrance/exit" name: String + "Gtfs id of entrance/exit" + gtfsId: String } "Entity to a step" From 3b8828831c3e0409fbe3da49a7d238fa0888a884 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Mon, 7 Oct 2024 17:22:54 +0300 Subject: [PATCH 04/36] Move StepEntity classes --- .../apis/gtfs/GtfsGraphQLIndex.java | 4 +-- .../datafetchers/StepEntityTypeResolver.java | 30 +++++++++++++++++++ .../apis/gtfs/model/StepEntity.java | 23 -------------- .../opentripplanner/model/plan/Entrance.java | 18 +++++++++++ .../model/plan/StepEntity.java | 3 ++ .../opentripplanner/model/plan/WalkStep.java | 2 +- .../model/plan/WalkStepBuilder.java | 4 +-- .../mapping/StatesToWalkStepsMapper.java | 6 ++-- 8 files changed, 58 insertions(+), 32 deletions(-) create mode 100644 src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java delete mode 100644 src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java create mode 100644 src/main/java/org/opentripplanner/model/plan/Entrance.java create mode 100644 src/main/java/org/opentripplanner/model/plan/StepEntity.java diff --git a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index ed3242b5823..5b288762262 100644 --- a/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -58,6 +58,7 @@ import org.opentripplanner.apis.gtfs.datafetchers.RouteImpl; import org.opentripplanner.apis.gtfs.datafetchers.RouteTypeImpl; import org.opentripplanner.apis.gtfs.datafetchers.RoutingErrorImpl; +import org.opentripplanner.apis.gtfs.datafetchers.StepEntityTypeResolver; import org.opentripplanner.apis.gtfs.datafetchers.StopGeometriesImpl; import org.opentripplanner.apis.gtfs.datafetchers.StopImpl; import org.opentripplanner.apis.gtfs.datafetchers.StopOnRouteImpl; @@ -81,7 +82,6 @@ import org.opentripplanner.apis.gtfs.datafetchers.serviceTimeRangeImpl; import org.opentripplanner.apis.gtfs.datafetchers.stepImpl; import org.opentripplanner.apis.gtfs.datafetchers.stopAtDistanceImpl; -import org.opentripplanner.apis.gtfs.model.StepEntity; import org.opentripplanner.apis.gtfs.model.StopPosition; import org.opentripplanner.apis.support.graphql.LoggingDataFetcherExceptionHandler; import org.opentripplanner.ext.actuator.MicrometerGraphQLInstrumentation; @@ -125,7 +125,7 @@ protected static GraphQLSchema buildSchema() { .type("Node", type -> type.typeResolver(new NodeTypeResolver())) .type("PlaceInterface", type -> type.typeResolver(new PlaceInterfaceTypeResolver())) .type("StopPosition", type -> type.typeResolver(new StopPosition() {})) - .type("StepEntity", type -> type.typeResolver(new StepEntity() {})) + .type("StepEntity", type -> type.typeResolver(new StepEntityTypeResolver())) .type("FareProduct", type -> type.typeResolver(new FareProductTypeResolver())) .type("AlertEntity", type -> type.typeResolver(new AlertEntityTypeResolver())) .type(typeWiring.build(AgencyImpl.class)) diff --git a/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java new file mode 100644 index 00000000000..5fc8a123226 --- /dev/null +++ b/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java @@ -0,0 +1,30 @@ +package org.opentripplanner.apis.gtfs.datafetchers; + +import graphql.TypeResolutionEnvironment; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.TypeResolver; +import org.opentripplanner.apis.gtfs.model.RouteTypeModel; +import org.opentripplanner.apis.gtfs.model.StopOnRouteModel; +import org.opentripplanner.apis.gtfs.model.StopOnTripModel; +import org.opentripplanner.apis.gtfs.model.UnknownModel; +import org.opentripplanner.model.plan.Entrance; +import org.opentripplanner.transit.model.network.Route; +import org.opentripplanner.transit.model.network.TripPattern; +import org.opentripplanner.transit.model.organization.Agency; +import org.opentripplanner.transit.model.site.RegularStop; +import org.opentripplanner.transit.model.timetable.Trip; + +public class StepEntityTypeResolver implements TypeResolver { + + @Override + public GraphQLObjectType getType(TypeResolutionEnvironment environment) { + Object o = environment.getObject(); + GraphQLSchema schema = environment.getSchema(); + + if (o instanceof Entrance) { + return schema.getObjectType("Entrance"); + } + return null; + } +} diff --git a/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java b/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java deleted file mode 100644 index e1f53cf6842..00000000000 --- a/src/main/java/org/opentripplanner/apis/gtfs/model/StepEntity.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.opentripplanner.apis.gtfs.model; - -import graphql.TypeResolutionEnvironment; -import graphql.schema.GraphQLObjectType; -import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; - -public interface StepEntity extends GraphQLDataFetchers.GraphQLStepEntity { - record Entrance(String code, String name, String gtfsId) implements StepEntity { - public static Entrance withCode(String code) { - return new Entrance(code, null, null); - } - } - - @Override - default GraphQLObjectType getType(TypeResolutionEnvironment env) { - var schema = env.getSchema(); - Object o = env.getObject(); - if (o instanceof Entrance) { - return schema.getObjectType("Entrance"); - } - return null; - } -} diff --git a/src/main/java/org/opentripplanner/model/plan/Entrance.java b/src/main/java/org/opentripplanner/model/plan/Entrance.java new file mode 100644 index 00000000000..7b28ee992a4 --- /dev/null +++ b/src/main/java/org/opentripplanner/model/plan/Entrance.java @@ -0,0 +1,18 @@ +package org.opentripplanner.model.plan; + +public final class Entrance extends StepEntity { + + private final String code; + private final String gtfsId; + private final String name; + + public Entrance(String code, String gtfsId, String name) { + this.code = code; + this.gtfsId = gtfsId; + this.name = name; + } + + public static Entrance withCode(String code) { + return new Entrance(code, null, null); + } +} diff --git a/src/main/java/org/opentripplanner/model/plan/StepEntity.java b/src/main/java/org/opentripplanner/model/plan/StepEntity.java new file mode 100644 index 00000000000..e6bfd587bfc --- /dev/null +++ b/src/main/java/org/opentripplanner/model/plan/StepEntity.java @@ -0,0 +1,3 @@ +package org.opentripplanner.model.plan; + +public abstract class StepEntity {} diff --git a/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/src/main/java/org/opentripplanner/model/plan/WalkStep.java index 3e9e9fe14dc..8114246d7e8 100644 --- a/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -4,11 +4,11 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import org.opentripplanner.apis.gtfs.model.StepEntity; import org.opentripplanner.framework.geometry.WgsCoordinate; 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; diff --git a/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java b/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java index d020f8d0113..02b73c0ce15 100644 --- a/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java +++ b/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java @@ -5,12 +5,12 @@ import java.util.List; import java.util.Set; import javax.annotation.Nullable; -import org.opentripplanner.apis.gtfs.model.StepEntity; -import org.opentripplanner.apis.gtfs.model.StepEntity.Entrance; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.lang.DoubleUtils; import org.opentripplanner.framework.lang.IntUtils; +import org.opentripplanner.model.plan.Entrance; +import org.opentripplanner.model.plan.StepEntity; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.note.StreetNote; diff --git a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index eeb091125aa..158979f5d91 100644 --- a/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -10,11 +10,11 @@ import javax.annotation.Nonnull; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Geometry; -import org.opentripplanner.apis.gtfs.model.StepEntity; import org.opentripplanner.framework.geometry.DirectionUtils; 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; @@ -396,9 +396,7 @@ private void setStationEntrance(State backState) { } if (entranceState.getVertex() instanceof StationEntranceVertex) { current.withEntrance( - StepEntity.Entrance.withCode( - ((StationEntranceVertex) entranceState.getVertex()).getEntranceName() - ) + Entrance.withCode(((StationEntranceVertex) entranceState.getVertex()).getEntranceName()) ); } } From 0a62bf81363030d990ed9e0e5e596a479c3a5644 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Wed, 16 Oct 2024 18:19:55 +0300 Subject: [PATCH 05/36] Remove default name for subway station entrances --- .../graph_builder/module/osm/VertexGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java b/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java index df9c4376871..633d4343b83 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java @@ -100,7 +100,7 @@ IntersectionVertex getVertexForOsmNode(OSMNode node, OSMWithTags way) { if (ref != null) { iv = vertexFactory.stationEntrance(nid, coordinate, ref); } else { - iv = vertexFactory.stationEntrance(nid, coordinate, "MAIN_ENTRANCE"); + iv = vertexFactory.stationEntrance(nid, coordinate, null); } } From 528ab55927be6269d8dee5bfec52e1b0dcbf999d Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Fri, 18 Oct 2024 17:39:43 +0300 Subject: [PATCH 06/36] Add option to turn on osm subway entrances in osmDefaults --- doc/user/BuildConfiguration.md | 2 ++ .../module/configure/GraphBuilderModules.java | 2 ++ .../graph_builder/module/osm/OsmModule.java | 8 ++++++- .../module/osm/OsmModuleBuilder.java | 9 +++++++- .../module/osm/VertexGenerator.java | 11 ++++++++-- .../osm/parameters/OsmExtractParameters.java | 21 +++++++++++++++++-- .../OsmExtractParametersBuilder.java | 15 +++++++++++++ .../parameters/OsmProcessingParameters.java | 4 +++- .../openstreetmap/OsmProvider.java | 9 ++++++++ .../config/buildconfig/OsmConfig.java | 8 +++++++ .../module/osm/WalkableAreaBuilderTest.java | 2 +- 11 files changed, 83 insertions(+), 8 deletions(-) diff --git a/doc/user/BuildConfiguration.md b/doc/user/BuildConfiguration.md index b311991120e..7af5bbad1c5 100644 --- a/doc/user/BuildConfiguration.md +++ b/doc/user/BuildConfiguration.md @@ -84,10 +84,12 @@ Sections follow that describe particular settings in more depth. |    [sharedGroupFilePattern](#nd_sharedGroupFilePattern) | `regexp` | Pattern for matching shared group NeTEx files in a NeTEx bundle. | *Optional* | `"(\w{3})-.*-shared\.xml"` | 2.0 | |    [ferryIdsNotAllowedForBicycle](#nd_ferryIdsNotAllowedForBicycle) | `string[]` | List ferries which do not allow bikes. | *Optional* | | 2.0 | | [osm](#osm) | `object[]` | Configure properties for a given OpenStreetMap feed. | *Optional* | | 2.2 | +|       includeOsmSubwayEntrances | `boolean` | Whether to include subway entrances in the OSM data. Overrides the value specified in `osmDefaults`. | *Optional* | `false` | 2.2 | |       [osmTagMapping](#osm_0_osmTagMapping) | `enum` | The named set of mapping rules applied when parsing OSM tags. Overrides the value specified in `osmDefaults`. | *Optional* | `"default"` | 2.2 | |       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | |       timeZone | `time-zone` | The timezone used to resolve opening hours in OSM data. Overrides the value specified in `osmDefaults`. | *Optional* | | 2.2 | | osmDefaults | `object` | Default properties for OpenStreetMap feeds. | *Optional* | | 2.2 | +|    includeOsmSubwayEntrances | `boolean` | Whether to include subway entrances in the OSM data. | *Optional* | `false` | 2.2 | |    [osmTagMapping](#od_osmTagMapping) | `enum` | The named set of mapping rules applied when parsing OSM tags. | *Optional* | `"default"` | 2.2 | |    timeZone | `time-zone` | The timezone used to resolve opening hours in OSM data. | *Optional* | | 2.2 | | [transferRequests](RouteRequest.md) | `object[]` | Routing requests to use for pre-calculating stop-to-stop transfers. | *Optional* | | 2.1 | diff --git a/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java b/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java index 10d3a997579..169ac351c87 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/configure/GraphBuilderModules.java @@ -68,6 +68,7 @@ static OsmModule provideOpenStreetMapModule( osmConfiguredDataSource.dataSource(), osmConfiguredDataSource.config().osmTagMapper(), osmConfiguredDataSource.config().timeZone(), + osmConfiguredDataSource.config().includeOsmSubwayEntrances(), config.osmCacheDataInMem, issueStore ) @@ -83,6 +84,7 @@ static OsmModule provideOpenStreetMapModule( .withStaticBikeParkAndRide(config.staticBikeParkAndRide) .withMaxAreaNodes(config.maxAreaNodes) .withBoardingAreaRefTags(config.boardingLocationTags) + .withIncludeOsmSubwayEntrances(config.osmDefaults.includeOsmSubwayEntrances()) .withIssueStore(issueStore) .withStreetLimitationParameters(streetLimitationParameters) .build(); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java b/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java index 10c215ee448..cbdd3d7a7a2 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java @@ -71,7 +71,13 @@ public class OsmModule implements GraphBuilderModule { this.issueStore = issueStore; this.params = params; this.osmdb = new OsmDatabase(issueStore); - this.vertexGenerator = new VertexGenerator(osmdb, graph, params.boardingAreaRefTags()); + this.vertexGenerator = + new VertexGenerator( + osmdb, + graph, + params.boardingAreaRefTags(), + params.includeOsmSubwayEntrances() + ); this.normalizer = new SafetyValueNormalizer(graph, issueStore); this.streetLimitationParameters = Objects.requireNonNull(streetLimitationParameters); } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java b/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java index f0a40fa678f..29e8f8a1ae5 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModuleBuilder.java @@ -24,6 +24,7 @@ public class OsmModuleBuilder { private boolean platformEntriesLinking = false; private boolean staticParkAndRide = false; private boolean staticBikeParkAndRide = false; + private boolean includeOsmSubwayEntrances = false; private int maxAreaNodes; private StreetLimitationParameters streetLimitationParameters = new StreetLimitationParameters(); @@ -72,6 +73,11 @@ public OsmModuleBuilder withMaxAreaNodes(int maxAreaNodes) { return this; } + public OsmModuleBuilder withIncludeOsmSubwayEntrances(boolean includeOsmSubwayEntrances) { + this.includeOsmSubwayEntrances = includeOsmSubwayEntrances; + return this; + } + public OsmModuleBuilder withStreetLimitationParameters(StreetLimitationParameters parameters) { this.streetLimitationParameters = parameters; return this; @@ -90,7 +96,8 @@ public OsmModule build() { areaVisibility, platformEntriesLinking, staticParkAndRide, - staticBikeParkAndRide + staticBikeParkAndRide, + includeOsmSubwayEntrances ) ); } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java b/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java index 633d4343b83..87cd88a5227 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java @@ -33,12 +33,19 @@ class VertexGenerator { private final HashMap> multiLevelNodes = new HashMap<>(); private final OsmDatabase osmdb; private final Set boardingAreaRefTags; + private final Boolean includeOsmSubwayEntrances; private final VertexFactory vertexFactory; - public VertexGenerator(OsmDatabase osmdb, Graph graph, Set boardingAreaRefTags) { + public VertexGenerator( + OsmDatabase osmdb, + Graph graph, + Set boardingAreaRefTags, + boolean includeOsmSubwayEntrances + ) { this.osmdb = osmdb; this.vertexFactory = new VertexFactory(graph); this.boardingAreaRefTags = boardingAreaRefTags; + this.includeOsmSubwayEntrances = includeOsmSubwayEntrances; } /** @@ -95,7 +102,7 @@ IntersectionVertex getVertexForOsmNode(OSMNode node, OSMWithTags way) { iv = bv; } - if (node.isSubwayEntrance()) { + if (includeOsmSubwayEntrances && node.isSubwayEntrance()) { String ref = node.getTag("ref"); if (ref != null) { iv = vertexFactory.stationEntrance(nid, coordinate, ref); diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java b/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java index 9d2eead5f7e..1cae389d9c4 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java @@ -11,16 +11,28 @@ * Example: {@code "osm" : [ {source: "file:///path/to/otp/norway.pbf"} ] } * */ -public record OsmExtractParameters(URI source, OsmTagMapperSource osmTagMapper, ZoneId timeZone) +public record OsmExtractParameters( + URI source, + OsmTagMapperSource osmTagMapper, + ZoneId timeZone, + boolean includeOsmSubwayEntrances +) implements DataSourceConfig { public static final OsmTagMapperSource DEFAULT_OSM_TAG_MAPPER = OsmTagMapperSource.DEFAULT; public static final ZoneId DEFAULT_TIME_ZONE = null; + public static final boolean DEFAULT_INCLUDE_OSM_SUBWAY_ENTRANCES = false; + public static final OsmExtractParameters DEFAULT = new OsmExtractParametersBuilder().build(); OsmExtractParameters(OsmExtractParametersBuilder builder) { - this(builder.getSource(), builder.getOsmTagMapper(), builder.getTimeZone()); + this( + builder.getSource(), + builder.getOsmTagMapper(), + builder.getTimeZone(), + builder.getIncludeOsmSubwayEntrances() + ); } @Override @@ -37,6 +49,11 @@ public ZoneId timeZone() { return timeZone; } + @Nullable + public boolean includeOsmSubwayEntrances() { + return includeOsmSubwayEntrances; + } + public OsmExtractParametersBuilder copyOf() { return new OsmExtractParametersBuilder(this); } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java b/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java index 03fd7eaec4e..0bbc184569d 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java @@ -24,14 +24,18 @@ public class OsmExtractParametersBuilder { */ private ZoneId timeZone; + private boolean includeOsmSubwayEntrances; + public OsmExtractParametersBuilder() { this.osmTagMapper = OsmExtractParameters.DEFAULT_OSM_TAG_MAPPER; this.timeZone = OsmExtractParameters.DEFAULT_TIME_ZONE; + this.includeOsmSubwayEntrances = OsmExtractParameters.DEFAULT_INCLUDE_OSM_SUBWAY_ENTRANCES; } public OsmExtractParametersBuilder(OsmExtractParameters original) { this.osmTagMapper = original.osmTagMapper(); this.timeZone = original.timeZone(); + this.includeOsmSubwayEntrances = original.includeOsmSubwayEntrances(); } public OsmExtractParametersBuilder withSource(URI source) { @@ -49,6 +53,13 @@ public OsmExtractParametersBuilder withTimeZone(ZoneId timeZone) { return this; } + public OsmExtractParametersBuilder withIncludeOsmSubwayEntrances( + boolean includeOsmSubwayEntrances + ) { + this.includeOsmSubwayEntrances = includeOsmSubwayEntrances; + return this; + } + public URI getSource() { return source; } @@ -61,6 +72,10 @@ public ZoneId getTimeZone() { return timeZone; } + public boolean getIncludeOsmSubwayEntrances() { + return includeOsmSubwayEntrances; + } + public OsmExtractParameters build() { return new OsmExtractParameters(this); } diff --git a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java b/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java index 52bf8d65314..a3fd14020e8 100644 --- a/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java +++ b/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmProcessingParameters.java @@ -13,6 +13,7 @@ * @param platformEntriesLinking Whether platform entries should be linked * @param staticParkAndRide Whether we should create car P+R stations from OSM data. * @param staticBikeParkAndRide Whether we should create bike P+R stations from OSM data. + * @param includeOsmSubwayEntrances Whether we should create subway entrances from OSM data. */ public record OsmProcessingParameters( Set boardingAreaRefTags, @@ -21,7 +22,8 @@ public record OsmProcessingParameters( boolean areaVisibility, boolean platformEntriesLinking, boolean staticParkAndRide, - boolean staticBikeParkAndRide + boolean staticBikeParkAndRide, + boolean includeOsmSubwayEntrances ) { public OsmProcessingParameters { boardingAreaRefTags = Set.copyOf(Objects.requireNonNull(boardingAreaRefTags)); diff --git a/src/main/java/org/opentripplanner/openstreetmap/OsmProvider.java b/src/main/java/org/opentripplanner/openstreetmap/OsmProvider.java index e35a846cbbd..d66f5db394b 100644 --- a/src/main/java/org/opentripplanner/openstreetmap/OsmProvider.java +++ b/src/main/java/org/opentripplanner/openstreetmap/OsmProvider.java @@ -37,6 +37,8 @@ public class OsmProvider { private final OsmTagMapper osmTagMapper; + private boolean includeOsmSubwayEntrances = false; + private final WayPropertySet wayPropertySet; private byte[] cachedBytes = null; @@ -46,6 +48,7 @@ public OsmProvider(File file, boolean cacheDataInMem) { new FileDataSource(file, FileType.OSM), OsmTagMapperSource.DEFAULT, null, + false, cacheDataInMem, DataImportIssueStore.NOOP ); @@ -55,11 +58,13 @@ public OsmProvider( DataSource dataSource, OsmTagMapperSource tagMapperSource, ZoneId zoneId, + boolean includeOsmSubwayEntrances, boolean cacheDataInMem, DataImportIssueStore issueStore ) { this.source = dataSource; this.zoneId = zoneId; + this.includeOsmSubwayEntrances = includeOsmSubwayEntrances; this.osmTagMapper = tagMapperSource.getInstance(); this.wayPropertySet = new WayPropertySet(issueStore); osmTagMapper.populateProperties(wayPropertySet); @@ -152,6 +157,10 @@ public OsmTagMapper getOsmTagMapper() { return osmTagMapper; } + public boolean getIncludeOsmSubwayEntrances() { + return includeOsmSubwayEntrances; + } + public WayPropertySet getWayPropertySet() { return wayPropertySet; } diff --git a/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java b/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java index 1b2ec0ed74d..c1a3963c6a5 100644 --- a/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java +++ b/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java @@ -84,6 +84,14 @@ public static OsmExtractParametersBuilder mapOsmGenericParameters( ) .docDefaultValue(docDefaults.timeZone()) .asZoneId(defaults.timeZone()) + ) + .withIncludeOsmSubwayEntrances( + node + .of("includeOsmSubwayEntrances") + .since(V2_2) + .summary("Whether to include subway entrances from the OSM data." + documentationAddition) + .docDefaultValue(docDefaults.includeOsmSubwayEntrances()) + .asBoolean(defaults.includeOsmSubwayEntrances()) ); } } diff --git a/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java b/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java index 4906bce930d..26500299062 100644 --- a/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java +++ b/src/test/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilderTest.java @@ -48,7 +48,7 @@ public Graph buildGraph(final TestInfo testInfo) { final WalkableAreaBuilder walkableAreaBuilder = new WalkableAreaBuilder( graph, osmdb, - new VertexGenerator(osmdb, graph, Set.of()), + new VertexGenerator(osmdb, graph, Set.of(), false), new DefaultNamer(), new SafetyValueNormalizer(graph, DataImportIssueStore.NOOP), DataImportIssueStore.NOOP, From 401a405cd9000a5f1ebb92bb9ba130f8a6ff0fcd Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Mon, 21 Oct 2024 18:41:18 +0300 Subject: [PATCH 07/36] Fix walk step generation --- .../mapping/StatesToWalkStepsMapper.java | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 9202c94c76a..6bcef1b0da9 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -177,6 +177,9 @@ private void processState(State backState, State forwardState) { if (edge instanceof ElevatorAlightEdge) { addStep(createElevatorWalkStep(backState, forwardState, edge)); return; + } else if (backState.getVertex() instanceof StationEntranceVertex) { + addStep(createStationEntranceWalkStep(backState, forwardState, edge)); + return; } else if (edge instanceof PathwayEdge pwe && pwe.signpostedAs().isPresent()) { createAndSaveStep(backState, forwardState, pwe.signpostedAs().get(), FOLLOW_SIGNS, edge); return; @@ -259,8 +262,6 @@ private void processState(State backState, State forwardState) { setMotorwayExit(backState); - setStationEntrance(backState); - if (createdNewStep && !modeTransition) { // check last three steps for zag int lastIndex = steps.size() - 1; @@ -382,23 +383,6 @@ private void setMotorwayExit(State backState) { } } - /** - * Update the walk step with the name of the station entrance if set from OSM - */ - private void setStationEntrance(State backState) { - State entranceState = backState; - Edge entranceEdge = entranceState.getBackEdge(); - while (entranceEdge instanceof FreeEdge) { - entranceState = entranceState.getBackState(); - entranceEdge = entranceState.getBackEdge(); - } - if (entranceState.getVertex() instanceof StationEntranceVertex) { - current.withEntrance( - Entrance.withCode(((StationEntranceVertex) entranceState.getVertex()).getEntranceName()) - ); - } - } - /** * Is it possible to turn to another street from this previous state */ @@ -536,6 +520,22 @@ private WalkStepBuilder createElevatorWalkStep(State backState, State forwardSta return step; } + private WalkStepBuilder createStationEntranceWalkStep( + State backState, + State forwardState, + Edge edge + ) { + // don't care what came before or comes after + var step = createWalkStep(forwardState, backState); + + step.withRelativeDirection(RelativeDirection.CONTINUE); + + step.withEntrance( + Entrance.withCode(((StationEntranceVertex) backState.getVertex()).getEntranceName()) + ); + return step; + } + private void createAndSaveStep( State backState, State forwardState, From 438bc318faa6ef96c1ef78f997005b631910c6fd Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Wed, 23 Oct 2024 20:14:01 +0300 Subject: [PATCH 08/36] Add step entity to graphql tests --- .../apis/gtfs/GraphQLIntegrationTest.java | 8 +++++++- .../apis/gtfs/expectations/walk-steps.json | 17 +++++++++++++++-- .../apis/gtfs/queries/walk-steps.graphql | 6 ++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index 663ce2d5f3f..020a1ec6113 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -49,6 +49,7 @@ import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.fare.RiderCategory; import org.opentripplanner.model.plan.Emissions; +import org.opentripplanner.model.plan.Entrance; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.RelativeDirection; @@ -232,8 +233,13 @@ public Set getRoutesForStop(StopLocation stop) { .build(); var step2 = walkStep("elevator").withRelativeDirection(RelativeDirection.ELEVATOR).build(); + var step3 = walkStep("entrance") + .withRelativeDirection(RelativeDirection.CONTINUE) + .withEntrance(Entrance.withCode("A")) + .build(); + Itinerary i1 = newItinerary(A, T11_00) - .walk(20, B, List.of(step1, step2)) + .walk(20, B, List.of(step1, step2, step3)) .bus(busRoute, 122, T11_01, T11_15, C) .rail(439, T11_30, T11_50, D) .carHail(D10m, E) diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json index be584a875be..b4172c0f70f 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json @@ -11,13 +11,26 @@ "streetName" : "street", "area" : false, "relativeDirection" : "DEPART", - "absoluteDirection" : "NORTHEAST" + "absoluteDirection" : "NORTHEAST", + "entity" : null }, { "streetName" : "elevator", "area" : false, "relativeDirection" : "ELEVATOR", - "absoluteDirection" : null + "absoluteDirection" : null, + "entity" : null + + }, + { + "streetName" : "entrance", + "area" : false, + "relativeDirection" : "CONTINUE", + "absoluteDirection" : null, + "entity" : { + "__typename" : "Entrance", + "code": "A" + } } ] }, diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql index dd2b96395ad..74cbe0c599e 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql @@ -20,6 +20,12 @@ area relativeDirection absoluteDirection + entity { + __typename + ... on Entrance { + code + } + } } } } From 97c2de6ac34d7315ffb07555f011b4aeacd52cfa Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Fri, 25 Oct 2024 15:15:02 +0300 Subject: [PATCH 09/36] Rename variables to match with graphql --- .../algorithm/mapping/StatesToWalkStepsMapper.java | 6 ++---- .../street/model/vertex/StationEntranceVertex.java | 12 ++++++------ 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 6bcef1b0da9..8a289713532 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -529,10 +529,8 @@ private WalkStepBuilder createStationEntranceWalkStep( var step = createWalkStep(forwardState, backState); step.withRelativeDirection(RelativeDirection.CONTINUE); - - step.withEntrance( - Entrance.withCode(((StationEntranceVertex) backState.getVertex()).getEntranceName()) - ); + System.out.println(backState.getVertex().toString()); + step.withEntrance(Entrance.withCode(((StationEntranceVertex) backState.getVertex()).getCode())); return step; } diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java index af1e824a7bd..083c0d52a0f 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java @@ -2,18 +2,18 @@ public class StationEntranceVertex extends OsmVertex { - private final String entranceName; + private final String code; - public StationEntranceVertex(double x, double y, long nodeId, String entranceName) { + public StationEntranceVertex(double x, double y, long nodeId, String code) { super(x, y, nodeId); - this.entranceName = entranceName; + this.code = code; } - public String getEntranceName() { - return entranceName; + public String getCode() { + return code; } public String toString() { - return "StationEntranceVertex(" + super.toString() + ")"; + return "StationEntranceVertex(" + super.toString() + ", code=" + code + ")"; } } From d844561b9d4a5f98d11a4f8eaabe63fe1b461a42 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Fri, 25 Oct 2024 16:10:14 +0300 Subject: [PATCH 10/36] Rename variables --- .../street/model/vertex/VertexFactory.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java b/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java index 007d3119a55..61f74841245 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java @@ -94,12 +94,8 @@ public ExitVertex exit(long nid, Coordinate coordinate, String exitName) { return addToGraph(new ExitVertex(coordinate.x, coordinate.y, nid, exitName)); } - public StationEntranceVertex stationEntrance( - long nid, - Coordinate coordinate, - String entranceName - ) { - return addToGraph(new StationEntranceVertex(coordinate.x, coordinate.y, nid, entranceName)); + public StationEntranceVertex stationEntrance(long nid, Coordinate coordinate, String code) { + return addToGraph(new StationEntranceVertex(coordinate.x, coordinate.y, nid, code)); } public OsmVertex osm( From 02a07ea2ed91ade71e5d4e5384a5e93fcf31ea67 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Sun, 27 Oct 2024 12:39:45 +0200 Subject: [PATCH 11/36] Rename function --- .../module/osm/parameters/OsmExtractParameters.java | 2 +- .../module/osm/parameters/OsmExtractParametersBuilder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java index 6e8ff0f793c..37edaf687ab 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java @@ -31,7 +31,7 @@ public record OsmExtractParameters( builder.getSource(), builder.getOsmTagMapper(), builder.getTimeZone(), - builder.getIncludeOsmSubwayEntrances() + builder.includeOsmSubwayEntrances() ); } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java index 9abc6e6bcc7..66c65e05d81 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParametersBuilder.java @@ -72,7 +72,7 @@ public ZoneId getTimeZone() { return timeZone; } - public boolean getIncludeOsmSubwayEntrances() { + public boolean includeOsmSubwayEntrances() { return includeOsmSubwayEntrances; } From 5dc74dd48555935dcd1deddcf39de0d4b73eaac0 Mon Sep 17 00:00:00 2001 From: Henrik Sundell <47221103+HenrikSundell@users.noreply.github.com> Date: Mon, 28 Oct 2024 15:05:39 +0200 Subject: [PATCH 12/36] Fix comments Co-authored-by: Joel Lappalainen --- .../java/org/opentripplanner/osm/model/OsmNode.java | 4 ++-- .../org/opentripplanner/apis/gtfs/schema.graphqls | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/osm/model/OsmNode.java b/application/src/main/java/org/opentripplanner/osm/model/OsmNode.java index 2c343401adf..cb9fcd679f0 100644 --- a/application/src/main/java/org/opentripplanner/osm/model/OsmNode.java +++ b/application/src/main/java/org/opentripplanner/osm/model/OsmNode.java @@ -64,9 +64,9 @@ public boolean isBarrier() { } /** - * Checks if this node is an subway station entrance + * Checks if this node is a subway station entrance. * - * @return true if it does + * @return true if it is */ public boolean isSubwayEntrance() { return hasTag("railway") && "subway_entrance".equals(getTag("railway")); diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 9c4d0e4dab1..b2d48f7e0b1 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -447,13 +447,13 @@ type Emissions { co2: Grams } -"Station entrance/exit" +"Station entrance or exit." type Entrance { - "Code of entrance/exit eg A or B" + "Short text or a number that identifies the entrance or exit for passengers. For example, `A` or `B`." code: String - "Gtfs id of entrance/exit" + "ID of the entrance in the format of `FeedId:EntranceId`." gtfsId: String - "Name of entrance/exit" + "Name of the entrance or exit." name: String } @@ -2658,7 +2658,7 @@ type step { distance: Float "The elevation profile as a list of { distance, elevation } values." elevationProfile: [elevationProfileComponent] - "Step entity e.g. an entrance" + "Step entity, e.g. an entrance." entity: StepEntity "When exiting a highway or traffic circle, the exit name/number." exit: String From 5d55646ab1861c7553d7a7b3b9f91a5d328bbd59 Mon Sep 17 00:00:00 2001 From: Henrik Sundell <47221103+HenrikSundell@users.noreply.github.com> Date: Mon, 28 Oct 2024 15:06:35 +0200 Subject: [PATCH 13/36] Remove println Co-authored-by: Joel Lappalainen --- .../routing/algorithm/mapping/StatesToWalkStepsMapper.java | 1 - 1 file changed, 1 deletion(-) diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 8a289713532..f04a6a5a2d9 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -529,7 +529,6 @@ private WalkStepBuilder createStationEntranceWalkStep( var step = createWalkStep(forwardState, backState); step.withRelativeDirection(RelativeDirection.CONTINUE); - System.out.println(backState.getVertex().toString()); step.withEntrance(Entrance.withCode(((StationEntranceVertex) backState.getVertex()).getCode())); return step; } From d1067c6679a68ee252f8bda96300d28dee8cfe75 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Mon, 28 Oct 2024 16:06:52 +0200 Subject: [PATCH 14/36] Remove unnecessary imports --- .../apis/gtfs/datafetchers/StepEntityTypeResolver.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java index 5fc8a123226..5e7d6098344 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java @@ -4,16 +4,7 @@ import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; import graphql.schema.TypeResolver; -import org.opentripplanner.apis.gtfs.model.RouteTypeModel; -import org.opentripplanner.apis.gtfs.model.StopOnRouteModel; -import org.opentripplanner.apis.gtfs.model.StopOnTripModel; -import org.opentripplanner.apis.gtfs.model.UnknownModel; import org.opentripplanner.model.plan.Entrance; -import org.opentripplanner.transit.model.network.Route; -import org.opentripplanner.transit.model.network.TripPattern; -import org.opentripplanner.transit.model.organization.Agency; -import org.opentripplanner.transit.model.site.RegularStop; -import org.opentripplanner.transit.model.timetable.Trip; public class StepEntityTypeResolver implements TypeResolver { From 5c97ad17f610d7458d6ff5e1a79c1b03ac643f18 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Mon, 28 Oct 2024 18:40:41 +0200 Subject: [PATCH 15/36] Add accessibilty information to entrances --- .../apis/gtfs/generated/GraphQLDataFetchers.java | 13 +++---------- .../graph_builder/module/osm/VertexGenerator.java | 8 +++----- .../org/opentripplanner/model/plan/Entrance.java | 8 +++++--- .../algorithm/mapping/StatesToWalkStepsMapper.java | 4 +++- .../street/model/vertex/StationEntranceVertex.java | 8 +++++++- .../street/model/vertex/VertexFactory.java | 9 +++++++-- .../org/opentripplanner/apis/gtfs/schema.graphqls | 2 ++ .../apis/gtfs/GraphQLIntegrationTest.java | 2 +- .../apis/gtfs/expectations/walk-steps.json | 3 ++- .../apis/gtfs/queries/walk-steps.graphql | 1 + 10 files changed, 34 insertions(+), 24 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 179758bd78d..ec0e573d705 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -1,11 +1,9 @@ //THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. package org.opentripplanner.apis.gtfs.generated; -import graphql.relay.Connection; import graphql.relay.Connection; import graphql.relay.DefaultEdge; import graphql.relay.Edge; -import graphql.relay.Edge; import graphql.schema.DataFetcher; import graphql.schema.TypeResolver; import java.util.Currency; @@ -27,12 +25,8 @@ import org.opentripplanner.apis.gtfs.model.FeedPublisher; import org.opentripplanner.apis.gtfs.model.PlanPageInfo; import org.opentripplanner.apis.gtfs.model.RideHailingProvider; -import org.opentripplanner.apis.gtfs.model.RouteTypeModel; -import org.opentripplanner.apis.gtfs.model.StopOnRouteModel; -import org.opentripplanner.apis.gtfs.model.StopOnTripModel; import org.opentripplanner.apis.gtfs.model.StopPosition; import org.opentripplanner.apis.gtfs.model.TripOccupancy; -import org.opentripplanner.apis.gtfs.model.UnknownModel; import org.opentripplanner.ext.fares.model.FareRuleSet; import org.opentripplanner.ext.ridehailing.model.RideEstimate; import org.opentripplanner.model.StopTimesInPattern; @@ -55,8 +49,6 @@ import org.opentripplanner.routing.graphfinder.PatternAtStop; import org.opentripplanner.routing.graphfinder.PlaceAtDistance; import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.routing.vehicle_parking.VehicleParking; import org.opentripplanner.routing.vehicle_parking.VehicleParkingSpaces; import org.opentripplanner.routing.vehicle_parking.VehicleParkingState; import org.opentripplanner.service.realtimevehicles.model.RealtimeVehicle; @@ -67,7 +59,6 @@ import org.opentripplanner.service.vehiclerental.model.VehicleRentalPlace; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStation; import org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris; -import org.opentripplanner.service.vehiclerental.model.VehicleRentalStationUris; import org.opentripplanner.service.vehiclerental.model.VehicleRentalSystem; import org.opentripplanner.service.vehiclerental.model.VehicleRentalVehicle; import org.opentripplanner.transit.model.basic.Money; @@ -366,8 +357,10 @@ public interface GraphQLEmissions { public DataFetcher co2(); } - /** Station entrance/exit */ + /** Station entrance or exit. */ public interface GraphQLEntrance { + public DataFetcher accessible(); + public DataFetcher code(); public DataFetcher gtfsId(); diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java index 42bbaf659c1..b4c3c08aa8b 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/VertexGenerator.java @@ -104,11 +104,9 @@ IntersectionVertex getVertexForOsmNode(OsmNode node, OsmWithTags way) { if (includeOsmSubwayEntrances && node.isSubwayEntrance()) { String ref = node.getTag("ref"); - if (ref != null) { - iv = vertexFactory.stationEntrance(nid, coordinate, ref); - } else { - iv = vertexFactory.stationEntrance(nid, coordinate, null); - } + + boolean accessible = node.isTag("wheelchair", "yes"); + iv = vertexFactory.stationEntrance(nid, coordinate, ref, accessible); } if (iv == null) { diff --git a/application/src/main/java/org/opentripplanner/model/plan/Entrance.java b/application/src/main/java/org/opentripplanner/model/plan/Entrance.java index 7b28ee992a4..fa1e0fe5e57 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/Entrance.java +++ b/application/src/main/java/org/opentripplanner/model/plan/Entrance.java @@ -5,14 +5,16 @@ public final class Entrance extends StepEntity { private final String code; private final String gtfsId; private final String name; + private final boolean accessible; - public Entrance(String code, String gtfsId, String name) { + public Entrance(String code, String gtfsId, String name, boolean accessible) { this.code = code; this.gtfsId = gtfsId; this.name = name; + this.accessible = accessible; } - public static Entrance withCode(String code) { - return new Entrance(code, null, null); + public static Entrance withCodeAndAccessible(String code, boolean accessible) { + return new Entrance(code, null, null, accessible); } } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index f04a6a5a2d9..14ed2a553e4 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -529,7 +529,9 @@ private WalkStepBuilder createStationEntranceWalkStep( var step = createWalkStep(forwardState, backState); step.withRelativeDirection(RelativeDirection.CONTINUE); - step.withEntrance(Entrance.withCode(((StationEntranceVertex) backState.getVertex()).getCode())); + + StationEntranceVertex vertex = (StationEntranceVertex) backState.getVertex(); + step.withEntrance(Entrance.withCodeAndAccessible(vertex.getCode(), vertex.isAccessible())); return step; } diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java index 083c0d52a0f..3f83a356dea 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java @@ -3,16 +3,22 @@ public class StationEntranceVertex extends OsmVertex { private final String code; + private final boolean accessible; - public StationEntranceVertex(double x, double y, long nodeId, String code) { + public StationEntranceVertex(double x, double y, long nodeId, String code, boolean accessible) { super(x, y, nodeId); this.code = code; + this.accessible = accessible; } public String getCode() { return code; } + public boolean isAccessible() { + return accessible; + } + public String toString() { return "StationEntranceVertex(" + super.toString() + ", code=" + code + ")"; } diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java b/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java index 61f74841245..1c37d39adb6 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/VertexFactory.java @@ -94,8 +94,13 @@ public ExitVertex exit(long nid, Coordinate coordinate, String exitName) { return addToGraph(new ExitVertex(coordinate.x, coordinate.y, nid, exitName)); } - public StationEntranceVertex stationEntrance(long nid, Coordinate coordinate, String code) { - return addToGraph(new StationEntranceVertex(coordinate.x, coordinate.y, nid, code)); + public StationEntranceVertex stationEntrance( + long nid, + Coordinate coordinate, + String code, + boolean accessible + ) { + return addToGraph(new StationEntranceVertex(coordinate.x, coordinate.y, nid, code, accessible)); } public OsmVertex osm( diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index b2d48f7e0b1..83c32e2c1ca 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -449,6 +449,8 @@ type Emissions { "Station entrance or exit." 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`." diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index 020a1ec6113..d2448a92c59 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -235,7 +235,7 @@ public Set getRoutesForStop(StopLocation stop) { var step3 = walkStep("entrance") .withRelativeDirection(RelativeDirection.CONTINUE) - .withEntrance(Entrance.withCode("A")) + .withEntrance(Entrance.withCodeAndAccessible("A", true)) .build(); Itinerary i1 = newItinerary(A, T11_00) diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json index b4172c0f70f..3a8e952880f 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json @@ -29,7 +29,8 @@ "absoluteDirection" : null, "entity" : { "__typename" : "Entrance", - "code": "A" + "code": "A", + "accessible": true } } ] diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql index 74cbe0c599e..5e7c0493c35 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql @@ -24,6 +24,7 @@ __typename ... on Entrance { code + accessible } } } From e10e0a2fae17e16cfebb1e888652a531e7fef493 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Thu, 7 Nov 2024 13:22:19 +0200 Subject: [PATCH 16/36] Use existing entrance class for walk steps --- .../mapping/RelativeDirectionMapper.java | 1 + .../restapi/model/ApiRelativeDirection.java | 1 + .../apis/gtfs/GtfsGraphQLIndex.java | 4 +- .../apis/gtfs/datafetchers/EntranceImpl.java | 53 +++++++++++++++++++ .../datafetchers/StepEntityTypeResolver.java | 2 +- .../apis/gtfs/datafetchers/stepImpl.java | 4 +- .../gtfs/generated/GraphQLDataFetchers.java | 9 ++-- .../apis/gtfs/generated/GraphQLTypes.java | 1 + .../apis/gtfs/mapping/DirectionMapper.java | 1 + .../opentripplanner/model/plan/Entrance.java | 20 ------- .../model/plan/RelativeDirection.java | 1 + .../model/plan/StepEntity.java | 3 -- .../opentripplanner/model/plan/WalkStep.java | 14 ++--- .../model/plan/WalkStepBuilder.java | 9 ++-- .../mapping/StatesToWalkStepsMapper.java | 17 ++++-- .../framework/AbstractTransitEntity.java | 2 +- .../opentripplanner/apis/gtfs/schema.graphqls | 12 ++--- .../apis/gtfs/GraphQLIntegrationTest.java | 14 +++-- .../apis/gtfs/expectations/walk-steps.json | 11 ++-- .../apis/gtfs/queries/walk-steps.graphql | 9 ++-- 20 files changed, 115 insertions(+), 73 deletions(-) create mode 100644 application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java delete mode 100644 application/src/main/java/org/opentripplanner/model/plan/Entrance.java delete mode 100644 application/src/main/java/org/opentripplanner/model/plan/StepEntity.java diff --git a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java index a1bdd145a55..708da1fd6c3 100644 --- a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java @@ -25,6 +25,7 @@ public static ApiRelativeDirection mapRelativeDirection(RelativeDirection domain case UTURN_RIGHT -> ApiRelativeDirection.UTURN_RIGHT; case ENTER_STATION -> ApiRelativeDirection.ENTER_STATION; case EXIT_STATION -> ApiRelativeDirection.EXIT_STATION; + case ENTER_OR_EXIT_STATION -> ApiRelativeDirection.ENTER_OR_EXIT_STATION; case FOLLOW_SIGNS -> ApiRelativeDirection.FOLLOW_SIGNS; }; } diff --git a/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java index 02a530f06de..eb624df5ea6 100644 --- a/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java @@ -21,5 +21,6 @@ public enum ApiRelativeDirection { UTURN_RIGHT, ENTER_STATION, EXIT_STATION, + ENTER_OR_EXIT_STATION, FOLLOW_SIGNS, } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index 5b288762262..a5eedb4c71c 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -37,6 +37,7 @@ import org.opentripplanner.apis.gtfs.datafetchers.CurrencyImpl; import org.opentripplanner.apis.gtfs.datafetchers.DefaultFareProductImpl; import org.opentripplanner.apis.gtfs.datafetchers.DepartureRowImpl; +import org.opentripplanner.apis.gtfs.datafetchers.EntranceImpl; import org.opentripplanner.apis.gtfs.datafetchers.FareProductTypeResolver; import org.opentripplanner.apis.gtfs.datafetchers.FareProductUseImpl; import org.opentripplanner.apis.gtfs.datafetchers.FeedImpl; @@ -58,7 +59,6 @@ import org.opentripplanner.apis.gtfs.datafetchers.RouteImpl; import org.opentripplanner.apis.gtfs.datafetchers.RouteTypeImpl; import org.opentripplanner.apis.gtfs.datafetchers.RoutingErrorImpl; -import org.opentripplanner.apis.gtfs.datafetchers.StepEntityTypeResolver; import org.opentripplanner.apis.gtfs.datafetchers.StopGeometriesImpl; import org.opentripplanner.apis.gtfs.datafetchers.StopImpl; import org.opentripplanner.apis.gtfs.datafetchers.StopOnRouteImpl; @@ -125,7 +125,6 @@ protected static GraphQLSchema buildSchema() { .type("Node", type -> type.typeResolver(new NodeTypeResolver())) .type("PlaceInterface", type -> type.typeResolver(new PlaceInterfaceTypeResolver())) .type("StopPosition", type -> type.typeResolver(new StopPosition() {})) - .type("StepEntity", type -> type.typeResolver(new StepEntityTypeResolver())) .type("FareProduct", type -> type.typeResolver(new FareProductTypeResolver())) .type("AlertEntity", type -> type.typeResolver(new AlertEntityTypeResolver())) .type(typeWiring.build(AgencyImpl.class)) @@ -181,6 +180,7 @@ protected static GraphQLSchema buildSchema() { .type(typeWiring.build(FareProductUseImpl.class)) .type(typeWiring.build(DefaultFareProductImpl.class)) .type(typeWiring.build(TripOccupancyImpl.class)) + .type(typeWiring.build(EntranceImpl.class)) .build(); SchemaGenerator schemaGenerator = new SchemaGenerator(); return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java new file mode 100644 index 00000000000..89f80286eed --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java @@ -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 code() { + return environment -> { + Entrance entrance = getEntrance(environment); + return entrance != null && entrance.getCode() != null ? entrance.getCode() : null; + }; + } + + @Override + public DataFetcher gtfsId() { + return environment -> { + Entrance entrance = getEntrance(environment); + return entrance != null && entrance.getId() != null ? entrance.getId().toString() : null; + }; + } + + @Override + public DataFetcher name() { + return environment -> { + Entrance entrance = getEntrance(environment); + return entrance != null && entrance.getName() != null ? entrance.getName().toString() : null; + }; + } + + @Override + public DataFetcher 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; + } +} diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java index 5e7d6098344..43762c97a7d 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java @@ -4,7 +4,7 @@ import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; import graphql.schema.TypeResolver; -import org.opentripplanner.model.plan.Entrance; +import org.opentripplanner.transit.model.site.Entrance; public class StepEntityTypeResolver implements TypeResolver { diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index 658f2d321ad..994434b4e4c 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -54,8 +54,8 @@ public DataFetcher exit() { } @Override - public DataFetcher entity() { - return environment -> getSource(environment).getEntity(); + public DataFetcher entrance() { + return environment -> getSource(environment).getEntrance(); } @Override diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index ec0e573d705..f99fceb410c 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -359,13 +359,13 @@ public interface GraphQLEmissions { /** Station entrance or exit. */ public interface GraphQLEntrance { - public DataFetcher accessible(); - public DataFetcher code(); public DataFetcher gtfsId(); public DataFetcher name(); + + public DataFetcher wheelchairAccessible(); } /** A 'medium' that a fare product applies to, for example cash, 'Oyster Card' or 'DB Navigator App'. */ @@ -984,9 +984,6 @@ public interface GraphQLRoutingError { public DataFetcher inputField(); } - /** Entity to a step */ - public interface GraphQLStepEntity extends TypeResolver {} - /** * Stop can represent either a single public transport stop, where passengers can * board and/or disembark vehicles, or a station, which contains multiple stops. @@ -1438,7 +1435,7 @@ public interface GraphQLStep { public DataFetcher> elevationProfile(); - public DataFetcher entity(); + public DataFetcher entrance(); public DataFetcher exit(); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index bf413f5fca4..9e4119100c0 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -3942,6 +3942,7 @@ public enum GraphQLRelativeDirection { CONTINUE, DEPART, ELEVATOR, + ENTER_OR_EXIT_STATION, ENTER_STATION, EXIT_STATION, FOLLOW_SIGNS, diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java index 69a78b05f55..1439cdd34c3 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java @@ -38,6 +38,7 @@ public static GraphQLRelativeDirection map(RelativeDirection relativeDirection) case UTURN_RIGHT -> GraphQLRelativeDirection.UTURN_RIGHT; case ENTER_STATION -> GraphQLRelativeDirection.ENTER_STATION; case EXIT_STATION -> GraphQLRelativeDirection.EXIT_STATION; + case ENTER_OR_EXIT_STATION -> GraphQLRelativeDirection.ENTER_OR_EXIT_STATION; case FOLLOW_SIGNS -> GraphQLRelativeDirection.FOLLOW_SIGNS; }; } diff --git a/application/src/main/java/org/opentripplanner/model/plan/Entrance.java b/application/src/main/java/org/opentripplanner/model/plan/Entrance.java deleted file mode 100644 index fa1e0fe5e57..00000000000 --- a/application/src/main/java/org/opentripplanner/model/plan/Entrance.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.opentripplanner.model.plan; - -public final class Entrance extends StepEntity { - - private final String code; - private final String gtfsId; - private final String name; - private final boolean accessible; - - public Entrance(String code, String gtfsId, String name, boolean accessible) { - this.code = code; - this.gtfsId = gtfsId; - this.name = name; - this.accessible = accessible; - } - - public static Entrance withCodeAndAccessible(String code, boolean accessible) { - return new Entrance(code, null, null, accessible); - } -} diff --git a/application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java b/application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java index ffc8993d0db..fbdb836ab6a 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java +++ b/application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java @@ -21,6 +21,7 @@ public enum RelativeDirection { UTURN_RIGHT, ENTER_STATION, EXIT_STATION, + ENTER_OR_EXIT_STATION, FOLLOW_SIGNS; public static RelativeDirection calculate( diff --git a/application/src/main/java/org/opentripplanner/model/plan/StepEntity.java b/application/src/main/java/org/opentripplanner/model/plan/StepEntity.java deleted file mode 100644 index e6bfd587bfc..00000000000 --- a/application/src/main/java/org/opentripplanner/model/plan/StepEntity.java +++ /dev/null @@ -1,3 +0,0 @@ -package org.opentripplanner.model.plan; - -public abstract class StepEntity {} diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java index 8114246d7e8..1f72a2960df 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -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 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; } /** diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java index 02b73c0ce15..b8055125051 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java @@ -9,10 +9,9 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.lang.DoubleUtils; import org.opentripplanner.framework.lang.IntUtils; -import org.opentripplanner.model.plan.Entrance; -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; public class WalkStepBuilder { @@ -27,7 +26,7 @@ public class WalkStepBuilder { private RelativeDirection relativeDirection; private ElevationProfile elevationProfile; private String exit; - private StepEntity entity; + private Entrance entrance; private boolean stayOn = false; /** * Distance used for appending elevation profiles @@ -78,7 +77,7 @@ public WalkStepBuilder withExit(String exit) { } public WalkStepBuilder withEntrance(Entrance entrance) { - this.entity = entrance; + this.entrance = entrance; return this; } @@ -164,7 +163,7 @@ public WalkStep build() { directionText, streetNotes, exit, - entity, + entrance, elevationProfile, bogusName, walkingBike, diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 14ed2a553e4..67b76578d9b 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -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); 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; } diff --git a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java index 258d505b53c..6f233aa9b31 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java @@ -30,7 +30,7 @@ public abstract class AbstractTransitEntity< private final FeedScopedId id; public AbstractTransitEntity(FeedScopedId id) { - this.id = Objects.requireNonNull(id); + this.id = id; // TODO IS THIS WORNG } public final FeedScopedId getId() { diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 83c32e2c1ca..de1a748c1e9 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -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." 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`." 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 "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 DEPART ELEVATOR + ENTER_OR_EXIT_STATION ENTER_STATION EXIT_STATION FOLLOW_SIGNS diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index d2448a92c59..a672ff3db3f 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -49,7 +49,6 @@ import org.opentripplanner.model.fare.ItineraryFares; import org.opentripplanner.model.fare.RiderCategory; import org.opentripplanner.model.plan.Emissions; -import org.opentripplanner.model.plan.Entrance; import org.opentripplanner.model.plan.Itinerary; import org.opentripplanner.model.plan.Place; import org.opentripplanner.model.plan.RelativeDirection; @@ -81,6 +80,7 @@ import org.opentripplanner.standalone.config.framework.json.JsonSupport; import org.opentripplanner.test.support.FilePatternSource; import org.opentripplanner.transit.model._data.TimetableRepositoryForTest; +import org.opentripplanner.transit.model.basic.Accessibility; import org.opentripplanner.transit.model.basic.Money; import org.opentripplanner.transit.model.basic.TransitMode; import org.opentripplanner.transit.model.framework.AbstractBuilder; @@ -90,6 +90,7 @@ import org.opentripplanner.transit.model.network.Route; import org.opentripplanner.transit.model.network.TripPattern; import org.opentripplanner.transit.model.organization.Agency; +import org.opentripplanner.transit.model.site.Entrance; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; import org.opentripplanner.transit.model.timetable.RealTimeTripTimes; @@ -232,10 +233,15 @@ public Set getRoutesForStop(StopLocation stop) { .withAbsoluteDirection(20) .build(); var step2 = walkStep("elevator").withRelativeDirection(RelativeDirection.ELEVATOR).build(); - + Entrance entrance = Entrance + .of(null) + .withCoordinate(new WgsCoordinate(60, 80)) + .withCode("A") + .withWheelchairAccessibility(Accessibility.POSSIBLE) + .build(); var step3 = walkStep("entrance") - .withRelativeDirection(RelativeDirection.CONTINUE) - .withEntrance(Entrance.withCodeAndAccessible("A", true)) + .withRelativeDirection(RelativeDirection.ENTER_OR_EXIT_STATION) + .withEntrance(entrance) .build(); Itinerary i1 = newItinerary(A, T11_00) diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json index 3a8e952880f..7cb304d6bb1 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json @@ -12,25 +12,24 @@ "area" : false, "relativeDirection" : "DEPART", "absoluteDirection" : "NORTHEAST", - "entity" : null + "entrance" : null }, { "streetName" : "elevator", "area" : false, "relativeDirection" : "ELEVATOR", "absoluteDirection" : null, - "entity" : null + "entrance" : null }, { "streetName" : "entrance", "area" : false, - "relativeDirection" : "CONTINUE", + "relativeDirection" : "ENTER_OR_EXIT_STATION", "absoluteDirection" : null, - "entity" : { - "__typename" : "Entrance", + "entrance": { "code": "A", - "accessible": true + "wheelchairAccessible": "POSSIBLE" } } ] diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql index 5e7c0493c35..c7de3f22ee1 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql @@ -20,12 +20,9 @@ area relativeDirection absoluteDirection - entity { - __typename - ... on Entrance { - code - accessible - } + entrance { + code + wheelchairAccessible } } } From 34761fe1b48d7ec93f735785a58f13e3b993e100 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Thu, 7 Nov 2024 14:41:35 +0200 Subject: [PATCH 17/36] Fix EntranceImpl --- .../apis/gtfs/datafetchers/EntranceImpl.java | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java index 89f80286eed..16cb3f5f6e7 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java @@ -1,7 +1,6 @@ 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; @@ -12,42 +11,37 @@ public class EntranceImpl implements GraphQLDataFetchers.GraphQLEntrance { @Override public DataFetcher code() { return environment -> { - Entrance entrance = getEntrance(environment); - return entrance != null && entrance.getCode() != null ? entrance.getCode() : null; + Entrance entrance = environment.getSource(); + return entrance.getCode(); }; } @Override public DataFetcher gtfsId() { return environment -> { - Entrance entrance = getEntrance(environment); - return entrance != null && entrance.getId() != null ? entrance.getId().toString() : null; + Entrance entrance = environment.getSource(); + return entrance.getId() != null ? entrance.getId().toString() : null; }; } @Override public DataFetcher name() { return environment -> { - Entrance entrance = getEntrance(environment); - return entrance != null && entrance.getName() != null ? entrance.getName().toString() : null; + Entrance entrance = environment.getSource(); + return entrance.getName() != null + ? org.opentripplanner.framework.graphql.GraphQLUtils.getTranslation( + entrance.getName(), + environment + ) + : null; }; } @Override public DataFetcher wheelchairAccessible() { return environment -> { - Entrance entrance = getEntrance(environment); - return entrance != null - ? GraphQLUtils.toGraphQL(entrance.getWheelchairAccessibility()) - : null; + Entrance entrance = environment.getSource(); + return GraphQLUtils.toGraphQL(entrance.getWheelchairAccessibility()); }; } - - /** - * 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; - } } From c84b7cf878974075ccd0049d813b33f94c9bf2e3 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Fri, 8 Nov 2024 10:09:53 +0200 Subject: [PATCH 18/36] Add id to walk step entrances --- .../opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java | 2 +- .../apis/gtfs/generated/GraphQLDataFetchers.java | 2 +- .../routing/algorithm/mapping/StatesToWalkStepsMapper.java | 5 ++++- .../street/model/vertex/StationEntranceVertex.java | 4 ++++ .../transit/model/framework/AbstractTransitEntity.java | 2 +- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- .../opentripplanner/apis/gtfs/GraphQLIntegrationTest.java | 3 ++- .../opentripplanner/apis/gtfs/expectations/walk-steps.json | 3 ++- .../org/opentripplanner/apis/gtfs/queries/walk-steps.graphql | 1 + 9 files changed, 17 insertions(+), 7 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java index 16cb3f5f6e7..c062f62d07a 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java @@ -17,7 +17,7 @@ public DataFetcher code() { } @Override - public DataFetcher gtfsId() { + public DataFetcher entranceId() { return environment -> { Entrance entrance = environment.getSource(); return entrance.getId() != null ? entrance.getId().toString() : null; diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index f99fceb410c..0d547b4cf10 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -361,7 +361,7 @@ public interface GraphQLEmissions { public interface GraphQLEntrance { public DataFetcher code(); - public DataFetcher gtfsId(); + public DataFetcher entranceId(); public DataFetcher name(); diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 67b76578d9b..81f6ffcb461 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -30,6 +30,7 @@ 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.framework.FeedScopedId; import org.opentripplanner.transit.model.site.Entrance; /** @@ -533,8 +534,10 @@ private WalkStepBuilder createStationEntranceWalkStep( StationEntranceVertex vertex = (StationEntranceVertex) backState.getVertex(); + FeedScopedId entranceId = new FeedScopedId("osm", vertex.getId()); + Entrance entrance = Entrance - .of(null) + .of(entranceId) .withCode(vertex.getCode()) .withCoordinate(new WgsCoordinate(vertex.getCoordinate())) .withWheelchairAccessibility( diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java index 3f83a356dea..e55ac7078db 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java @@ -19,6 +19,10 @@ public boolean isAccessible() { return accessible; } + public String getId() { + return Long.toString(nodeId); + } + public String toString() { return "StationEntranceVertex(" + super.toString() + ", code=" + code + ")"; } diff --git a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java index 6f233aa9b31..258d505b53c 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java +++ b/application/src/main/java/org/opentripplanner/transit/model/framework/AbstractTransitEntity.java @@ -30,7 +30,7 @@ public abstract class AbstractTransitEntity< private final FeedScopedId id; public AbstractTransitEntity(FeedScopedId id) { - this.id = id; // TODO IS THIS WORNG + this.id = Objects.requireNonNull(id); } public final FeedScopedId getId() { diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index de1a748c1e9..b4a5ce6da15 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -449,7 +449,7 @@ type Entrance { "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`." - gtfsId: String + entranceId: String "Name of the entrance or exit." name: String "Whether the entrance or exit is accessible by wheelchair" diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java index a672ff3db3f..d67038ec3f6 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/GraphQLIntegrationTest.java @@ -233,8 +233,9 @@ public Set getRoutesForStop(StopLocation stop) { .withAbsoluteDirection(20) .build(); var step2 = walkStep("elevator").withRelativeDirection(RelativeDirection.ELEVATOR).build(); + FeedScopedId entranceId = new FeedScopedId("osm", "123"); Entrance entrance = Entrance - .of(null) + .of(entranceId) .withCoordinate(new WgsCoordinate(60, 80)) .withCode("A") .withWheelchairAccessibility(Accessibility.POSSIBLE) diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json index 7cb304d6bb1..a0a781153f1 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json @@ -29,7 +29,8 @@ "absoluteDirection" : null, "entrance": { "code": "A", - "wheelchairAccessible": "POSSIBLE" + "wheelchairAccessible": "POSSIBLE", + "entranceId": "osm:123" } } ] diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql index c7de3f22ee1..45e2eed904a 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql @@ -23,6 +23,7 @@ entrance { code wheelchairAccessible + entranceId } } } From 2ea8a522e6616f2832b7410ed896c6434758c238 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Fri, 8 Nov 2024 10:37:19 +0200 Subject: [PATCH 19/36] Remove old file --- .../datafetchers/StepEntityTypeResolver.java | 21 ------------------- 1 file changed, 21 deletions(-) delete mode 100644 application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java deleted file mode 100644 index 43762c97a7d..00000000000 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepEntityTypeResolver.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.opentripplanner.apis.gtfs.datafetchers; - -import graphql.TypeResolutionEnvironment; -import graphql.schema.GraphQLObjectType; -import graphql.schema.GraphQLSchema; -import graphql.schema.TypeResolver; -import org.opentripplanner.transit.model.site.Entrance; - -public class StepEntityTypeResolver implements TypeResolver { - - @Override - public GraphQLObjectType getType(TypeResolutionEnvironment environment) { - Object o = environment.getObject(); - GraphQLSchema schema = environment.getSchema(); - - if (o instanceof Entrance) { - return schema.getObjectType("Entrance"); - } - return null; - } -} From 39b0db37f86b28fe5f03f7da2716f47bdbfed3cc Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Fri, 8 Nov 2024 10:38:59 +0200 Subject: [PATCH 20/36] Fix otp version --- .../standalone/config/buildconfig/OsmConfig.java | 3 ++- doc/user/BuildConfiguration.md | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java index c1a3963c6a5..5cc67844b50 100644 --- a/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java +++ b/application/src/main/java/org/opentripplanner/standalone/config/buildconfig/OsmConfig.java @@ -1,6 +1,7 @@ package org.opentripplanner.standalone.config.buildconfig; import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_2; +import static org.opentripplanner.standalone.config.framework.json.OtpVersion.V2_7; import org.opentripplanner.graph_builder.module.osm.parameters.OsmExtractParameters; import org.opentripplanner.graph_builder.module.osm.parameters.OsmExtractParametersBuilder; @@ -88,7 +89,7 @@ public static OsmExtractParametersBuilder mapOsmGenericParameters( .withIncludeOsmSubwayEntrances( node .of("includeOsmSubwayEntrances") - .since(V2_2) + .since(V2_7) .summary("Whether to include subway entrances from the OSM data." + documentationAddition) .docDefaultValue(docDefaults.includeOsmSubwayEntrances()) .asBoolean(defaults.includeOsmSubwayEntrances()) diff --git a/doc/user/BuildConfiguration.md b/doc/user/BuildConfiguration.md index 8b38da6fdbb..c5fdfa8095b 100644 --- a/doc/user/BuildConfiguration.md +++ b/doc/user/BuildConfiguration.md @@ -84,12 +84,12 @@ Sections follow that describe particular settings in more depth. |    [sharedGroupFilePattern](#nd_sharedGroupFilePattern) | `regexp` | Pattern for matching shared group NeTEx files in a NeTEx bundle. | *Optional* | `"(\w{3})-.*-shared\.xml"` | 2.0 | |    [ferryIdsNotAllowedForBicycle](#nd_ferryIdsNotAllowedForBicycle) | `string[]` | List ferries which do not allow bikes. | *Optional* | | 2.0 | | [osm](#osm) | `object[]` | Configure properties for a given OpenStreetMap feed. | *Optional* | | 2.2 | -|       includeOsmSubwayEntrances | `boolean` | Whether to include subway entrances from the OSM data. Overrides the value specified in `osmDefaults`. | *Optional* | `false` | 2.2 | +|       includeOsmSubwayEntrances | `boolean` | Whether to include subway entrances from the OSM data. Overrides the value specified in `osmDefaults`. | *Optional* | `false` | 2.7 | |       [osmTagMapping](#osm_0_osmTagMapping) | `enum` | The named set of mapping rules applied when parsing OSM tags. Overrides the value specified in `osmDefaults`. | *Optional* | `"default"` | 2.2 | |       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 | |       timeZone | `time-zone` | The timezone used to resolve opening hours in OSM data. Overrides the value specified in `osmDefaults`. | *Optional* | | 2.2 | | osmDefaults | `object` | Default properties for OpenStreetMap feeds. | *Optional* | | 2.2 | -|    includeOsmSubwayEntrances | `boolean` | Whether to include subway entrances from the OSM data. | *Optional* | `false` | 2.2 | +|    includeOsmSubwayEntrances | `boolean` | Whether to include subway entrances from the OSM data. | *Optional* | `false` | 2.7 | |    [osmTagMapping](#od_osmTagMapping) | `enum` | The named set of mapping rules applied when parsing OSM tags. | *Optional* | `"default"` | 2.2 | |    timeZone | `time-zone` | The timezone used to resolve opening hours in OSM data. | *Optional* | | 2.2 | | [transferRequests](RouteRequest.md) | `object[]` | Routing requests to use for pre-calculating stop-to-stop transfers. | *Optional* | | 2.1 | From 3b6bf3fbab24a97c67957effb7838b8383b652ff Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Fri, 8 Nov 2024 10:39:31 +0200 Subject: [PATCH 21/36] Remove unused import --- .../org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java | 1 - 1 file changed, 1 deletion(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index 9e4119100c0..32e1fc69870 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -1,7 +1,6 @@ // THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. package org.opentripplanner.apis.gtfs.generated; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; From c9df52d9e8e3a2359ef39c64e78295230090ff2e Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Sun, 10 Nov 2024 17:02:44 +0200 Subject: [PATCH 22/36] Require entranceId --- .../opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java | 2 +- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java index c062f62d07a..d7e2e6aa3ac 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java @@ -20,7 +20,7 @@ public DataFetcher code() { public DataFetcher entranceId() { return environment -> { Entrance entrance = environment.getSource(); - return entrance.getId() != null ? entrance.getId().toString() : null; + return entrance.getId().toString(); }; } diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 80094ecfd3f..c7cb1a6e346 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -449,7 +449,7 @@ type Entrance { "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`." - entranceId: String + entranceId: String! "Name of the entrance or exit." name: String "Whether the entrance or exit is accessible by wheelchair" From 7a9a8f694ad29a782827605bdc70e7cd8adea370 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Sun, 10 Nov 2024 17:59:58 +0200 Subject: [PATCH 23/36] Rename methods --- .../opentripplanner/ext/restapi/mapping/WalkStepMapper.java | 2 +- .../opentripplanner/apis/gtfs/datafetchers/stepImpl.java | 4 ++-- .../apis/transmodel/model/plan/PathGuidanceType.java | 2 +- .../main/java/org/opentripplanner/model/plan/WalkStep.java | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java index c5c59e4dc37..1df3d7e6fa7 100644 --- a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java @@ -39,7 +39,7 @@ public ApiWalkStep mapWalkStep(WalkStep domain) { api.streetName = domain.getDirectionText().toString(locale); api.absoluteDirection = domain.getAbsoluteDirection().map(AbsoluteDirectionMapper::mapAbsoluteDirection).orElse(null); - api.exit = domain.getExit(); + api.exit = domain.getHighwayExit(); api.stayOn = domain.isStayOn(); api.area = domain.getArea(); api.bogusName = domain.getBogusName(); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index 994434b4e4c..4414fc7b4cd 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -50,12 +50,12 @@ public DataFetcher> elevationProfile() { @Override public DataFetcher exit() { - return environment -> getSource(environment).getExit(); + return environment -> getSource(environment).getHighwayExit(); } @Override public DataFetcher entrance() { - return environment -> getSource(environment).getEntrance(); + return environment -> getSource(environment).getStationEntrance(); } @Override diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java index c52baa0be4c..12eaa089a50 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java @@ -65,7 +65,7 @@ public static GraphQLObjectType create(GraphQLObjectType elevationStepType) { .name("exit") .description("When exiting a highway or traffic circle, the exit name/number.") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((WalkStep) environment.getSource()).getExit()) + .dataFetcher(environment -> ((WalkStep) environment.getSource()).getHighwayExit()) .build() ) .field( diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java index 9e055e33559..96bde6d1ef3 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -130,14 +130,14 @@ public Optional getAbsoluteDirection() { /** * When exiting a highway or traffic circle, the exit name/number. */ - public String getExit() { + public String getHighwayExit() { return exit; } /** - * Get information about building entrance or exit. + * Get information about a subway station entrance or exit. */ - public Entrance getEntrance() { + public Entrance getStationEntrance() { return entrance; } From c9139e31f60662e7cae7cf35ace311ec9adc1d37 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Mon, 11 Nov 2024 15:04:33 +0200 Subject: [PATCH 24/36] Update dosumentation --- .../routing/algorithm/mapping/StatesToWalkStepsMapper.java | 3 ++- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 81f6ffcb461..b0df9658301 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -529,7 +529,8 @@ private WalkStepBuilder createStationEntranceWalkStep( ) { // don't care what came before or comes after var step = createWalkStep(forwardState, backState); - + // There is not a way to definitively determine if a user is entering or exiting the station, + // since the doors might be between or inside stations. step.withRelativeDirection(RelativeDirection.ENTER_OR_EXIT_STATION); StationEntranceVertex vertex = (StationEntranceVertex) backState.getVertex(); diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index c7cb1a6e346..13b576a46c7 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -444,11 +444,11 @@ type Emissions { co2: Grams } -"Station entrance or exit." +"Station entrance or exit, originating from OSM or GTFS data." type Entrance { "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`." + "ID of the entrance in the format of `FeedId:EntranceId`. If the `FeedId` is `osm`, the entrance originates from OSM data." entranceId: String! "Name of the entrance or exit." name: String From 7b210246ee0c5be3b54b4eff66722ffdd7e39e90 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Mon, 11 Nov 2024 15:18:55 +0200 Subject: [PATCH 25/36] Update documentation --- .../routing/algorithm/mapping/StatesToWalkStepsMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index b0df9658301..39941b72ecd 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -529,7 +529,7 @@ private WalkStepBuilder createStationEntranceWalkStep( ) { // don't care what came before or comes after var step = createWalkStep(forwardState, backState); - // There is not a way to definitively determine if a user is entering or exiting the station, + // There is not a way to definitively determine if a user is entering or exiting the station, // since the doors might be between or inside stations. step.withRelativeDirection(RelativeDirection.ENTER_OR_EXIT_STATION); From ce7719cf50c103b24a4a25530ec9be29aaa67d5a Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Mon, 11 Nov 2024 15:20:23 +0200 Subject: [PATCH 26/36] Remove redundant null check --- .../apis/gtfs/datafetchers/EntranceImpl.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java index d7e2e6aa3ac..9891d107479 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java @@ -28,12 +28,10 @@ public DataFetcher entranceId() { public DataFetcher name() { return environment -> { Entrance entrance = environment.getSource(); - return entrance.getName() != null - ? org.opentripplanner.framework.graphql.GraphQLUtils.getTranslation( - entrance.getName(), - environment - ) - : null; + return org.opentripplanner.framework.graphql.GraphQLUtils.getTranslation( + entrance.getName(), + environment + ); }; } From b73741100d9cb5a6a3691ded6976691880ed7682 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Thu, 14 Nov 2024 09:49:28 +0200 Subject: [PATCH 27/36] Add feature union to steps --- .../apis/gtfs/GtfsGraphQLIndex.java | 2 ++ .../apis/gtfs/datafetchers/EntranceImpl.java | 13 +++++++--- .../datafetchers/StepFeatureTypeResolver.java | 25 +++++++++++++++++++ .../apis/gtfs/datafetchers/stepImpl.java | 4 +-- .../gtfs/generated/GraphQLDataFetchers.java | 8 +++--- .../apis/gtfs/model/StepFeature.java | 20 +++++++++++++++ .../opentripplanner/model/plan/WalkStep.java | 14 +++++------ .../model/plan/WalkStepBuilder.java | 7 +++--- .../opentripplanner/apis/gtfs/schema.graphqls | 7 ++++-- .../apis/gtfs/expectations/walk-steps.json | 11 ++++---- .../apis/gtfs/queries/walk-steps.graphql | 11 +++++--- 11 files changed, 92 insertions(+), 30 deletions(-) create mode 100644 application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepFeatureTypeResolver.java create mode 100644 application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index a5eedb4c71c..22e8f2e6fa7 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -59,6 +59,7 @@ import org.opentripplanner.apis.gtfs.datafetchers.RouteImpl; import org.opentripplanner.apis.gtfs.datafetchers.RouteTypeImpl; import org.opentripplanner.apis.gtfs.datafetchers.RoutingErrorImpl; +import org.opentripplanner.apis.gtfs.datafetchers.StepFeatureTypeResolver; import org.opentripplanner.apis.gtfs.datafetchers.StopGeometriesImpl; import org.opentripplanner.apis.gtfs.datafetchers.StopImpl; import org.opentripplanner.apis.gtfs.datafetchers.StopOnRouteImpl; @@ -127,6 +128,7 @@ protected static GraphQLSchema buildSchema() { .type("StopPosition", type -> type.typeResolver(new StopPosition() {})) .type("FareProduct", type -> type.typeResolver(new FareProductTypeResolver())) .type("AlertEntity", type -> type.typeResolver(new AlertEntityTypeResolver())) + .type("StepFeature", type -> type.typeResolver(new StepFeatureTypeResolver())) .type(typeWiring.build(AgencyImpl.class)) .type(typeWiring.build(AlertImpl.class)) .type(typeWiring.build(BikeParkImpl.class)) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java index 9891d107479..bcf37d42cc7 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java @@ -4,6 +4,7 @@ import org.opentripplanner.apis.gtfs.GraphQLUtils; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; +import org.opentripplanner.apis.gtfs.model.StepFeature; import org.opentripplanner.transit.model.site.Entrance; public class EntranceImpl implements GraphQLDataFetchers.GraphQLEntrance { @@ -11,7 +12,8 @@ public class EntranceImpl implements GraphQLDataFetchers.GraphQLEntrance { @Override public DataFetcher code() { return environment -> { - Entrance entrance = environment.getSource(); + StepFeature feature = environment.getSource(); + Entrance entrance = (Entrance) feature.getFeature(); return entrance.getCode(); }; } @@ -19,7 +21,8 @@ public DataFetcher code() { @Override public DataFetcher entranceId() { return environment -> { - Entrance entrance = environment.getSource(); + StepFeature feature = environment.getSource(); + Entrance entrance = (Entrance) feature.getFeature(); return entrance.getId().toString(); }; } @@ -27,7 +30,8 @@ public DataFetcher entranceId() { @Override public DataFetcher name() { return environment -> { - Entrance entrance = environment.getSource(); + StepFeature feature = environment.getSource(); + Entrance entrance = (Entrance) feature.getFeature(); return org.opentripplanner.framework.graphql.GraphQLUtils.getTranslation( entrance.getName(), environment @@ -38,7 +42,8 @@ public DataFetcher name() { @Override public DataFetcher wheelchairAccessible() { return environment -> { - Entrance entrance = environment.getSource(); + StepFeature feature = environment.getSource(); + Entrance entrance = (Entrance) feature.getFeature(); return GraphQLUtils.toGraphQL(entrance.getWheelchairAccessibility()); }; } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepFeatureTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepFeatureTypeResolver.java new file mode 100644 index 00000000000..8748d87700d --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepFeatureTypeResolver.java @@ -0,0 +1,25 @@ +package org.opentripplanner.apis.gtfs.datafetchers; + +import graphql.TypeResolutionEnvironment; +import graphql.schema.GraphQLObjectType; +import graphql.schema.GraphQLSchema; +import graphql.schema.TypeResolver; +import org.opentripplanner.apis.gtfs.model.StepFeature; +import org.opentripplanner.transit.model.site.Entrance; + +public class StepFeatureTypeResolver implements TypeResolver { + + @Override + public GraphQLObjectType getType(TypeResolutionEnvironment environment) { + Object o = environment.getObject(); + GraphQLSchema schema = environment.getSchema(); + + if (o instanceof StepFeature) { + Object feature = ((StepFeature) o).getFeature(); + if (feature instanceof Entrance) { + return schema.getObjectType("Entrance"); + } + } + return null; + } +} diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index 4414fc7b4cd..74453d6e7c4 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -54,8 +54,8 @@ public DataFetcher exit() { } @Override - public DataFetcher entrance() { - return environment -> getSource(environment).getStationEntrance(); + public DataFetcher feature() { + return environment -> getSource(environment).getStepFeature(); } @Override diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 0d547b4cf10..b7889c8be3a 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -357,7 +357,7 @@ public interface GraphQLEmissions { public DataFetcher co2(); } - /** Station entrance or exit. */ + /** Station entrance or exit, originating from OSM or GTFS data. */ public interface GraphQLEntrance { public DataFetcher code(); @@ -984,6 +984,8 @@ public interface GraphQLRoutingError { public DataFetcher inputField(); } + public interface GraphQLStepFeature extends TypeResolver {} + /** * Stop can represent either a single public transport stop, where passengers can * board and/or disembark vehicles, or a station, which contains multiple stops. @@ -1435,10 +1437,10 @@ public interface GraphQLStep { public DataFetcher> elevationProfile(); - public DataFetcher entrance(); - public DataFetcher exit(); + public DataFetcher feature(); + public DataFetcher lat(); public DataFetcher lon(); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java new file mode 100644 index 00000000000..c4842e25476 --- /dev/null +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java @@ -0,0 +1,20 @@ +package org.opentripplanner.apis.gtfs.model; + +import org.opentripplanner.transit.model.site.Entrance; + +/** + * A generic wrapper class for features in Walk steps. + * At the moment only subway station entrances. + **/ +public class StepFeature { + + private final Object feature; + + public StepFeature(Entrance entrance) { + this.feature = entrance; + } + + public Object getFeature() { + return feature; + } +} diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java index 96bde6d1ef3..660b973a8a8 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -4,11 +4,11 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import org.opentripplanner.apis.gtfs.model.StepFeature; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.note.StreetNote; -import org.opentripplanner.transit.model.site.Entrance; import org.opentripplanner.utils.lang.DoubleUtils; import org.opentripplanner.utils.tostring.ToStringBuilder; @@ -45,7 +45,7 @@ public final class WalkStep { private final boolean walkingBike; private final String exit; - private final Entrance entrance; + private final StepFeature feature; private final ElevationProfile elevationProfile; private final boolean stayOn; @@ -58,7 +58,7 @@ public final class WalkStep { I18NString directionText, Set streetNotes, String exit, - Entrance entrance, + StepFeature feature, ElevationProfile elevationProfile, boolean bogusName, boolean walkingBike, @@ -79,7 +79,7 @@ public final class WalkStep { this.walkingBike = walkingBike; this.area = area; this.exit = exit; - this.entrance = entrance; + this.feature = feature; this.elevationProfile = elevationProfile; this.stayOn = stayOn; this.edges = List.copyOf(Objects.requireNonNull(edges)); @@ -135,10 +135,10 @@ public String getHighwayExit() { } /** - * Get information about a subway station entrance or exit. + * Get information about feature e.g. a subway station entrance or exit. */ - public Entrance getStationEntrance() { - return entrance; + public StepFeature getStepFeature() { + return feature; } /** diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java index 7ef5012e145..6752eba95e9 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java @@ -5,6 +5,7 @@ import java.util.List; import java.util.Set; import javax.annotation.Nullable; +import org.opentripplanner.apis.gtfs.model.StepFeature; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.street.model.edge.Edge; @@ -26,7 +27,7 @@ public class WalkStepBuilder { private RelativeDirection relativeDirection; private ElevationProfile elevationProfile; private String exit; - private Entrance entrance; + private StepFeature feature; private boolean stayOn = false; /** * Distance used for appending elevation profiles @@ -77,7 +78,7 @@ public WalkStepBuilder withExit(String exit) { } public WalkStepBuilder withEntrance(Entrance entrance) { - this.entrance = entrance; + this.feature = new StepFeature(entrance); return this; } @@ -163,7 +164,7 @@ public WalkStep build() { directionText, streetNotes, exit, - entrance, + feature, elevationProfile, bogusName, walkingBike, diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 13b576a46c7..83fe952ce7e 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -73,6 +73,9 @@ interface PlaceInterface { "Entity related to an alert" union AlertEntity = Agency | Pattern | Route | RouteType | Stop | StopOnRoute | StopOnTrip | Trip | Unknown +"A feature for a step" +union StepFeature = Entrance + union StopPosition = PositionAtStop | PositionBetweenStops "A public transport agency" @@ -2657,10 +2660,10 @@ type step { distance: Float "The elevation profile as a list of { distance, elevation } values." elevationProfile: [elevationProfileComponent] - "Information about an station entrance or exit" - entrance: Entrance "When exiting a highway or traffic circle, the exit name/number." exit: String + "Information about an feature associated with a step e.g. an station entrance or exit" + feature: StepFeature "The latitude of the start of the step." lat: Float "The longitude of the start of the step." diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json index a0a781153f1..8d79102fc59 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json @@ -12,14 +12,14 @@ "area" : false, "relativeDirection" : "DEPART", "absoluteDirection" : "NORTHEAST", - "entrance" : null + "feature" : null }, { "streetName" : "elevator", "area" : false, "relativeDirection" : "ELEVATOR", "absoluteDirection" : null, - "entrance" : null + "feature" : null }, { @@ -27,10 +27,11 @@ "area" : false, "relativeDirection" : "ENTER_OR_EXIT_STATION", "absoluteDirection" : null, - "entrance": { + "feature": { + "__typename": "Entrance", "code": "A", - "wheelchairAccessible": "POSSIBLE", - "entranceId": "osm:123" + "entranceId": "osm:123", + "wheelchairAccessible": "POSSIBLE" } } ] diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql index 45e2eed904a..565e620fed3 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/queries/walk-steps.graphql @@ -20,10 +20,13 @@ area relativeDirection absoluteDirection - entrance { - code - wheelchairAccessible - entranceId + feature { + __typename + ... on Entrance { + code + entranceId + wheelchairAccessible + } } } } From f547e074f2879c9e4f6bec37759a7d64fc927258 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Thu, 14 Nov 2024 12:42:47 +0200 Subject: [PATCH 28/36] Return feature based on relativeDirection --- .../apis/gtfs/datafetchers/EntranceImpl.java | 13 ++++--------- .../gtfs/datafetchers/StepFeatureTypeResolver.java | 8 ++------ .../apis/gtfs/datafetchers/stepImpl.java | 9 ++++++++- .../apis/gtfs/model/StepFeature.java | 8 ++++---- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java index bcf37d42cc7..9891d107479 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/EntranceImpl.java @@ -4,7 +4,6 @@ import org.opentripplanner.apis.gtfs.GraphQLUtils; import org.opentripplanner.apis.gtfs.generated.GraphQLDataFetchers; import org.opentripplanner.apis.gtfs.generated.GraphQLTypes; -import org.opentripplanner.apis.gtfs.model.StepFeature; import org.opentripplanner.transit.model.site.Entrance; public class EntranceImpl implements GraphQLDataFetchers.GraphQLEntrance { @@ -12,8 +11,7 @@ public class EntranceImpl implements GraphQLDataFetchers.GraphQLEntrance { @Override public DataFetcher code() { return environment -> { - StepFeature feature = environment.getSource(); - Entrance entrance = (Entrance) feature.getFeature(); + Entrance entrance = environment.getSource(); return entrance.getCode(); }; } @@ -21,8 +19,7 @@ public DataFetcher code() { @Override public DataFetcher entranceId() { return environment -> { - StepFeature feature = environment.getSource(); - Entrance entrance = (Entrance) feature.getFeature(); + Entrance entrance = environment.getSource(); return entrance.getId().toString(); }; } @@ -30,8 +27,7 @@ public DataFetcher entranceId() { @Override public DataFetcher name() { return environment -> { - StepFeature feature = environment.getSource(); - Entrance entrance = (Entrance) feature.getFeature(); + Entrance entrance = environment.getSource(); return org.opentripplanner.framework.graphql.GraphQLUtils.getTranslation( entrance.getName(), environment @@ -42,8 +38,7 @@ public DataFetcher name() { @Override public DataFetcher wheelchairAccessible() { return environment -> { - StepFeature feature = environment.getSource(); - Entrance entrance = (Entrance) feature.getFeature(); + Entrance entrance = environment.getSource(); return GraphQLUtils.toGraphQL(entrance.getWheelchairAccessibility()); }; } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepFeatureTypeResolver.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepFeatureTypeResolver.java index 8748d87700d..714518cb9ea 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepFeatureTypeResolver.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/StepFeatureTypeResolver.java @@ -4,7 +4,6 @@ import graphql.schema.GraphQLObjectType; import graphql.schema.GraphQLSchema; import graphql.schema.TypeResolver; -import org.opentripplanner.apis.gtfs.model.StepFeature; import org.opentripplanner.transit.model.site.Entrance; public class StepFeatureTypeResolver implements TypeResolver { @@ -14,11 +13,8 @@ public GraphQLObjectType getType(TypeResolutionEnvironment environment) { Object o = environment.getObject(); GraphQLSchema schema = environment.getSchema(); - if (o instanceof StepFeature) { - Object feature = ((StepFeature) o).getFeature(); - if (feature instanceof Entrance) { - return schema.getObjectType("Entrance"); - } + if (o instanceof Entrance) { + return schema.getObjectType("Entrance"); } return null; } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index 74453d6e7c4..6a1c180fad6 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -7,6 +7,7 @@ import org.opentripplanner.apis.gtfs.mapping.DirectionMapper; import org.opentripplanner.apis.gtfs.mapping.StreetNoteMapper; import org.opentripplanner.model.plan.ElevationProfile.Step; +import org.opentripplanner.model.plan.RelativeDirection; import org.opentripplanner.model.plan.WalkStep; import org.opentripplanner.routing.alertpatch.TransitAlert; @@ -55,7 +56,13 @@ public DataFetcher exit() { @Override public DataFetcher feature() { - return environment -> getSource(environment).getStepFeature(); + return environment -> { + WalkStep source = getSource(environment); + if (source.getRelativeDirection() == RelativeDirection.ENTER_OR_EXIT_STATION) { + return source.getStepFeature().getEntrance(); + } + return null; + }; } @Override diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java index c4842e25476..bf5fd8cc104 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java @@ -8,13 +8,13 @@ **/ public class StepFeature { - private final Object feature; + private final Entrance entranceFeature; public StepFeature(Entrance entrance) { - this.feature = entrance; + this.entranceFeature = entrance; } - public Object getFeature() { - return feature; + public Entrance getEntrance() { + return entranceFeature; } } From 18b84f00a2f83841ef5a993cd5d958899a3805fd Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Thu, 14 Nov 2024 14:20:00 +0200 Subject: [PATCH 29/36] Remove StepFeature class --- .../apis/gtfs/datafetchers/stepImpl.java | 2 +- .../apis/gtfs/model/StepFeature.java | 20 ------------------- .../opentripplanner/model/plan/WalkStep.java | 14 ++++++------- .../model/plan/WalkStepBuilder.java | 7 +++---- 4 files changed, 11 insertions(+), 32 deletions(-) delete mode 100644 application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index 6a1c180fad6..c98237f78c5 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -59,7 +59,7 @@ public DataFetcher feature() { return environment -> { WalkStep source = getSource(environment); if (source.getRelativeDirection() == RelativeDirection.ENTER_OR_EXIT_STATION) { - return source.getStepFeature().getEntrance(); + return source.getEntrance(); } return null; }; diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java b/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java deleted file mode 100644 index bf5fd8cc104..00000000000 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/model/StepFeature.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.opentripplanner.apis.gtfs.model; - -import org.opentripplanner.transit.model.site.Entrance; - -/** - * A generic wrapper class for features in Walk steps. - * At the moment only subway station entrances. - **/ -public class StepFeature { - - private final Entrance entranceFeature; - - public StepFeature(Entrance entrance) { - this.entranceFeature = entrance; - } - - public Entrance getEntrance() { - return entranceFeature; - } -} diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java index 660b973a8a8..2efe6e36aff 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -4,11 +4,11 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; -import org.opentripplanner.apis.gtfs.model.StepFeature; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.note.StreetNote; +import org.opentripplanner.transit.model.site.Entrance; import org.opentripplanner.utils.lang.DoubleUtils; import org.opentripplanner.utils.tostring.ToStringBuilder; @@ -45,7 +45,7 @@ public final class WalkStep { private final boolean walkingBike; private final String exit; - private final StepFeature feature; + private final Entrance entrance; private final ElevationProfile elevationProfile; private final boolean stayOn; @@ -58,7 +58,7 @@ public final class WalkStep { I18NString directionText, Set streetNotes, String exit, - StepFeature feature, + 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.feature = feature; + this.entrance = entrance; this.elevationProfile = elevationProfile; this.stayOn = stayOn; this.edges = List.copyOf(Objects.requireNonNull(edges)); @@ -135,10 +135,10 @@ public String getHighwayExit() { } /** - * Get information about feature e.g. a subway station entrance or exit. + * Get information about a subway station entrance or exit. */ - public StepFeature getStepFeature() { - return feature; + public Entrance getEntrance() { + return entrance; } /** diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java index 6752eba95e9..7ef5012e145 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStepBuilder.java @@ -5,7 +5,6 @@ import java.util.List; import java.util.Set; import javax.annotation.Nullable; -import org.opentripplanner.apis.gtfs.model.StepFeature; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.street.model.edge.Edge; @@ -27,7 +26,7 @@ public class WalkStepBuilder { private RelativeDirection relativeDirection; private ElevationProfile elevationProfile; private String exit; - private StepFeature feature; + private Entrance entrance; private boolean stayOn = false; /** * Distance used for appending elevation profiles @@ -78,7 +77,7 @@ public WalkStepBuilder withExit(String exit) { } public WalkStepBuilder withEntrance(Entrance entrance) { - this.feature = new StepFeature(entrance); + this.entrance = entrance; return this; } @@ -164,7 +163,7 @@ public WalkStep build() { directionText, streetNotes, exit, - feature, + entrance, elevationProfile, bogusName, walkingBike, From 04d35b7c34c5ab646ee044c7bd80caa50b99355b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 18 Dec 2024 00:08:13 +0100 Subject: [PATCH 30/36] Clean up code a little --- .../apis/gtfs/GtfsGraphQLIndex.java | 2 +- .../mapping/StatesToWalkStepsMapper.java | 31 +++++++------------ .../model/vertex/StationEntranceVertex.java | 26 +++++++++++----- .../model/site/StationElementBuilder.java | 3 +- .../opentripplanner/apis/gtfs/schema.graphqls | 1 - .../apis/gtfs/expectations/walk-steps.json | 17 +++++----- 6 files changed, 42 insertions(+), 38 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java index cd72633a886..d3f64288417 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/GtfsGraphQLIndex.java @@ -39,8 +39,8 @@ import org.opentripplanner.apis.gtfs.datafetchers.CurrencyImpl; import org.opentripplanner.apis.gtfs.datafetchers.DefaultFareProductImpl; import org.opentripplanner.apis.gtfs.datafetchers.DepartureRowImpl; -import org.opentripplanner.apis.gtfs.datafetchers.EstimatedTimeImpl; import org.opentripplanner.apis.gtfs.datafetchers.EntranceImpl; +import org.opentripplanner.apis.gtfs.datafetchers.EstimatedTimeImpl; import org.opentripplanner.apis.gtfs.datafetchers.FareProductTypeResolver; import org.opentripplanner.apis.gtfs.datafetchers.FareProductUseImpl; import org.opentripplanner.apis.gtfs.datafetchers.FeedImpl; diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 956ec6d5701..97310a47453 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -30,7 +30,6 @@ 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.framework.FeedScopedId; import org.opentripplanner.transit.model.site.Entrance; /** @@ -179,8 +178,8 @@ private void processState(State backState, State forwardState) { if (edge instanceof ElevatorAlightEdge) { addStep(createElevatorWalkStep(backState, forwardState, edge)); return; - } else if (backState.getVertex() instanceof StationEntranceVertex) { - addStep(createStationEntranceWalkStep(backState, forwardState, edge)); + } else if (backState.getVertex() instanceof StationEntranceVertex stationEntranceVertex) { + addStep(createStationEntranceWalkStep(backState, forwardState, stationEntranceVertex)); return; } else if (edge instanceof PathwayEdge pwe && pwe.signpostedAs().isPresent()) { createAndSaveStep(backState, forwardState, pwe.signpostedAs().get(), FOLLOW_SIGNS, edge); @@ -525,29 +524,23 @@ private WalkStepBuilder createElevatorWalkStep(State backState, State forwardSta private WalkStepBuilder createStationEntranceWalkStep( State backState, State forwardState, - Edge edge + StationEntranceVertex vertex ) { - // don't care what came before or comes after - var step = createWalkStep(forwardState, backState); - // There is not a way to definitively determine if a user is entering or exiting the station, - // since the doors might be between or inside stations. - step.withRelativeDirection(RelativeDirection.ENTER_OR_EXIT_STATION); - - StationEntranceVertex vertex = (StationEntranceVertex) backState.getVertex(); - - FeedScopedId entranceId = new FeedScopedId("osm", vertex.getId()); - Entrance entrance = Entrance - .of(entranceId) - .withCode(vertex.getCode()) + .of(vertex.id()) + .withCode(vertex.code()) .withCoordinate(new WgsCoordinate(vertex.getCoordinate())) .withWheelchairAccessibility( - vertex.isAccessible() ? Accessibility.POSSIBLE : Accessibility.NOT_POSSIBLE + vertex.wheelchairAccessibility() ) .build(); - step.withEntrance(entrance); - return step; + // don't care what came before or comes after + return createWalkStep(forwardState, backState) + // There is not a way to definitively determine if a user is entering or exiting the station, + // since the doors might be between or inside stations. + .withRelativeDirection(RelativeDirection.ENTER_OR_EXIT_STATION) + .withEntrance(entrance); } private void createAndSaveStep( diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java index e55ac7078db..6dd528204b2 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java @@ -1,5 +1,10 @@ package org.opentripplanner.street.model.vertex; +import javax.annotation.Nullable; +import org.opentripplanner.transit.model.basic.Accessibility; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.utils.tostring.ToStringBuilder; + public class StationEntranceVertex extends OsmVertex { private final String code; @@ -11,19 +16,26 @@ public StationEntranceVertex(double x, double y, long nodeId, String code, boole this.accessible = accessible; } - public String getCode() { - return code; + public FeedScopedId id() { + return new FeedScopedId("osm", String.valueOf(nodeId)); } - public boolean isAccessible() { - return accessible; + @Nullable + public String code() { + return code; } - public String getId() { - return Long.toString(nodeId); + public Accessibility wheelchairAccessibility() { + return accessible ? Accessibility.POSSIBLE : Accessibility.NOT_POSSIBLE; } + @Override public String toString() { - return "StationEntranceVertex(" + super.toString() + ", code=" + code + ")"; + return ToStringBuilder + .of(StationEntranceVertex.class) + .addNum("nodeId", nodeId) + .addStr("code", code) + .toString(); } + } diff --git a/application/src/main/java/org/opentripplanner/transit/model/site/StationElementBuilder.java b/application/src/main/java/org/opentripplanner/transit/model/site/StationElementBuilder.java index 7a7fc0e4621..ea90231bead 100644 --- a/application/src/main/java/org/opentripplanner/transit/model/site/StationElementBuilder.java +++ b/application/src/main/java/org/opentripplanner/transit/model/site/StationElementBuilder.java @@ -1,5 +1,6 @@ package org.opentripplanner.transit.model.site; +import javax.annotation.Nullable; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.transit.model.basic.Accessibility; @@ -54,7 +55,7 @@ public String code() { return code; } - public B withCode(String code) { + public B withCode(@Nullable String code) { this.code = code; return instance(); } diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 1c4951b782c..3eac957f7bb 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -3542,7 +3542,6 @@ enum RelativeDirection { CONTINUE DEPART ELEVATOR - ENTER_OR_EXIT_STATION ENTER_STATION EXIT_STATION FOLLOW_SIGNS diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json index 19f7f5cc758..be952f72303 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json @@ -11,22 +11,21 @@ "streetName": "street", "area": false, "relativeDirection": "DEPART", - "absoluteDirection" : "NORTHEAST", - "feature" : null + "absoluteDirection": "NORTHEAST", + "feature": null }, { "streetName": "elevator", "area": false, "relativeDirection": "ELEVATOR", - "absoluteDirection" : null, - "feature" : null - + "absoluteDirection": null, + "feature": null }, { - "streetName" : "entrance", - "area" : false, - "relativeDirection" : "ENTER_OR_EXIT_STATION", - "absoluteDirection" : null, + "streetName": "entrance", + "area": false, + "relativeDirection": "ENTER_OR_EXIT_STATION", + "absoluteDirection": null, "feature": { "__typename": "Entrance", "code": "A", From c4d665d21bb995678bc3e3b56a526b1cd3ce0c5f Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 18 Dec 2024 00:20:12 +0100 Subject: [PATCH 31/36] Reformat code and schema --- .../gtfs/generated/GraphQLDataFetchers.java | 15 +++++----- .../apis/gtfs/generated/GraphQLTypes.java | 1 - .../apis/gtfs/mapping/DirectionMapper.java | 3 +- .../mapping/StatesToWalkStepsMapper.java | 4 +-- .../model/vertex/StationEntranceVertex.java | 1 - .../opentripplanner/apis/gtfs/schema.graphqls | 28 +++++++++---------- 6 files changed, 24 insertions(+), 28 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java index 760e890045b..d9c9ceb67e8 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLDataFetchers.java @@ -392,13 +392,6 @@ public interface GraphQLEmissions { public DataFetcher co2(); } - /** Real-time estimates for an arrival or departure at a certain place. */ - public interface GraphQLEstimatedTime { - public DataFetcher delay(); - - public DataFetcher time(); - } - /** Station entrance or exit, originating from OSM or GTFS data. */ public interface GraphQLEntrance { public DataFetcher code(); @@ -410,6 +403,13 @@ public interface GraphQLEntrance { public DataFetcher wheelchairAccessible(); } + /** Real-time estimates for an arrival or departure at a certain place. */ + public interface GraphQLEstimatedTime { + public DataFetcher delay(); + + public DataFetcher time(); + } + /** A 'medium' that a fare product applies to, for example cash, 'Oyster Card' or 'DB Navigator App'. */ public interface GraphQLFareMedium { public DataFetcher id(); @@ -1035,6 +1035,7 @@ public interface GraphQLRoutingError { public DataFetcher inputField(); } + /** A feature for a step */ public interface GraphQLStepFeature extends TypeResolver {} /** diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java index fe598f88e40..a969b5223b1 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/generated/GraphQLTypes.java @@ -4334,7 +4334,6 @@ public enum GraphQLRelativeDirection { CONTINUE, DEPART, ELEVATOR, - ENTER_OR_EXIT_STATION, ENTER_STATION, EXIT_STATION, FOLLOW_SIGNS, diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java index 1439cdd34c3..3f69047f94d 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapper.java @@ -27,7 +27,7 @@ public static GraphQLRelativeDirection map(RelativeDirection relativeDirection) case HARD_LEFT -> GraphQLRelativeDirection.HARD_LEFT; case LEFT -> GraphQLRelativeDirection.LEFT; case SLIGHTLY_LEFT -> GraphQLRelativeDirection.SLIGHTLY_LEFT; - case CONTINUE -> GraphQLRelativeDirection.CONTINUE; + case CONTINUE, ENTER_OR_EXIT_STATION -> GraphQLRelativeDirection.CONTINUE; case SLIGHTLY_RIGHT -> GraphQLRelativeDirection.SLIGHTLY_RIGHT; case RIGHT -> GraphQLRelativeDirection.RIGHT; case HARD_RIGHT -> GraphQLRelativeDirection.HARD_RIGHT; @@ -38,7 +38,6 @@ public static GraphQLRelativeDirection map(RelativeDirection relativeDirection) case UTURN_RIGHT -> GraphQLRelativeDirection.UTURN_RIGHT; case ENTER_STATION -> GraphQLRelativeDirection.ENTER_STATION; case EXIT_STATION -> GraphQLRelativeDirection.EXIT_STATION; - case ENTER_OR_EXIT_STATION -> GraphQLRelativeDirection.ENTER_OR_EXIT_STATION; case FOLLOW_SIGNS -> GraphQLRelativeDirection.FOLLOW_SIGNS; }; } diff --git a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java index 97310a47453..9365c50509c 100644 --- a/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java +++ b/application/src/main/java/org/opentripplanner/routing/algorithm/mapping/StatesToWalkStepsMapper.java @@ -530,9 +530,7 @@ private WalkStepBuilder createStationEntranceWalkStep( .of(vertex.id()) .withCode(vertex.code()) .withCoordinate(new WgsCoordinate(vertex.getCoordinate())) - .withWheelchairAccessibility( - vertex.wheelchairAccessibility() - ) + .withWheelchairAccessibility(vertex.wheelchairAccessibility()) .build(); // don't care what came before or comes after diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java index 6dd528204b2..ef94bbb64ef 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java @@ -37,5 +37,4 @@ public String toString() { .addStr("code", code) .toString(); } - } diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 3eac957f7bb..748b69607e0 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -491,18 +491,6 @@ type Emissions { co2: Grams } -"Real-time estimates for an arrival or departure at a certain place." -type EstimatedTime { - """ - The delay or "earliness" of the vehicle at a certain place. This estimate can change quite often. - - If the vehicle is early then this is a negative duration. - """ - delay: Duration! - "The estimate for a call event (such as arrival or departure) at a certain place. This estimate can change quite often." - time: OffsetDateTime! -} - "Station entrance or exit, originating from OSM or GTFS data." type Entrance { "Short text or a number that identifies the entrance or exit for passengers. For example, `A` or `B`." @@ -515,6 +503,18 @@ type Entrance { wheelchairAccessible: WheelchairBoarding } +"Real-time estimates for an arrival or departure at a certain place." +type EstimatedTime { + """ + The delay or "earliness" of the vehicle at a certain place. This estimate can change quite often. + + If the vehicle is early then this is a negative duration. + """ + delay: Duration! + "The estimate for a call event (such as arrival or departure) at a certain place. This estimate can change quite often." + time: OffsetDateTime! +} + "A 'medium' that a fare product applies to, for example cash, 'Oyster Card' or 'DB Navigator App'." type FareMedium { "ID of the medium" @@ -2359,7 +2359,7 @@ type Stoptime { """ The position of the stop in the pattern. This is required to start from 0 and be consecutive along the pattern, up to n-1 for a pattern with n stops. - + The purpose of this field is to identify the position of the stop within the pattern so it can be cross-referenced between different trips on the same pattern, as stopPosition can be different between trips even within the same pattern. @@ -2518,7 +2518,7 @@ type TripOnServiceDate { end: StopCall! """ The service date when the trip occurs. - + **Note**: A service date is a technical term useful for transit planning purposes and might not correspond to a how a passenger thinks of a calendar date. For example, a night bus running on Sunday morning at 1am to 3am, might have the previous Saturday's service date. From bf89f4969fd39cc2b1265f35b3c79836ac6ca496 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 18 Dec 2024 00:25:08 +0100 Subject: [PATCH 32/36] Fix tests --- .../resources/org/opentripplanner/apis/gtfs/schema.graphqls | 6 +++--- .../apis/gtfs/mapping/DirectionMapperTest.java | 1 + .../opentripplanner/apis/gtfs/expectations/walk-steps.json | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls index 748b69607e0..6ac56be3d1d 100644 --- a/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls +++ b/application/src/main/resources/org/opentripplanner/apis/gtfs/schema.graphqls @@ -507,7 +507,7 @@ type Entrance { type EstimatedTime { """ The delay or "earliness" of the vehicle at a certain place. This estimate can change quite often. - + If the vehicle is early then this is a negative duration. """ delay: Duration! @@ -2359,7 +2359,7 @@ type Stoptime { """ The position of the stop in the pattern. This is required to start from 0 and be consecutive along the pattern, up to n-1 for a pattern with n stops. - + The purpose of this field is to identify the position of the stop within the pattern so it can be cross-referenced between different trips on the same pattern, as stopPosition can be different between trips even within the same pattern. @@ -2518,7 +2518,7 @@ type TripOnServiceDate { end: StopCall! """ The service date when the trip occurs. - + **Note**: A service date is a technical term useful for transit planning purposes and might not correspond to a how a passenger thinks of a calendar date. For example, a night bus running on Sunday morning at 1am to 3am, might have the previous Saturday's service date. diff --git a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapperTest.java b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapperTest.java index 2c69f3dca46..1dcd6e210a3 100644 --- a/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapperTest.java +++ b/application/src/test/java/org/opentripplanner/apis/gtfs/mapping/DirectionMapperTest.java @@ -23,6 +23,7 @@ void absoluteDirection() { void relativeDirection() { Arrays .stream(RelativeDirection.values()) + .filter(v -> v != RelativeDirection.ENTER_OR_EXIT_STATION) .forEach(d -> { var mapped = DirectionMapper.map(d); assertEquals(d.toString(), mapped.toString()); diff --git a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json index be952f72303..0e089aac428 100644 --- a/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json +++ b/application/src/test/resources/org/opentripplanner/apis/gtfs/expectations/walk-steps.json @@ -24,7 +24,7 @@ { "streetName": "entrance", "area": false, - "relativeDirection": "ENTER_OR_EXIT_STATION", + "relativeDirection": "CONTINUE", "absoluteDirection": null, "feature": { "__typename": "Entrance", From 2eb0e7b45c87941ea5fb928c4929f748fa089d5b Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 18 Dec 2024 11:33:51 +0100 Subject: [PATCH 33/36] Add documentation --- .../model/vertex/StationEntranceVertex.java | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java index ef94bbb64ef..254c71c527d 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/StationEntranceVertex.java @@ -5,28 +5,46 @@ import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.utils.tostring.ToStringBuilder; +/** + * A station entrance extracted from OSM and therefore not (yet) associated with the transit + * entity {@link org.opentripplanner.transit.model.site.Station}. + */ public class StationEntranceVertex extends OsmVertex { + private static final String FEED_ID = "osm"; private final String code; - private final boolean accessible; - - public StationEntranceVertex(double x, double y, long nodeId, String code, boolean accessible) { - super(x, y, nodeId); + private final boolean wheelchairAccessible; + + public StationEntranceVertex( + double lat, + double lon, + long nodeId, + String code, + boolean wheelchairAccessible + ) { + super(lat, lon, nodeId); this.code = code; - this.accessible = accessible; + this.wheelchairAccessible = wheelchairAccessible; } + /** + * The id of the entrance which may or may not be human-readable. + */ public FeedScopedId id() { - return new FeedScopedId("osm", String.valueOf(nodeId)); + return new FeedScopedId(FEED_ID, String.valueOf(nodeId)); } + /** + * Short human-readable code of the exit, like A or H3. + * If we need a proper name like "Oranienplatz" we have to add a name field. + */ @Nullable public String code() { return code; } public Accessibility wheelchairAccessibility() { - return accessible ? Accessibility.POSSIBLE : Accessibility.NOT_POSSIBLE; + return wheelchairAccessible ? Accessibility.POSSIBLE : Accessibility.NOT_POSSIBLE; } @Override From 977d8ebc943d0476f3e1723ed56f1e9ee48be39d Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 18 Dec 2024 12:07:09 +0100 Subject: [PATCH 34/36] Clean up --- .../ext/restapi/mapping/RelativeDirectionMapper.java | 3 +-- .../opentripplanner/ext/restapi/mapping/WalkStepMapper.java | 2 +- .../ext/restapi/model/ApiRelativeDirection.java | 1 - .../opentripplanner/apis/gtfs/datafetchers/stepImpl.java | 2 +- .../apis/transmodel/model/plan/PathGuidanceType.java | 2 +- .../module/osm/parameters/OsmExtractParameters.java | 1 - .../org/opentripplanner/model/plan/RelativeDirection.java | 6 ++++++ .../main/java/org/opentripplanner/model/plan/WalkStep.java | 2 +- 8 files changed, 11 insertions(+), 8 deletions(-) diff --git a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java index 708da1fd6c3..ab9abaa4481 100644 --- a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/RelativeDirectionMapper.java @@ -14,7 +14,7 @@ public static ApiRelativeDirection mapRelativeDirection(RelativeDirection domain case HARD_LEFT -> ApiRelativeDirection.HARD_LEFT; case LEFT -> ApiRelativeDirection.LEFT; case SLIGHTLY_LEFT -> ApiRelativeDirection.SLIGHTLY_LEFT; - case CONTINUE -> ApiRelativeDirection.CONTINUE; + case CONTINUE, ENTER_OR_EXIT_STATION -> ApiRelativeDirection.CONTINUE; case SLIGHTLY_RIGHT -> ApiRelativeDirection.SLIGHTLY_RIGHT; case RIGHT -> ApiRelativeDirection.RIGHT; case HARD_RIGHT -> ApiRelativeDirection.HARD_RIGHT; @@ -25,7 +25,6 @@ public static ApiRelativeDirection mapRelativeDirection(RelativeDirection domain case UTURN_RIGHT -> ApiRelativeDirection.UTURN_RIGHT; case ENTER_STATION -> ApiRelativeDirection.ENTER_STATION; case EXIT_STATION -> ApiRelativeDirection.EXIT_STATION; - case ENTER_OR_EXIT_STATION -> ApiRelativeDirection.ENTER_OR_EXIT_STATION; case FOLLOW_SIGNS -> ApiRelativeDirection.FOLLOW_SIGNS; }; } diff --git a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java index 9360620d40b..49e467a89db 100644 --- a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java @@ -39,7 +39,7 @@ public ApiWalkStep mapWalkStep(WalkStep domain) { api.streetName = domain.getDirectionText().toString(locale); api.absoluteDirection = domain.getAbsoluteDirection().map(AbsoluteDirectionMapper::mapAbsoluteDirection).orElse(null); - api.exit = domain.getHighwayExit(); + api.exit = domain.isHighwayExit(); api.stayOn = domain.isStayOn(); api.area = domain.getArea(); api.bogusName = domain.nameIsDerived(); diff --git a/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java index eb624df5ea6..02a530f06de 100644 --- a/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/model/ApiRelativeDirection.java @@ -21,6 +21,5 @@ public enum ApiRelativeDirection { UTURN_RIGHT, ENTER_STATION, EXIT_STATION, - ENTER_OR_EXIT_STATION, FOLLOW_SIGNS, } diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index 4953d887713..7b1df1693d3 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -51,7 +51,7 @@ public DataFetcher> elevationProfile() { @Override public DataFetcher exit() { - return environment -> getSource(environment).getHighwayExit(); + return environment -> getSource(environment).isHighwayExit(); } @Override diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java index 5c2fa6f3a5e..74b30c83f44 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java @@ -65,7 +65,7 @@ public static GraphQLObjectType create(GraphQLObjectType elevationStepType) { .name("exit") .description("When exiting a highway or traffic circle, the exit name/number.") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((WalkStep) environment.getSource()).getHighwayExit()) + .dataFetcher(environment -> ((WalkStep) environment.getSource()).isHighwayExit()) .build() ) .field( diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java index 37edaf687ab..a59147137f6 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/parameters/OsmExtractParameters.java @@ -49,7 +49,6 @@ public ZoneId timeZone() { return timeZone; } - @Nullable public boolean includeOsmSubwayEntrances() { return includeOsmSubwayEntrances; } diff --git a/application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java b/application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java index fbdb836ab6a..3ce16a45c11 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java +++ b/application/src/main/java/org/opentripplanner/model/plan/RelativeDirection.java @@ -21,6 +21,12 @@ public enum RelativeDirection { UTURN_RIGHT, ENTER_STATION, EXIT_STATION, + /** + * We don't have a way to reliably tell if we are entering or exiting a station and therefore + * use this generic enum value. Please don't expose it in APIs. + *

+ * If we manage to figure it out in the future, we can remove this. + */ ENTER_OR_EXIT_STATION, FOLLOW_SIGNS; diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java index eb59196b971..7edae8d7174 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -130,7 +130,7 @@ public Optional getAbsoluteDirection() { /** * When exiting a highway or traffic circle, the exit name/number. */ - public String getHighwayExit() { + public String isHighwayExit() { return exit; } From b7cc6fddb042f6f69a098208925c8d71cba7ee29 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 18 Dec 2024 12:36:16 +0100 Subject: [PATCH 35/36] Remove enum mapper test for REST API --- .../ext/restapi/mapping/EnumMapperTest.java | 41 ------------------- .../ext/restapi/mapping/WalkStepMapper.java | 2 +- .../apis/gtfs/datafetchers/stepImpl.java | 11 +---- .../model/plan/PathGuidanceType.java | 4 +- .../opentripplanner/model/plan/WalkStep.java | 8 ++-- 5 files changed, 10 insertions(+), 56 deletions(-) diff --git a/application/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java b/application/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java index 35cc368fec4..5b03ada1c1f 100644 --- a/application/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java +++ b/application/src/ext-test/java/org/opentripplanner/ext/restapi/mapping/EnumMapperTest.java @@ -8,39 +8,11 @@ import java.util.Map; import java.util.function.Function; import org.junit.jupiter.api.Test; -import org.opentripplanner.ext.restapi.model.ApiAbsoluteDirection; -import org.opentripplanner.ext.restapi.model.ApiRelativeDirection; import org.opentripplanner.ext.restapi.model.ApiVertexType; -import org.opentripplanner.model.plan.AbsoluteDirection; -import org.opentripplanner.model.plan.RelativeDirection; import org.opentripplanner.model.plan.VertexType; public class EnumMapperTest { - private static final String MSG = - "Assert that the API enums have the exact same values that " + - "the domain enums of the same type, and that the specialized mapper is mapping all " + - "values. If this assumtion does not hold, create a new test."; - - @Test - public void map() { - try { - verifyExactMatch( - AbsoluteDirection.class, - ApiAbsoluteDirection.class, - AbsoluteDirectionMapper::mapAbsoluteDirection - ); - verifyExactMatch( - RelativeDirection.class, - ApiRelativeDirection.class, - RelativeDirectionMapper::mapRelativeDirection - ); - } catch (RuntimeException ex) { - System.out.println(MSG); - throw ex; - } - } - @Test public void testVertexTypeMapping() { verifyExplicitMatch( @@ -75,17 +47,4 @@ private , A extends Enum> void verifyExplicitMatch( assertTrue(rest.isEmpty()); } - private , A extends Enum> void verifyExactMatch( - Class domainClass, - Class apiClass, - Function mapper - ) { - List rest = new ArrayList<>(List.of(apiClass.getEnumConstants())); - for (D it : domainClass.getEnumConstants()) { - A result = mapper.apply(it); - assertEquals(result.name(), it.name()); - rest.remove(result); - } - assertTrue(rest.isEmpty()); - } } diff --git a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java index 49e467a89db..c4aa11904cc 100644 --- a/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java +++ b/application/src/ext/java/org/opentripplanner/ext/restapi/mapping/WalkStepMapper.java @@ -39,7 +39,7 @@ public ApiWalkStep mapWalkStep(WalkStep domain) { api.streetName = domain.getDirectionText().toString(locale); api.absoluteDirection = domain.getAbsoluteDirection().map(AbsoluteDirectionMapper::mapAbsoluteDirection).orElse(null); - api.exit = domain.isHighwayExit(); + api.exit = domain.highwayExit().orElse(null); api.stayOn = domain.isStayOn(); api.area = domain.getArea(); api.bogusName = domain.nameIsDerived(); diff --git a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java index 7b1df1693d3..409bb2abb1d 100644 --- a/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java +++ b/application/src/main/java/org/opentripplanner/apis/gtfs/datafetchers/stepImpl.java @@ -7,7 +7,6 @@ import org.opentripplanner.apis.gtfs.mapping.DirectionMapper; import org.opentripplanner.apis.gtfs.mapping.StreetNoteMapper; import org.opentripplanner.model.plan.ElevationProfile.Step; -import org.opentripplanner.model.plan.RelativeDirection; import org.opentripplanner.model.plan.WalkStep; import org.opentripplanner.routing.alertpatch.TransitAlert; @@ -51,18 +50,12 @@ public DataFetcher> elevationProfile() { @Override public DataFetcher exit() { - return environment -> getSource(environment).isHighwayExit(); + return environment -> getSource(environment).highwayExit().orElse(null); } @Override public DataFetcher feature() { - return environment -> { - WalkStep source = getSource(environment); - if (source.getRelativeDirection() == RelativeDirection.ENTER_OR_EXIT_STATION) { - return source.getEntrance(); - } - return null; - }; + return environment -> getSource(environment).entrance().orElse(null); } @Override diff --git a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java index 74b30c83f44..86c8359c026 100644 --- a/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java +++ b/application/src/main/java/org/opentripplanner/apis/transmodel/model/plan/PathGuidanceType.java @@ -65,7 +65,9 @@ public static GraphQLObjectType create(GraphQLObjectType elevationStepType) { .name("exit") .description("When exiting a highway or traffic circle, the exit name/number.") .type(Scalars.GraphQLString) - .dataFetcher(environment -> ((WalkStep) environment.getSource()).isHighwayExit()) + .dataFetcher(environment -> + ((WalkStep) environment.getSource()).highwayExit().orElse(null) + ) .build() ) .field( diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java index 7edae8d7174..fea605fe910 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -130,15 +130,15 @@ public Optional getAbsoluteDirection() { /** * When exiting a highway or traffic circle, the exit name/number. */ - public String isHighwayExit() { - return exit; + public Optional highwayExit() { + return exit.describeConstable(); } /** * Get information about a subway station entrance or exit. */ - public Entrance getEntrance() { - return entrance; + public Optional entrance() { + return Optional.ofNullable(entrance); } /** From e473061d17441245d415771ee7f1c25c404a02a0 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Wed, 18 Dec 2024 12:44:25 +0100 Subject: [PATCH 36/36] Fix highway exits --- .../java/org/opentripplanner/model/plan/WalkStep.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java index fea605fe910..7ade16de39a 100644 --- a/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java +++ b/application/src/main/java/org/opentripplanner/model/plan/WalkStep.java @@ -44,7 +44,7 @@ public final class WalkStep { private final double angle; private final boolean walkingBike; - private final String exit; + private final String highwayExit; private final Entrance entrance; private final ElevationProfile elevationProfile; private final boolean stayOn; @@ -57,7 +57,7 @@ public final class WalkStep { AbsoluteDirection absoluteDirection, I18NString directionText, Set streetNotes, - String exit, + String highwayExit, Entrance entrance, ElevationProfile elevationProfile, boolean nameIsDerived, @@ -78,7 +78,7 @@ public final class WalkStep { this.angle = DoubleUtils.roundTo2Decimals(angle); this.walkingBike = walkingBike; this.area = area; - this.exit = exit; + this.highwayExit = highwayExit; this.entrance = entrance; this.elevationProfile = elevationProfile; this.stayOn = stayOn; @@ -131,7 +131,7 @@ public Optional getAbsoluteDirection() { * When exiting a highway or traffic circle, the exit name/number. */ public Optional highwayExit() { - return exit.describeConstable(); + return Optional.ofNullable(highwayExit); } /**