Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for routing to Station centroid instead of child stops #6047

Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions doc/user/BuildConfiguration.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Sections follow that describe particular settings in more depth.
|    [sharedFilePattern](#nd_sharedFilePattern) | `regexp` | Pattern for matching shared NeTEx files in a NeTEx bundle. | *Optional* | `"shared-data\.xml"` | 2.0 |
|    [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 |
|    [routeToCentroidStationIds](#nd_routeToCentroidStationIds) | `string[]` | List stations that should route to centroid. | *Optional* | | 2.6 |
| [osm](#osm) | `object[]` | Configure properties for a given OpenStreetMap feed. | *Optional* | | 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 |
Expand Down Expand Up @@ -113,6 +114,7 @@ Sections follow that describe particular settings in more depth.
|       [sharedGroupFilePattern](#tf_1_sharedGroupFilePattern) | `regexp` | Pattern for matching shared group NeTEx files in a NeTEx bundle. | *Optional* | `"(\w{3})-.*-shared\.xml"` | 2.0 |
|       source | `uri` | The unique URI pointing to the data file. | *Required* | | 2.2 |
|       [ferryIdsNotAllowedForBicycle](#tf_1_ferryIdsNotAllowedForBicycle) | `string[]` | List ferries which do not allow bikes. | *Optional* | | 2.0 |
|       [routeToCentroidStationIds](#tf_1_routeToCentroidStationIds) | `string[]` | List stations that should route to centroid. | *Optional* | | 2.6 |

<!-- PARAMETERS-TABLE END -->

Expand Down Expand Up @@ -922,6 +924,26 @@ For this reason we allow bicycles on ferries by default and allow to override th
case where this is not the case.


<h3 id="nd_routeToCentroidStationIds">routeToCentroidStationIds</h3>

**Since version:** `2.6` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional`
**Path:** /netexDefaults

List stations that should route to centroid.

This field contains a list of station ids for which the centroid will be used instead
of the stop coordinates.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
of the stop coordinates.
of the stop coordinates when routing to the Station.


When doing street routing from/to a station the default behaviour is to route to any of
the stations' child stops. This can cause strange results for stations that have stops
spread over a large area.

For some stations you might instead wish to use the centroid of the station as the
source/destination for street routing. In this case the centroid will be used both for
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
source/destination for street routing. In this case the centroid will be used both for
source/destination for street routing. In this case the centroid will be used both for

direct street search and for access/egress street search where the station is used as
the start/end of the access/egress.


<h3 id="osm">osm</h3>

**Since version:** `2.2` ∙ **Type:** `object[]` ∙ **Cardinality:** `Optional`
Expand Down Expand Up @@ -1067,6 +1089,26 @@ For this reason we allow bicycles on ferries by default and allow to override th
case where this is not the case.


<h3 id="tf_1_routeToCentroidStationIds">routeToCentroidStationIds</h3>

**Since version:** `2.6` ∙ **Type:** `string[]` ∙ **Cardinality:** `Optional`
**Path:** /transitFeeds/[1]

List stations that should route to centroid.

This field contains a list of station ids for which the centroid will be used instead
of the stop coordinates.

When doing street routing from/to a station the default behaviour is to route to any of
the stations' child stops. This can cause strange results for stations that have stops
spread over a large area.

For some stations you might instead wish to use the centroid of the station as the
source/destination for street routing. In this case the centroid will be used both for
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
source/destination for street routing. In this case the centroid will be used both for
source/destination for street routing. In this case the centroid will be used both for

direct street search and for access/egress street search where the station is used as
the start/end of the access/egress.



<!-- PARAMETERS-DETAILS END -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -194,6 +195,7 @@ public boolean isOff() {
/**
* If feature is turned on, then return supplied object if not return {@code null}.
*/
@Nullable
public <T> T isOnElseNull(Supplier<T> supplier) {
return isOn() ? supplier.get() : null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.opentripplanner.transit.model.site.PathwayMode;
import org.opentripplanner.transit.model.site.PathwayNode;
import org.opentripplanner.transit.model.site.RegularStop;
import org.opentripplanner.transit.model.site.Station;
import org.opentripplanner.transit.model.site.StationElement;
import org.opentripplanner.transit.model.site.StopLocation;
import org.opentripplanner.transit.service.TransitModel;
Expand Down Expand Up @@ -86,6 +87,7 @@ private void applyToGraph(TransitModel transitModel) {

addStopsToGraphAndGenerateStopVertexes(transitModel);
addEntrancesToGraph();
addStationCentroidsToGraph();
addPathwayNodesToGraph();
addBoardingAreasToGraph();

Expand Down Expand Up @@ -142,6 +144,14 @@ private void addEntrancesToGraph() {
}
}

private void addStationCentroidsToGraph() {
for (Station station : otpTransitService.stopModel().listStations()) {
if (station.shouldRouteToCentroid()) {
vertexFactory.transitStationCentroid(station);
}
}
}

private void addPathwayNodesToGraph() {
for (PathwayNode node : otpTransitService.getAllPathwayNodes()) {
TransitPathwayNodeVertex nodeVertex = vertexFactory.transitPathwayNode(node);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ public void buildGraph() {
LOG.debug("Linking stop '{}' {}", stop, ts0);

for (RouteRequest transferProfile : transferRequests) {
for (NearbyStop sd : findNearbyStops(
nearbyStopFinder,
for (NearbyStop sd : nearbyStopFinder.findNearbyStops(
ts0,
transferProfile,
transferProfile.journey().transfer(),
Expand All @@ -126,8 +125,7 @@ public void buildGraph() {
if (OTPFeature.FlexRouting.isOn()) {
// This code is for finding transfers from AreaStops to Stops, transfers
// from Stops to AreaStops and between Stops are already covered above.
for (NearbyStop sd : findNearbyStops(
nearbyStopFinder,
for (NearbyStop sd : nearbyStopFinder.findNearbyStops(
ts0,
transferProfile,
transferProfile.journey().transfer(),
Expand Down Expand Up @@ -203,15 +201,5 @@ private NearbyStopFinder createNearbyStopFinder() {
}
}

private static Iterable<NearbyStop> findNearbyStops(
NearbyStopFinder nearbyStopFinder,
Vertex vertex,
RouteRequest request,
StreetRequest streetRequest,
boolean reverseDirection
) {
return nearbyStopFinder.findNearbyStops(vertex, request, streetRequest, reverseDirection);
}

private record TransferKey(StopLocation source, StopLocation target, List<Edge> edges) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
import org.opentripplanner.routing.vehicle_parking.VehicleParkingHelper;
import org.opentripplanner.street.model.edge.Edge;
import org.opentripplanner.street.model.edge.StreetTransitEntranceLink;
import org.opentripplanner.street.model.edge.StreetTransitStationCentroidLink;
import org.opentripplanner.street.model.edge.StreetTransitStopLink;
import org.opentripplanner.street.model.edge.StreetVehicleParkingLink;
import org.opentripplanner.street.model.edge.VehicleParkingEdge;
import org.opentripplanner.street.model.vertex.StreetVertex;
import org.opentripplanner.street.model.vertex.TransitEntranceVertex;
import org.opentripplanner.street.model.vertex.TransitStationCentroidVertex;
import org.opentripplanner.street.model.vertex.TransitStopVertex;
import org.opentripplanner.street.model.vertex.VehicleParkingEntranceVertex;
import org.opentripplanner.street.search.TraverseMode;
Expand Down Expand Up @@ -70,6 +72,7 @@ public void buildGraph() {
if (graph.hasStreets) {
linkTransitStops(graph, transitModel);
linkTransitEntrances(graph);
linkTransitStationCentroids(graph);
linkVehicleParks(graph, issueStore);
}

Expand Down Expand Up @@ -257,6 +260,32 @@ private void linkTransitEntrances(Graph graph) {
}
}

private void linkTransitStationCentroids(Graph graph) {
LOG.info("Linking TransitStationCentroidVertices to graph...");
for (TransitStationCentroidVertex tVertex : graph.getVerticesOfType(
TransitStationCentroidVertex.class
)) {
graph
.getLinker()
.linkVertexPermanently(
tVertex,
new TraverseModeSet(TraverseMode.WALK),
LinkingDirection.BOTH_WAYS,
(vertex, streetVertex) ->
List.of(
StreetTransitStationCentroidLink.createStreetTransitStationLink(
(TransitStationCentroidVertex) vertex,
streetVertex
),
StreetTransitStationCentroidLink.createStreetTransitStationLink(
streetVertex,
(TransitStationCentroidVertex) vertex
)
)
);
}
}

private void linkVehicleParks(Graph graph, DataImportIssueStore issueStore) {
LOG.info("Linking vehicle parks to graph...");
List<VehicleParking> vehicleParkingToRemove = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.opentripplanner.graph_builder.module.nearbystops;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.opentripplanner.routing.api.request.RouteRequest;
import org.opentripplanner.routing.api.request.request.StreetRequest;
import org.opentripplanner.routing.graphfinder.NearbyStop;
import org.opentripplanner.street.model.vertex.TransitStopVertex;
import org.opentripplanner.street.model.vertex.Vertex;
import org.opentripplanner.street.search.request.StreetSearchRequest;
import org.opentripplanner.street.search.request.StreetSearchRequestMapper;
import org.opentripplanner.street.search.state.State;

public class DirectlyConnectedStopFinder {

/**
* Given a list of vertices, find the ones that corresponds to stops and return them as NearbyStops
*/
public static List<NearbyStop> findDirectlyConnectedStops(
Set<Vertex> originVertices,
boolean reverseDirection,
RouteRequest request,
StreetRequest streetRequest
) {
List<NearbyStop> stopsFound = new ArrayList<>();

StreetSearchRequest streetSearchRequest = StreetSearchRequestMapper
.mapToTransferRequest(request)
.withArriveBy(reverseDirection)
.withMode(streetRequest.mode())
.build();

for (Vertex vertex : originVertices) {
if (vertex instanceof TransitStopVertex tsv) {
stopsFound.add(
new NearbyStop(
tsv.getStop(),
0,
Collections.emptyList(),
new State(vertex, streetSearchRequest)
)
);
}
}

return stopsFound;
}
}
Loading
Loading