From 1d19a052a8bf2523c3af537edfc92fe9a72e8c62 Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Wed, 18 Sep 2024 17:22:19 +0300 Subject: [PATCH 01/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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/30] 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 2060016c0eb92528e08aee4bcff2a5ebf06a410f Mon Sep 17 00:00:00 2001 From: Henrik Sundell Date: Tue, 3 Dec 2024 09:31:06 +0200 Subject: [PATCH 30/30] Reuse transit entrance vertex --- .../module/OsmBoardingLocationsModule.java | 4 +- .../module/StreetLinkerModule.java | 12 ++- .../module/osm/ElevatorProcessor.java | 3 +- .../module/osm/EscalatorProcessor.java | 6 +- .../graph_builder/module/osm/OsmModule.java | 13 ++-- .../module/osm/ParkingProcessor.java | 8 +- .../module/osm/VertexGenerator.java | 27 +++++-- .../module/osm/WalkableAreaBuilder.java | 14 ++-- .../mapping/StatesToWalkStepsMapper.java | 22 +----- .../routing/linking/FlexLocationAdder.java | 8 +- .../routing/linking/VertexLinker.java | 40 +++++----- .../VehicleParkingEntrance.java | 12 +-- .../street/StreetVehicleRentalLink.java | 10 +-- .../street/model/edge/AreaEdgeBuilder.java | 10 +-- .../street/model/edge/AreaEdgeList.java | 10 +-- .../street/model/edge/StreetEdge.java | 12 +-- .../street/model/edge/StreetEdgeBuilder.java | 18 ++--- .../model/edge/StreetStationCentroidLink.java | 10 +-- .../model/edge/StreetTransitEntityLink.java | 77 +++++++++++++++++-- .../model/edge/StreetTransitEntranceLink.java | 10 +-- .../model/edge/StreetTransitStopLink.java | 14 ++-- .../model/edge/StreetVehicleParkingLink.java | 10 +-- .../model/vertex/TransitEntranceVertex.java | 4 + .../street/model/vertex/Vertex.java | 56 ++++++++++++++ .../routing/algorithm/GraphRoutingTest.java | 54 ++++++------- 25 files changed, 287 insertions(+), 177 deletions(-) diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java index c4acabefd6c..2557b344d83 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/OsmBoardingLocationsModule.java @@ -22,8 +22,8 @@ import org.opentripplanner.street.model.edge.StreetEdgeBuilder; import org.opentripplanner.street.model.edge.StreetTransitStopLink; import org.opentripplanner.street.model.vertex.OsmBoardingLocationVertex; -import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TransitStopVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexFactory; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.TraverseModeSet; @@ -182,7 +182,7 @@ private boolean connectVertexToStop(TransitStopVertex ts, StreetIndex index) { return false; } - private StreetEdge linkBoardingLocationToStreetNetwork(StreetVertex from, StreetVertex to) { + private StreetEdge linkBoardingLocationToStreetNetwork(Vertex from, Vertex to) { var line = GeometryUtils.makeLineString(List.of(from.getCoordinate(), to.getCoordinate())); return new StreetEdgeBuilder<>() .withFromVertex(from) diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java index 98b2287542e..c9a22819e6d 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/StreetLinkerModule.java @@ -20,14 +20,12 @@ import org.opentripplanner.street.model.edge.StreetVehicleParkingLink; import org.opentripplanner.street.model.edge.VehicleParkingEdge; import org.opentripplanner.street.model.vertex.StationCentroidVertex; -import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TransitEntranceVertex; import org.opentripplanner.street.model.vertex.TransitStopVertex; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.TraverseModeSet; -import org.opentripplanner.transit.model.network.CarAccess; import org.opentripplanner.transit.model.site.GroupStop; import org.opentripplanner.transit.model.site.RegularStop; import org.opentripplanner.transit.model.site.StopLocation; @@ -170,10 +168,7 @@ private void linkToDriveableEdge(TransitStopVertex tStop) { ); } - private static List createStopLinkEdges( - TransitStopVertex vertex, - StreetVertex streetVertex - ) { + private static List createStopLinkEdges(TransitStopVertex vertex, Vertex streetVertex) { return List.of( StreetTransitStopLink.createStreetTransitStopLink(vertex, streetVertex), StreetTransitStopLink.createStreetTransitStopLink(streetVertex, vertex) @@ -230,6 +225,9 @@ private static void linkVehicleParkingWithLinker( private void linkTransitEntrances(Graph graph) { LOG.info("Linking transit entrances to graph..."); for (TransitEntranceVertex tEntrance : graph.getVerticesOfType(TransitEntranceVertex.class)) { + if (tEntrance.isConnectedToGraph()) { + continue; + } graph .getLinker() .linkVertexPermanently( @@ -252,7 +250,7 @@ private void linkTransitEntrances(Graph graph) { } private void linkStationCentroids(Graph graph) { - BiFunction> stationAndStreetVertexLinker = ( + BiFunction> stationAndStreetVertexLinker = ( theStation, streetVertex ) -> diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java index 490d6a266b9..d8dad03da57 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ElevatorProcessor.java @@ -22,7 +22,6 @@ import org.opentripplanner.street.model.edge.FreeEdge; import org.opentripplanner.street.model.vertex.ElevatorOffboardVertex; import org.opentripplanner.street.model.vertex.ElevatorOnboardVertex; -import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.OsmVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexFactory; @@ -154,7 +153,7 @@ public void buildElevatorEdges(Graph graph) { private static void createElevatorVertices( Graph graph, ArrayList onboardVertices, - IntersectionVertex sourceVertex, + Vertex sourceVertex, String label, String levelName ) { diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java index 75e0965d82f..b160b01af68 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/EscalatorProcessor.java @@ -5,16 +5,16 @@ import java.util.Map; import org.opentripplanner.osm.model.OsmWay; import org.opentripplanner.street.model.edge.EscalatorEdge; -import org.opentripplanner.street.model.vertex.IntersectionVertex; +import org.opentripplanner.street.model.vertex.Vertex; /** * Contains the logic for extracting escalators out of OSM data */ class EscalatorProcessor { - private final Map intersectionNodes; + private final Map intersectionNodes; - public EscalatorProcessor(Map intersectionNodes) { + public EscalatorProcessor(Map intersectionNodes) { this.intersectionNodes = intersectionNodes; } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java index f257d619f09..19bbaec14fe 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/OsmModule.java @@ -31,7 +31,6 @@ import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.StreetEdgeBuilder; import org.opentripplanner.street.model.vertex.BarrierVertex; -import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.utils.logging.ProgressTracker; import org.slf4j.Logger; @@ -295,8 +294,8 @@ private void buildBasicGraph() { lastLevel = level; } - IntersectionVertex startEndpoint = null; - IntersectionVertex endEndpoint = null; + Vertex startEndpoint = null; + Vertex endEndpoint = null; ArrayList segmentCoordinates = new ArrayList<>(); @@ -465,8 +464,8 @@ private void applyEdgesToTurnRestrictions( * http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing#Oneway. */ private StreetEdgePair getEdgesForStreet( - IntersectionVertex startEndpoint, - IntersectionVertex endEndpoint, + Vertex startEndpoint, + Vertex endEndpoint, OsmWay way, int index, StreetTraversalPermission permissions, @@ -519,8 +518,8 @@ private StreetEdgePair getEdgesForStreet( } private StreetEdge getEdgeForStreet( - IntersectionVertex startEndpoint, - IntersectionVertex endEndpoint, + Vertex startEndpoint, + Vertex endEndpoint, OsmWay way, int index, double length, diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java index f372f0c82e2..37a6e9fd714 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/ParkingProcessor.java @@ -30,8 +30,8 @@ import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.StreetEdge; import org.opentripplanner.street.model.edge.VehicleParkingEdge; -import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexFactory; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.transit.model.framework.FeedScopedId; @@ -44,14 +44,14 @@ class ParkingProcessor { private static final String VEHICLE_PARKING_OSM_FEED_ID = "OSM"; private final DataImportIssueStore issueStore; private final OsmOpeningHoursParser osmOpeningHoursParser; - private final BiFunction getVertexForOsmNode; + private final BiFunction getVertexForOsmNode; private final VertexFactory vertexFactory; private final VehicleParkingHelper vehicleParkingHelper; public ParkingProcessor( Graph graph, DataImportIssueStore issueStore, - BiFunction getVertexForOsmNode + BiFunction getVertexForOsmNode ) { this.issueStore = issueStore; this.getVertexForOsmNode = getVertexForOsmNode; @@ -475,4 +475,4 @@ private List createParkingEntrance } } -record VertexAndName(I18NString name, IntersectionVertex vertex) {} +record VertexAndName(I18NString name, Vertex vertex) {} 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 b4c3c08aa8b..432214da5a7 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 @@ -7,6 +7,7 @@ import java.util.Map; import java.util.Set; import org.locationtech.jts.geom.Coordinate; +import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.osm.model.OsmLevel; import org.opentripplanner.osm.model.OsmNode; @@ -15,10 +16,13 @@ import org.opentripplanner.routing.graph.Graph; import org.opentripplanner.street.model.edge.ElevatorEdge; import org.opentripplanner.street.model.vertex.BarrierVertex; -import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.OsmBoardingLocationVertex; import org.opentripplanner.street.model.vertex.OsmVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexFactory; +import org.opentripplanner.transit.model.basic.Accessibility; +import org.opentripplanner.transit.model.framework.FeedScopedId; +import org.opentripplanner.transit.model.site.Entrance; /** * Tracks the generation of vertices and returns an existing instance if a vertex is encountered @@ -28,7 +32,7 @@ class VertexGenerator { private static final String nodeLabelFormat = "osm:node:%d"; - private final Map intersectionNodes = new HashMap<>(); + private final Map intersectionNodes = new HashMap<>(); private final HashMap> multiLevelNodes = new HashMap<>(); private final OsmDatabase osmdb; @@ -58,11 +62,11 @@ public VertexGenerator( * @return vertex The graph vertex. This is not always an OSM vertex; it can also be a * {@link OsmBoardingLocationVertex} */ - IntersectionVertex getVertexForOsmNode(OsmNode node, OsmWithTags way) { + Vertex getVertexForOsmNode(OsmNode node, OsmWithTags way) { // If the node should be decomposed to multiple levels, // use the numeric level because it is unique, the human level may not be (although // it will likely lead to some head-scratching if it is not). - IntersectionVertex iv = null; + Vertex iv = null; if (node.isMultiLevel()) { // make a separate node for every level return recordLevel(node, way); @@ -106,7 +110,18 @@ IntersectionVertex getVertexForOsmNode(OsmNode node, OsmWithTags way) { String ref = node.getTag("ref"); boolean accessible = node.isTag("wheelchair", "yes"); - iv = vertexFactory.stationEntrance(nid, coordinate, ref, accessible); + + FeedScopedId id = new FeedScopedId("osm", Long.toString(nid)); + Entrance entrance = Entrance + .of(id) + .withCoordinate(new WgsCoordinate(coordinate)) + .withCode(ref) + .withWheelchairAccessibility( + accessible ? Accessibility.POSSIBLE : Accessibility.NOT_POSSIBLE + ) + .build(); + + iv = vertexFactory.transitEntrance(entrance); } if (iv == null) { @@ -161,7 +176,7 @@ void initIntersectionNodes() { /** * Track OSM nodes that will become graph vertices because they appear in multiple OSM ways */ - Map intersectionNodes() { + Map intersectionNodes() { return intersectionNodes; } diff --git a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java index f27d80d5617..c32e6083ce2 100644 --- a/application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java +++ b/application/src/main/java/org/opentripplanner/graph_builder/module/osm/WalkableAreaBuilder.java @@ -212,7 +212,7 @@ public void buildWithVisibility(AreaGroup group) { // or those linked to ways HashSet visibilityNodes = new HashSet<>(); HashSet alreadyAddedEdges = new HashSet<>(); - HashSet platformLinkingVertices = new HashSet<>(); + HashSet platformLinkingVertices = new HashSet<>(); // we need to accumulate visibility points from all contained areas // inside this ring, but only for shared nodes; we don't care about // convexity, which we'll handle for the grouped area only. @@ -340,7 +340,7 @@ public void buildWithVisibility(AreaGroup group) { continue; } i = (int) Math.floor(sum_i); - IntersectionVertex startEndpoint = vertexBuilder.getVertexForOsmNode(nodeI, areaEntity); + Vertex startEndpoint = vertexBuilder.getVertexForOsmNode(nodeI, areaEntity); if (startingNodes.contains(nodeI)) { startingVertices.add(startEndpoint); } @@ -355,7 +355,7 @@ public void buildWithVisibility(AreaGroup group) { NodeEdge edge = new NodeEdge(nodeI, nodeJ); if (alreadyAddedEdges.contains(edge)) continue; - IntersectionVertex endEndpoint = vertexBuilder.getVertexForOsmNode(nodeJ, areaEntity); + Vertex endEndpoint = vertexBuilder.getVertexForOsmNode(nodeJ, areaEntity); Coordinate[] coordinates = new Coordinate[] { startEndpoint.getCoordinate(), @@ -463,15 +463,15 @@ private Set createEdgesForRingSegment( return Set.of(); } alreadyAddedEdges.add(nodeEdge); - IntersectionVertex startEndpoint = vertexBuilder.getVertexForOsmNode(node, area.parent); - IntersectionVertex endEndpoint = vertexBuilder.getVertexForOsmNode(nextNode, area.parent); + Vertex startEndpoint = vertexBuilder.getVertexForOsmNode(node, area.parent); + Vertex endEndpoint = vertexBuilder.getVertexForOsmNode(nextNode, area.parent); return createSegments(startEndpoint, endEndpoint, List.of(area), edgeList); } private Set createSegments( - IntersectionVertex startEndpoint, - IntersectionVertex endEndpoint, + Vertex startEndpoint, + Vertex endEndpoint, Collection areas, AreaEdgeList edgeList ) { 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 39941b72ecd..4c13f172255 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 @@ -25,13 +25,10 @@ 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.TransitEntranceVertex; 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.framework.FeedScopedId; -import org.opentripplanner.transit.model.site.Entrance; /** * Process a list of states into a list of walking/driving instructions for a street leg. @@ -179,7 +176,7 @@ private void processState(State backState, State forwardState) { if (edge instanceof ElevatorAlightEdge) { addStep(createElevatorWalkStep(backState, forwardState, edge)); return; - } else if (backState.getVertex() instanceof StationEntranceVertex) { + } else if (backState.getVertex() instanceof TransitEntranceVertex) { addStep(createStationEntranceWalkStep(backState, forwardState, edge)); return; } else if (edge instanceof PathwayEdge pwe && pwe.signpostedAs().isPresent()) { @@ -533,20 +530,9 @@ private WalkStepBuilder createStationEntranceWalkStep( // since the doors might be between or inside stations. step.withRelativeDirection(RelativeDirection.ENTER_OR_EXIT_STATION); - StationEntranceVertex vertex = (StationEntranceVertex) backState.getVertex(); + TransitEntranceVertex vertex = (TransitEntranceVertex) backState.getVertex(); - FeedScopedId entranceId = new FeedScopedId("osm", vertex.getId()); - - Entrance entrance = Entrance - .of(entranceId) - .withCode(vertex.getCode()) - .withCoordinate(new WgsCoordinate(vertex.getCoordinate())) - .withWheelchairAccessibility( - vertex.isAccessible() ? Accessibility.POSSIBLE : Accessibility.NOT_POSSIBLE - ) - .build(); - - step.withEntrance(entrance); + step.withEntrance(vertex.getEntrance()); return step; } diff --git a/application/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java b/application/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java index e9d29f596c7..a762382ccaf 100644 --- a/application/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java +++ b/application/src/main/java/org/opentripplanner/routing/linking/FlexLocationAdder.java @@ -6,17 +6,13 @@ import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.street.model.StreetTraversalPermission; import org.opentripplanner.street.model.edge.StreetEdge; -import org.opentripplanner.street.model.vertex.IntersectionVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.transit.model.site.AreaStop; import org.opentripplanner.transit.service.SiteRepository; class FlexLocationAdder { - static void addFlexLocations( - StreetEdge edge, - IntersectionVertex v0, - SiteRepository siteRepository - ) { + static void addFlexLocations(StreetEdge edge, Vertex v0, SiteRepository siteRepository) { if (edge.getPermission().allows(StreetTraversalPermission.PEDESTRIAN_AND_CAR)) { Point p = GeometryUtils.getGeometryFactory().createPoint(v0.getCoordinate()); Envelope env = p.getEnvelopeInternal(); diff --git a/application/src/main/java/org/opentripplanner/routing/linking/VertexLinker.java b/application/src/main/java/org/opentripplanner/routing/linking/VertexLinker.java index 48f5ff997c8..0be89121a7c 100644 --- a/application/src/main/java/org/opentripplanner/routing/linking/VertexLinker.java +++ b/application/src/main/java/org/opentripplanner/routing/linking/VertexLinker.java @@ -26,9 +26,7 @@ import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.NamedArea; import org.opentripplanner.street.model.edge.StreetEdge; -import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.SplitterVertex; -import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TemporarySplitterVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.model.vertex.VertexFactory; @@ -96,7 +94,7 @@ public void linkVertexPermanently( Vertex vertex, TraverseModeSet traverseModes, LinkingDirection direction, - BiFunction> edgeFunction + BiFunction> edgeFunction ) { link(vertex, traverseModes, direction, Scope.PERMANENT, edgeFunction); } @@ -105,7 +103,7 @@ public DisposableEdgeCollection linkVertexForRealTime( Vertex vertex, TraverseModeSet traverseModes, LinkingDirection direction, - BiFunction> edgeFunction + BiFunction> edgeFunction ) { return link(vertex, traverseModes, direction, Scope.REALTIME, edgeFunction); } @@ -114,7 +112,7 @@ public DisposableEdgeCollection linkVertexForRequest( Vertex vertex, TraverseModeSet traverseModes, LinkingDirection direction, - BiFunction> edgeFunction + BiFunction> edgeFunction ) { return link(vertex, traverseModes, direction, Scope.REQUEST, edgeFunction); } @@ -181,14 +179,14 @@ private DisposableEdgeCollection link( TraverseModeSet traverseModes, LinkingDirection direction, Scope scope, - BiFunction> edgeFunction + BiFunction> edgeFunction ) { DisposableEdgeCollection tempEdges = (scope != Scope.PERMANENT) ? new DisposableEdgeCollection(graph, scope) : null; try { - Set streetVertices = linkToStreetEdges( + Set streetVertices = linkToStreetEdges( vertex, traverseModes, direction, @@ -208,7 +206,7 @@ private DisposableEdgeCollection link( ); } - for (StreetVertex streetVertex : streetVertices) { + for (Vertex streetVertex : streetVertices) { List edges = edgeFunction.apply(vertex, streetVertex); if (tempEdges != null) { for (Edge edge : edges) { @@ -226,7 +224,7 @@ private DisposableEdgeCollection link( return tempEdges; } - private Set linkToStreetEdges( + private Set linkToStreetEdges( Vertex vertex, TraverseModeSet traverseModes, LinkingDirection direction, @@ -329,7 +327,7 @@ private Set> getClosestEdgesPerMode( } /** Split the edge if necessary return the closest vertex */ - private StreetVertex link( + private Vertex link( Vertex vertex, StreetEdge edge, double xScale, @@ -345,7 +343,7 @@ private StreetVertex link( LinearLocation ll = il.project(new Coordinate(vertex.getLon() * xScale, vertex.getLat())); double length = SphericalDistanceLibrary.length(orig); - IntersectionVertex start = null; + Vertex start = null; boolean snapped = true; // if we're very close to one end of the line or the other, or endwise, don't bother to split, @@ -356,19 +354,19 @@ private StreetVertex link( ll.getSegmentIndex() == 0 && (ll.getSegmentFraction() < 1e-8 || ll.getSegmentFraction() * length < 0.1) ) { - start = (IntersectionVertex) edge.getFromVertex(); + start = (Vertex) edge.getFromVertex(); } // -1 converts from count to index. Because of the fencepost problem, npoints - 1 is the "segment" // past the last point else if (ll.getSegmentIndex() == orig.getNumPoints() - 1) { - start = (IntersectionVertex) edge.getToVertex(); + start = (Vertex) edge.getToVertex(); } // nPoints - 2: -1 to correct for index vs count, -1 to account for fencepost problem else if ( ll.getSegmentIndex() == orig.getNumPoints() - 2 && (ll.getSegmentFraction() > 1 - 1e-8 || (1 - ll.getSegmentFraction()) * length < 0.1) ) { - start = (IntersectionVertex) edge.getToVertex(); + start = (Vertex) edge.getToVertex(); } else { snapped = false; boolean split = true; @@ -380,7 +378,7 @@ else if ( if (!linkedAreas.add(ael)) { return null; } - if (vertex instanceof IntersectionVertex iv) { + if (vertex instanceof Vertex iv) { start = iv; } else { start = splitVertex(aEdge, scope, direction, vertex.getLon(), vertex.getLat()); @@ -522,7 +520,7 @@ public boolean equals(Object o) { /** * Link a new vertex permanently with area geometry */ - public void addPermanentAreaVertex(IntersectionVertex newVertex, AreaEdgeList edgeList) { + public void addPermanentAreaVertex(Vertex newVertex, AreaEdgeList edgeList) { addAreaVertex(newVertex, edgeList, Scope.PERMANENT, null); } @@ -532,7 +530,7 @@ public void addPermanentAreaVertex(IntersectionVertex newVertex, AreaEdgeList ed */ public void addAreaVertex( - IntersectionVertex newVertex, + Vertex newVertex, AreaEdgeList edgeList, Scope scope, DisposableEdgeCollection tempEdges @@ -556,7 +554,7 @@ public void addAreaVertex( int i = 0; float sum_i = 0; - for (IntersectionVertex v : edgeList.visibilityVertices()) { + for (Vertex v : edgeList.visibilityVertices()) { sum_i += skip_ratio; if (Math.floor(sum_i) < i + 1) { continue; @@ -581,7 +579,7 @@ public void addAreaVertex( // TODO: Temporary fix for unconnected area edges. This should go away when moving walkable // area calculation to be done after stop linking if (added == 0) { - for (IntersectionVertex v : edgeList.visibilityVertices()) { + for (Vertex v : edgeList.visibilityVertices()) { createSegments(newVertex, v, edgeList, areas, scope, tempEdges); } } @@ -611,8 +609,8 @@ private Set getNoThruModes(Collection edges) { } private void createSegments( - IntersectionVertex from, - IntersectionVertex to, + Vertex from, + Vertex to, AreaEdgeList ael, List areas, Scope scope, diff --git a/application/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingEntrance.java b/application/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingEntrance.java index f6bc584fb18..73cd50e6606 100644 --- a/application/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingEntrance.java +++ b/application/src/main/java/org/opentripplanner/routing/vehicle_parking/VehicleParkingEntrance.java @@ -5,7 +5,7 @@ import javax.annotation.Nullable; import org.opentripplanner.framework.geometry.WgsCoordinate; import org.opentripplanner.framework.i18n.I18NString; -import org.opentripplanner.street.model.vertex.StreetVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.transit.model.framework.FeedScopedId; import org.opentripplanner.utils.tostring.ToStringBuilder; @@ -23,14 +23,14 @@ public class VehicleParkingEntrance implements Serializable { // If this entrance should be linked to walk/bike accessible streets private final boolean walkAccessible; // Used to explicitly specify the intersection to link to instead of using (x, y) - private transient StreetVertex vertex; + private transient Vertex vertex; VehicleParkingEntrance( VehicleParking vehicleParking, FeedScopedId entranceId, WgsCoordinate coordinate, I18NString name, - StreetVertex vertex, + Vertex vertex, boolean carAccessible, boolean walkAccessible ) { @@ -64,7 +64,7 @@ public I18NString getName() { return name; } - public StreetVertex getVertex() { + public Vertex getVertex() { return vertex; } @@ -120,7 +120,7 @@ public static class VehicleParkingEntranceBuilder { private FeedScopedId entranceId; private WgsCoordinate coordinate; private I18NString name; - private StreetVertex vertex; + private Vertex vertex; private boolean carAccessible; private boolean walkAccessible; @@ -146,7 +146,7 @@ public VehicleParkingEntranceBuilder name(I18NString name) { return this; } - public VehicleParkingEntranceBuilder vertex(StreetVertex vertex) { + public VehicleParkingEntranceBuilder vertex(Vertex vertex) { this.vertex = vertex; return this; } diff --git a/application/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java index 99775b6112d..869b99fd4ce 100644 --- a/application/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java +++ b/application/src/main/java/org/opentripplanner/service/vehiclerental/street/StreetVehicleRentalLink.java @@ -2,7 +2,7 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.street.model.edge.Edge; -import org.opentripplanner.street.model.vertex.StreetVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.StateEditor; @@ -13,18 +13,18 @@ public class StreetVehicleRentalLink extends Edge { private final VehicleRentalPlaceVertex vehicleRentalPlaceVertex; - private StreetVehicleRentalLink(StreetVertex fromv, VehicleRentalPlaceVertex tov) { + private StreetVehicleRentalLink(Vertex fromv, VehicleRentalPlaceVertex tov) { super(fromv, tov); vehicleRentalPlaceVertex = tov; } - private StreetVehicleRentalLink(VehicleRentalPlaceVertex fromv, StreetVertex tov) { + private StreetVehicleRentalLink(VehicleRentalPlaceVertex fromv, Vertex tov) { super(fromv, tov); vehicleRentalPlaceVertex = fromv; } public static StreetVehicleRentalLink createStreetVehicleRentalLink( - StreetVertex fromv, + Vertex fromv, VehicleRentalPlaceVertex tov ) { return connectToGraph(new StreetVehicleRentalLink(fromv, tov)); @@ -32,7 +32,7 @@ public static StreetVehicleRentalLink createStreetVehicleRentalLink( public static StreetVehicleRentalLink createStreetVehicleRentalLink( VehicleRentalPlaceVertex fromv, - StreetVertex tov + Vertex tov ) { return connectToGraph(new StreetVehicleRentalLink(fromv, tov)); } diff --git a/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeBuilder.java b/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeBuilder.java index efabefa7cea..0677a7a11bf 100644 --- a/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeBuilder.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeBuilder.java @@ -1,6 +1,6 @@ package org.opentripplanner.street.model.edge; -import org.opentripplanner.street.model.vertex.IntersectionVertex; +import org.opentripplanner.street.model.vertex.Vertex; public class AreaEdgeBuilder extends StreetEdgeBuilder { @@ -12,13 +12,13 @@ public AreaEdge buildAndConnect() { } @Override - public IntersectionVertex fromVertex() { - return (IntersectionVertex) super.fromVertex(); + public Vertex fromVertex() { + return super.fromVertex(); } @Override - public IntersectionVertex toVertex() { - return (IntersectionVertex) super.toVertex(); + public Vertex toVertex() { + return super.toVertex(); } public AreaEdgeList area() { diff --git a/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java b/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java index 1f8d286995b..ec2b04877e1 100644 --- a/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/AreaEdgeList.java @@ -9,7 +9,7 @@ import java.util.stream.Stream; import org.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.Polygon; -import org.opentripplanner.street.model.vertex.IntersectionVertex; +import org.opentripplanner.street.model.vertex.Vertex; /** * This is a representation of a set of contiguous OSM areas, used for various tasks related to edge @@ -19,8 +19,8 @@ */ public class AreaEdgeList implements Serializable { - private static final Set EMPTY_SET = Set.of(); - private Set visibilityVertices = EMPTY_SET; + private static final Set EMPTY_SET = Set.of(); + private Set visibilityVertices = EMPTY_SET; // these are all of the original edges of the area, whether // or not there are corresponding OSM edges. It is used as part of a hack @@ -59,14 +59,14 @@ public Geometry getGeometry() { /** * Returns the list of visibility vertices. */ - public Set visibilityVertices() { + public Set visibilityVertices() { return visibilityVertices; } /** * Add a visibility vertex to this edge. */ - public void addVisibilityVertex(IntersectionVertex toBeAdded) { + public void addVisibilityVertex(Vertex toBeAdded) { Objects.requireNonNull(toBeAdded); synchronized (this) { if (visibilityVertices == EMPTY_SET) { diff --git a/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java index b606bcd9962..786faf60098 100644 --- a/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdge.java @@ -28,7 +28,7 @@ import org.opentripplanner.street.model.vertex.BarrierVertex; import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.SplitterVertex; -import org.opentripplanner.street.model.vertex.StreetVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.TraverseModeSet; import org.opentripplanner.street.search.state.State; @@ -626,7 +626,7 @@ public SplitStreetEdge splitDestructively(SplitterVertex v) { SplitLineString geoms = GeometryUtils.splitGeometryAtPoint(getGeometry(), v.getCoordinate()); StreetEdgeBuilder seb1 = new StreetEdgeBuilder<>() - .withFromVertex((StreetVertex) fromv) + .withFromVertex(fromv) .withToVertex(v) .withGeometry(geoms.beginning()) .withName(name) @@ -635,7 +635,7 @@ public SplitStreetEdge splitDestructively(SplitterVertex v) { StreetEdgeBuilder seb2 = new StreetEdgeBuilder<>() .withFromVertex(v) - .withToVertex((StreetVertex) tov) + .withToVertex(tov) .withGeometry(geoms.ending()) .withName(name) .withPermission(permission) @@ -712,7 +712,7 @@ public SplitStreetEdge splitNonDestructively( if (direction == LinkingDirection.OUTGOING || direction == LinkingDirection.BOTH_WAYS) { var seb1 = new TemporaryPartialStreetEdgeBuilder() .withParentEdge(this) - .withFromVertex((StreetVertex) fromv) + .withFromVertex(fromv) .withToVertex(v) .withGeometry(geoms.beginning()) .withName(name) @@ -726,7 +726,7 @@ public SplitStreetEdge splitNonDestructively( var seb2 = new TemporaryPartialStreetEdgeBuilder() .withParentEdge(this) .withFromVertex(v) - .withToVertex((StreetVertex) tov) + .withToVertex(tov) .withGeometry(geoms.ending()) .withName(name) .withBack(isBack()); @@ -745,7 +745,7 @@ public SplitStreetEdge splitNonDestructively( return splitEdges; } - public Optional createPartialEdge(StreetVertex from, StreetVertex to) { + public Optional createPartialEdge(Vertex from, Vertex to) { LineString parent = getGeometry(); LineString head = GeometryUtils.getInteriorSegment( parent, diff --git a/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java index 99a02205eb6..7fa1bb72d4c 100644 --- a/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetEdgeBuilder.java @@ -15,7 +15,7 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.framework.i18n.NonLocalizedString; import org.opentripplanner.street.model.StreetTraversalPermission; -import org.opentripplanner.street.model.vertex.StreetVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.utils.lang.BitSetUtils; @@ -26,8 +26,8 @@ public class StreetEdgeBuilder> { public static final float DEFAULT_WALK_SAFETY_FACTOR = 1.0f; private static final float DEFAULT_BICYCLE_SAFETY_FACTOR = 1.0f; - private StreetVertex from; - private StreetVertex to; + private Vertex from; + private Vertex to; private LineString geometry; private I18NString name; private int millimeterLength; @@ -48,8 +48,8 @@ public StreetEdgeBuilder() { } public StreetEdgeBuilder(StreetEdge original) { - this.from = (StreetVertex) original.getFromVertex(); - this.to = (StreetVertex) original.getToVertex(); + this.from = original.getFromVertex(); + this.to = original.getToVertex(); this.geometry = original.getGeometry(); this.name = original.getName(); this.millimeterLength = original.getMillimeterLength(); @@ -65,20 +65,20 @@ public StreetEdge buildAndConnect() { return Edge.connectToGraph(new StreetEdge(this)); } - public StreetVertex fromVertex() { + public Vertex fromVertex() { return from; } - public B withFromVertex(StreetVertex from) { + public B withFromVertex(Vertex from) { this.from = from; return instance(); } - public StreetVertex toVertex() { + public Vertex toVertex() { return to; } - public B withToVertex(StreetVertex to) { + public B withToVertex(Vertex to) { this.to = to; return instance(); } diff --git a/application/src/main/java/org/opentripplanner/street/model/edge/StreetStationCentroidLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetStationCentroidLink.java index 6b336907db5..d0e7ef13363 100644 --- a/application/src/main/java/org/opentripplanner/street/model/edge/StreetStationCentroidLink.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetStationCentroidLink.java @@ -1,23 +1,23 @@ package org.opentripplanner.street.model.edge; import org.opentripplanner.street.model.vertex.StationCentroidVertex; -import org.opentripplanner.street.model.vertex.StreetVertex; +import org.opentripplanner.street.model.vertex.Vertex; /** * This represents the connection between a street vertex and a transit station centroid vertex */ public class StreetStationCentroidLink extends FreeEdge { - private StreetStationCentroidLink(StreetVertex fromv, StationCentroidVertex tov) { + private StreetStationCentroidLink(Vertex fromv, StationCentroidVertex tov) { super(fromv, tov); } - private StreetStationCentroidLink(StationCentroidVertex fromv, StreetVertex tov) { + private StreetStationCentroidLink(StationCentroidVertex fromv, Vertex tov) { super(fromv, tov); } public static StreetStationCentroidLink createStreetStationLink( - StreetVertex fromv, + Vertex fromv, StationCentroidVertex tov ) { return connectToGraph(new StreetStationCentroidLink(fromv, tov)); @@ -25,7 +25,7 @@ public static StreetStationCentroidLink createStreetStationLink( public static StreetStationCentroidLink createStreetStationLink( StationCentroidVertex fromv, - StreetVertex tov + Vertex tov ) { return connectToGraph(new StreetStationCentroidLink(fromv, tov)); } diff --git a/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java index 5a62eda0f90..9a05590c7d0 100644 --- a/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntityLink.java @@ -5,7 +5,10 @@ import org.opentripplanner.framework.geometry.GeometryUtils; import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.routing.api.request.preference.RoutingPreferences; -import org.opentripplanner.street.model.vertex.StreetVertex; +import org.opentripplanner.street.model.vertex.StationCentroidVertex; +import org.opentripplanner.street.model.vertex.TransitEntranceVertex; +import org.opentripplanner.street.model.vertex.TransitStopVertex; +import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.StateEditor; @@ -20,13 +23,13 @@ public abstract class StreetTransitEntityLink static final int STEL_TRAVERSE_COST = 1; - private final T transitEntityVertex; + private final Vertex transitEntityVertex; private final Accessibility wheelchairAccessibility; protected StreetTransitEntityLink( - StreetVertex fromv, - T tov, + Vertex fromv, + TransitEntranceVertex tov, Accessibility wheelchairAccessibility ) { super(fromv, tov); @@ -35,8 +38,68 @@ protected StreetTransitEntityLink( } protected StreetTransitEntityLink( - T fromv, - StreetVertex tov, + TransitEntranceVertex fromv, + Vertex tov, + Accessibility wheelchairAccessibility + ) { + super(fromv, tov); + this.transitEntityVertex = fromv; + this.wheelchairAccessibility = wheelchairAccessibility; + } + + protected StreetTransitEntityLink( + Vertex fromv, + VehicleParkingEntranceVertex tov, + Accessibility wheelchairAccessibility + ) { + super(fromv, tov); + this.transitEntityVertex = tov; + this.wheelchairAccessibility = wheelchairAccessibility; + } + + protected StreetTransitEntityLink( + VehicleParkingEntranceVertex fromv, + Vertex tov, + Accessibility wheelchairAccessibility + ) { + super(fromv, tov); + this.transitEntityVertex = fromv; + this.wheelchairAccessibility = wheelchairAccessibility; + } + + protected StreetTransitEntityLink( + Vertex fromv, + TransitStopVertex tov, + Accessibility wheelchairAccessibility + ) { + super(fromv, tov); + this.transitEntityVertex = tov; + this.wheelchairAccessibility = wheelchairAccessibility; + } + + protected StreetTransitEntityLink( + TransitStopVertex fromv, + Vertex tov, + Accessibility wheelchairAccessibility + ) { + super(fromv, tov); + this.transitEntityVertex = fromv; + this.wheelchairAccessibility = wheelchairAccessibility; + } + + protected StreetTransitEntityLink( + Vertex fromv, + StationCentroidVertex tov, + Accessibility wheelchairAccessibility + ) { + super(fromv, tov); + this.transitEntityVertex = tov; + this.wheelchairAccessibility = wheelchairAccessibility; + } + + protected StreetTransitEntityLink( + StationCentroidVertex fromv, + Vertex tov, Accessibility wheelchairAccessibility ) { super(fromv, tov); @@ -159,7 +222,7 @@ public LineString getGeometry() { protected abstract int getStreetToStopTime(); - protected T getTransitEntityVertex() { + protected Vertex getTransitEntityVertex() { return transitEntityVertex; } diff --git a/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java index 7145f6183e4..d79e54c9b76 100644 --- a/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetTransitEntranceLink.java @@ -1,7 +1,7 @@ package org.opentripplanner.street.model.edge; -import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TransitEntranceVertex; +import org.opentripplanner.street.model.vertex.Vertex; /** * This represents the connection between a street vertex and a transit vertex belonging the street @@ -11,18 +11,18 @@ public class StreetTransitEntranceLink extends StreetTransitEntityLink { - private StreetTransitStopLink(StreetVertex fromv, TransitStopVertex tov) { + private StreetTransitStopLink(Vertex fromv, TransitStopVertex tov) { super(fromv, tov, tov.getWheelchairAccessibility()); } - private StreetTransitStopLink(TransitStopVertex fromv, StreetVertex tov) { + private StreetTransitStopLink(TransitStopVertex fromv, Vertex tov) { super(fromv, tov, fromv.getWheelchairAccessibility()); } public static StreetTransitStopLink createStreetTransitStopLink( - StreetVertex fromv, + Vertex fromv, TransitStopVertex tov ) { return connectToGraph(new StreetTransitStopLink(fromv, tov)); @@ -26,14 +26,14 @@ public static StreetTransitStopLink createStreetTransitStopLink( public static StreetTransitStopLink createStreetTransitStopLink( TransitStopVertex fromv, - StreetVertex tov + Vertex tov ) { return connectToGraph(new StreetTransitStopLink(fromv, tov)); } protected int getStreetToStopTime() { - return getTransitEntityVertex().hasPathways() + return ((TransitStopVertex) getTransitEntityVertex()).hasPathways() ? 0 - : getTransitEntityVertex().getStreetToStopTime(); + : ((TransitStopVertex) getTransitEntityVertex()).getStreetToStopTime(); } } diff --git a/application/src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java b/application/src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java index 682aeca0b3e..907feea2639 100644 --- a/application/src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java +++ b/application/src/main/java/org/opentripplanner/street/model/edge/StreetVehicleParkingLink.java @@ -5,8 +5,8 @@ import org.opentripplanner.framework.i18n.I18NString; import org.opentripplanner.routing.api.request.preference.VehicleParkingPreferences; import org.opentripplanner.routing.vehicle_parking.VehicleParking; -import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex; +import org.opentripplanner.street.model.vertex.Vertex; import org.opentripplanner.street.search.TraverseMode; import org.opentripplanner.street.search.state.State; import org.opentripplanner.street.search.state.StateEditor; @@ -18,18 +18,18 @@ public class StreetVehicleParkingLink extends Edge { private final VehicleParkingEntranceVertex vehicleParkingEntranceVertex; - private StreetVehicleParkingLink(StreetVertex fromv, VehicleParkingEntranceVertex tov) { + private StreetVehicleParkingLink(Vertex fromv, VehicleParkingEntranceVertex tov) { super(fromv, tov); vehicleParkingEntranceVertex = tov; } - private StreetVehicleParkingLink(VehicleParkingEntranceVertex fromv, StreetVertex tov) { + private StreetVehicleParkingLink(VehicleParkingEntranceVertex fromv, Vertex tov) { super(fromv, tov); vehicleParkingEntranceVertex = fromv; } public static StreetVehicleParkingLink createStreetVehicleParkingLink( - StreetVertex fromv, + Vertex fromv, VehicleParkingEntranceVertex tov ) { return connectToGraph(new StreetVehicleParkingLink(fromv, tov)); @@ -37,7 +37,7 @@ public static StreetVehicleParkingLink createStreetVehicleParkingLink( public static StreetVehicleParkingLink createStreetVehicleParkingLink( VehicleParkingEntranceVertex fromv, - StreetVertex tov + Vertex tov ) { return connectToGraph(new StreetVehicleParkingLink(fromv, tov)); } diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java index 81b89ad3dfb..4e7e99d4424 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/TransitEntranceVertex.java @@ -36,4 +36,8 @@ public Entrance getEntrance() { public StationElement getStationElement() { return this.entrance; } + + public boolean isConnectedToGraph() { + return getDegreeOut() + getDegreeIn() > 0; + } } diff --git a/application/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java b/application/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java index 75fd5b7218e..80cd985e286 100644 --- a/application/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java +++ b/application/src/main/java/org/opentripplanner/street/model/vertex/Vertex.java @@ -8,6 +8,10 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.locationtech.jts.geom.Coordinate; import org.opentripplanner.astar.spi.AStarVertex; import org.opentripplanner.framework.geometry.WgsCoordinate; @@ -15,7 +19,10 @@ import org.opentripplanner.street.model.RentalRestrictionExtension; import org.opentripplanner.street.model.edge.Edge; import org.opentripplanner.street.model.edge.StreetEdge; +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.AreaStop; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +42,8 @@ public abstract class Vertex implements AStarVertex, Serial private transient Edge[] outgoing = new Edge[0]; private RentalRestrictionExtension rentalRestrictions = RentalRestrictionExtension.NO_RESTRICTION; + private static final Set EMPTY_SET = Set.of(); + private Set areaStops = EMPTY_SET; /* CONSTRUCTORS */ @@ -113,6 +122,25 @@ public int getDegreeIn() { return incoming.length; } + /** + * Does the vertex have an outgoing edge that allows driving. + */ + public boolean isConnectedToDriveableEdge() { + return this.getOutgoing() + .stream() + .anyMatch(edge -> + edge instanceof StreetEdge && ((StreetEdge) edge).getPermission().allows(TraverseMode.CAR) + ); + } + + public boolean isConnectedToWalkingEdge() { + return this.getOutgoing() + .stream() + .anyMatch(edge -> + edge instanceof StreetEdge && ((StreetEdge) edge).getPermission().allows(TraverseMode.WALK) + ); + } + /** Get the longitude of the vertex */ public final double getX() { return getLon(); @@ -225,6 +253,10 @@ public boolean rentalTraversalBanned(State currentState) { return rentalRestrictions.traversalBanned(currentState); } + public Accessibility getWheelchairAccessibility() { + return Accessibility.NO_INFORMATION; + } + public void addRentalRestriction(RentalRestrictionExtension ext) { rentalRestrictions = rentalRestrictions.add(ext); } @@ -302,4 +334,28 @@ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundE this.incoming = new Edge[0]; this.outgoing = new Edge[0]; } + + /** + * Returns the list of area stops that this vertex is inside of. + */ + public Set areaStops() { + return areaStops; + } + + /** + * Add a collection of area stops to this vertex. + */ + public void addAreaStops(Collection toBeAdded) { + Objects.requireNonNull(toBeAdded); + synchronized (this) { + if (areaStops == EMPTY_SET) { + areaStops = Set.copyOf(toBeAdded); + } else { + areaStops = + Stream + .concat(areaStops.stream(), toBeAdded.stream()) + .collect(Collectors.toUnmodifiableSet()); + } + } + } } diff --git a/application/src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java b/application/src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java index b9f9d7acb56..2cd97beac0b 100644 --- a/application/src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java +++ b/application/src/test/java/org/opentripplanner/routing/algorithm/GraphRoutingTest.java @@ -39,7 +39,6 @@ import org.opentripplanner.street.model.vertex.ElevatorOnboardVertex; import org.opentripplanner.street.model.vertex.IntersectionVertex; import org.opentripplanner.street.model.vertex.StationCentroidVertex; -import org.opentripplanner.street.model.vertex.StreetVertex; import org.opentripplanner.street.model.vertex.TemporaryStreetLocation; import org.opentripplanner.street.model.vertex.TemporaryVertex; import org.opentripplanner.street.model.vertex.TransitEntranceVertex; @@ -118,8 +117,8 @@ public IntersectionVertex intersection(String label, WgsCoordinate coordinate) { } public StreetEdgeBuilder streetBuilder( - StreetVertex from, - StreetVertex to, + Vertex from, + Vertex to, int length, StreetTraversalPermission permissions ) { @@ -138,13 +137,13 @@ public StreetEdgeBuilder streetBuilder( /** * Create a street with all permissions in both directions */ - public List biStreet(StreetVertex from, StreetVertex to, int length) { + public List biStreet(Vertex from, Vertex to, int length) { return street(from, to, length, StreetTraversalPermission.ALL, StreetTraversalPermission.ALL); } public StreetEdge street( - StreetVertex from, - StreetVertex to, + Vertex from, + Vertex to, int length, StreetTraversalPermission permissions ) { @@ -152,8 +151,8 @@ public StreetEdge street( } public List street( - StreetVertex from, - StreetVertex to, + Vertex from, + Vertex to, int length, StreetTraversalPermission forwardPermissions, StreetTraversalPermission reversePermissions @@ -300,39 +299,39 @@ public StationCentroidVertex stationCentroid(Station station) { return vertexFactory.stationCentroid(station); } - public StreetTransitEntranceLink link(StreetVertex from, TransitEntranceVertex to) { + public StreetTransitEntranceLink link(Vertex from, TransitEntranceVertex to) { return StreetTransitEntranceLink.createStreetTransitEntranceLink(from, to); } - public StreetTransitEntranceLink link(TransitEntranceVertex from, StreetVertex to) { + public StreetTransitEntranceLink link(TransitEntranceVertex from, Vertex to) { return StreetTransitEntranceLink.createStreetTransitEntranceLink(from, to); } - public List biLink(StreetVertex from, TransitEntranceVertex to) { + public List biLink(Vertex from, TransitEntranceVertex to) { return List.of(link(from, to), link(to, from)); } - public StreetTransitStopLink link(StreetVertex from, TransitStopVertex to) { + public StreetTransitStopLink link(Vertex from, TransitStopVertex to) { return StreetTransitStopLink.createStreetTransitStopLink(from, to); } - public StreetTransitStopLink link(TransitStopVertex from, StreetVertex to) { + public StreetTransitStopLink link(TransitStopVertex from, Vertex to) { return StreetTransitStopLink.createStreetTransitStopLink(from, to); } - public List biLink(StreetVertex from, TransitStopVertex to) { + public List biLink(Vertex from, TransitStopVertex to) { return List.of(link(from, to), link(to, from)); } - public StreetStationCentroidLink link(StreetVertex from, StationCentroidVertex to) { + public StreetStationCentroidLink link(Vertex from, StationCentroidVertex to) { return StreetStationCentroidLink.createStreetStationLink(from, to); } - public StreetStationCentroidLink link(StationCentroidVertex from, StreetVertex to) { + public StreetStationCentroidLink link(StationCentroidVertex from, Vertex to) { return StreetStationCentroidLink.createStreetStationLink(from, to); } - public List biLink(StreetVertex from, StationCentroidVertex to) { + public List biLink(Vertex from, StationCentroidVertex to) { return List.of(link(from, to), link(to, from)); } @@ -367,11 +366,11 @@ public TemporaryStreetLocation streetLocation( ); } - public TemporaryFreeEdge link(TemporaryVertex from, StreetVertex to) { + public TemporaryFreeEdge link(TemporaryVertex from, Vertex to) { return TemporaryFreeEdge.createTemporaryFreeEdge(from, to); } - public TemporaryFreeEdge link(StreetVertex from, TemporaryVertex to) { + public TemporaryFreeEdge link(Vertex from, TemporaryVertex to) { return TemporaryFreeEdge.createTemporaryFreeEdge(from, to); } @@ -420,15 +419,15 @@ public VehicleRentalPlaceVertex vehicleRentalStation( return vehicleRentalStation(id, latitude, longitude, TEST_VEHICLE_RENTAL_NETWORK); } - public StreetVehicleRentalLink link(StreetVertex from, VehicleRentalPlaceVertex to) { + public StreetVehicleRentalLink link(Vertex from, VehicleRentalPlaceVertex to) { return StreetVehicleRentalLink.createStreetVehicleRentalLink(from, to); } - public StreetVehicleRentalLink link(VehicleRentalPlaceVertex from, StreetVertex to) { + public StreetVehicleRentalLink link(VehicleRentalPlaceVertex from, Vertex to) { return StreetVehicleRentalLink.createStreetVehicleRentalLink(from, to); } - public List biLink(StreetVertex from, VehicleRentalPlaceVertex to) { + public List biLink(Vertex from, VehicleRentalPlaceVertex to) { return List.of(link(from, to), link(to, from)); } @@ -472,7 +471,7 @@ public VehicleParking vehicleParking( } public VehicleParking.VehicleParkingEntranceCreator vehicleParkingEntrance( - StreetVertex streetVertex, + Vertex streetVertex, String id, boolean carAccessible, boolean walkAccessible @@ -487,18 +486,15 @@ public VehicleParking.VehicleParkingEntranceCreator vehicleParkingEntrance( .walkAccessible(walkAccessible); } - public StreetVehicleParkingLink link(StreetVertex from, VehicleParkingEntranceVertex to) { + public StreetVehicleParkingLink link(Vertex from, VehicleParkingEntranceVertex to) { return StreetVehicleParkingLink.createStreetVehicleParkingLink(from, to); } - public StreetVehicleParkingLink link(VehicleParkingEntranceVertex from, StreetVertex to) { + public StreetVehicleParkingLink link(VehicleParkingEntranceVertex from, Vertex to) { return StreetVehicleParkingLink.createStreetVehicleParkingLink(from, to); } - public List biLink( - StreetVertex from, - VehicleParkingEntranceVertex to - ) { + public List biLink(Vertex from, VehicleParkingEntranceVertex to) { return List.of(link(from, to), link(to, from)); }