Skip to content

Commit 9aed4b0

Browse files
committed
Refactor AccessEgressRouter to use template method pattern
1 parent c397b4a commit 9aed4b0

2 files changed

Lines changed: 126 additions & 59 deletions

File tree

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package org.opentripplanner.routing.algorithm.raptoradapter.router.street;
2+
3+
import java.time.Duration;
4+
import java.util.Collection;
5+
import java.util.List;
6+
import java.util.Set;
7+
import java.util.stream.Collectors;
8+
import org.opentripplanner.framework.application.OTPRequestTimeoutException;
9+
import org.opentripplanner.graph_builder.module.nearbystops.StopResolver;
10+
import org.opentripplanner.routing.api.request.RouteRequest;
11+
import org.opentripplanner.routing.api.request.request.StreetRequest;
12+
import org.opentripplanner.routing.graphfinder.NearbyStop;
13+
import org.opentripplanner.routing.graphfinder.NearbyStopFactory;
14+
import org.opentripplanner.routing.linking.LinkingContext;
15+
import org.opentripplanner.street.model.edge.ExtensionRequestContext;
16+
import org.opentripplanner.street.model.vertex.Vertex;
17+
import org.opentripplanner.utils.collection.ListUtils;
18+
import org.slf4j.Logger;
19+
import org.slf4j.LoggerFactory;
20+
21+
/**
22+
* Abstract class for a street search to find paths to all the access/egress stop within range.
23+
* Follows template method pattern.
24+
*/
25+
public abstract class AccessEgressRouter {
26+
27+
private static final Logger LOG = LoggerFactory.getLogger(AccessEgressRouter.class);
28+
private final NearbyStopFactory nearbyStopFactory;
29+
30+
public AccessEgressRouter(StopResolver stopResolver) {
31+
this.nearbyStopFactory = new NearbyStopFactory(stopResolver::getRegularStop);
32+
}
33+
34+
/**
35+
* Find accesses or egresses.
36+
*/
37+
public Collection<NearbyStop> findAccessEgresses(
38+
RouteRequest request,
39+
StreetRequest streetRequest,
40+
Collection<ExtensionRequestContext> extensionRequestContexts,
41+
AccessEgressType accessOrEgress,
42+
Duration durationLimit,
43+
int maxStopCount,
44+
LinkingContext linkingContext
45+
) {
46+
OTPRequestTimeoutException.checkForTimeout();
47+
48+
// Note: We calculate access/egresses in two parts. First we fetch the stops with zero distance.
49+
// Then we do street search. This is because some stations might use the centroid for street
50+
// routing, but should still give zero distance access/egresses to its child-stops.
51+
var zeroDistanceAccessEgress = findAccessEgressWithZeroDistance(
52+
request,
53+
streetRequest,
54+
accessOrEgress,
55+
linkingContext
56+
);
57+
58+
// When looking for street accesses/egresses we ignore the already found direct accesses/egresses
59+
var ignoreVertices = zeroDistanceAccessEgress
60+
.stream()
61+
.map(nearbyStop -> nearbyStop.lastStates.getLast().getVertex())
62+
.collect(Collectors.toSet());
63+
64+
var streetAccessEgress = findStreetAccessEgresses(
65+
request,
66+
streetRequest,
67+
extensionRequestContexts,
68+
accessOrEgress,
69+
durationLimit,
70+
maxStopCount,
71+
linkingContext,
72+
ignoreVertices
73+
);
74+
75+
var results = ListUtils.combine(zeroDistanceAccessEgress, streetAccessEgress);
76+
LOG.debug("Found {} {} stops", results.size(), accessOrEgress);
77+
return results;
78+
}
79+
80+
/**
81+
* Find accesses or egresses using street routing.
82+
*/
83+
abstract Collection<NearbyStop> findStreetAccessEgresses(
84+
RouteRequest request,
85+
StreetRequest streetRequest,
86+
Collection<ExtensionRequestContext> extensionRequestContexts,
87+
AccessEgressType accessOrEgress,
88+
Duration durationLimit,
89+
int maxStopCount,
90+
LinkingContext linkingContext,
91+
Set<Vertex> ignoreVertices
92+
);
93+
94+
/**
95+
* Return a list of direct accesses/egresses that do not require any street search. This will
96+
* return an empty list if the source/destination is not a stopId.
97+
*/
98+
private List<NearbyStop> findAccessEgressWithZeroDistance(
99+
RouteRequest routeRequest,
100+
StreetRequest streetRequest,
101+
AccessEgressType accessOrEgress,
102+
LinkingContext linkingContext
103+
) {
104+
var transitStopVertices = accessOrEgress.isAccess()
105+
? linkingContext.fromStopVertices()
106+
: linkingContext.toStopVertices();
107+
108+
return nearbyStopFactory.nearbyStopsForTransitStopVerticesFiltered(
109+
transitStopVertices,
110+
accessOrEgress.isEgress(),
111+
routeRequest,
112+
streetRequest
113+
);
114+
}
115+
}

application/src/main/java/org/opentripplanner/routing/algorithm/raptoradapter/router/street/DefaultAccessEgressRouter.java

Lines changed: 11 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2,98 +2,50 @@
22

33
import java.time.Duration;
44
import java.util.Collection;
5-
import java.util.List;
6-
import java.util.stream.Collectors;
7-
import org.opentripplanner.framework.application.OTPRequestTimeoutException;
5+
import java.util.Set;
86
import org.opentripplanner.graph_builder.module.nearbystops.StopResolver;
97
import org.opentripplanner.graph_builder.module.nearbystops.StreetNearbyStopFinder;
108
import org.opentripplanner.routing.api.request.RouteRequest;
119
import org.opentripplanner.routing.api.request.request.StreetRequest;
1210
import org.opentripplanner.routing.graphfinder.NearbyStop;
13-
import org.opentripplanner.routing.graphfinder.NearbyStopFactory;
1411
import org.opentripplanner.routing.linking.LinkingContext;
1512
import org.opentripplanner.street.model.edge.ExtensionRequestContext;
16-
import org.opentripplanner.utils.collection.ListUtils;
17-
import org.slf4j.Logger;
18-
import org.slf4j.LoggerFactory;
13+
import org.opentripplanner.street.model.vertex.Vertex;
1914

2015
/**
21-
* This uses a street search to find paths to all the access/egress stop within range
16+
* This uses a street search to find paths to all the access/egress stop within range. Doesn't
17+
* support routing through via locations.
2218
*/
23-
public class DefaultAccessEgressRouter {
19+
public class DefaultAccessEgressRouter extends AccessEgressRouter {
2420

25-
private static final Logger LOG = LoggerFactory.getLogger(DefaultAccessEgressRouter.class);
2621
private final StopResolver stopResolver;
27-
private final NearbyStopFactory nearbyStopFactory;
2822

2923
public DefaultAccessEgressRouter(StopResolver stopResolver) {
24+
super(stopResolver);
3025
this.stopResolver = stopResolver;
31-
this.nearbyStopFactory = new NearbyStopFactory(stopResolver::getRegularStop);
3226
}
3327

3428
/**
3529
* Find accesses or egresses.
3630
*/
37-
public Collection<NearbyStop> findAccessEgresses(
31+
@Override
32+
Collection<NearbyStop> findStreetAccessEgresses(
3833
RouteRequest request,
3934
StreetRequest streetRequest,
4035
Collection<ExtensionRequestContext> extensionRequestContexts,
4136
AccessEgressType accessOrEgress,
4237
Duration durationLimit,
4338
int maxStopCount,
44-
LinkingContext linkingContext
39+
LinkingContext linkingContext,
40+
Set<Vertex> ignoreVertices
4541
) {
46-
OTPRequestTimeoutException.checkForTimeout();
47-
48-
// Note: We calculate access/egresses in two parts. First we fetch the stops with zero distance.
49-
// Then we do street search. This is because some stations might use the centroid for street
50-
// routing, but should still give zero distance access/egresses to its child-stops.
51-
var zeroDistanceAccessEgress = findAccessEgressWithZeroDistance(
52-
request,
53-
streetRequest,
54-
accessOrEgress,
55-
linkingContext
56-
);
57-
58-
// When looking for street accesses/egresses we ignore the already found direct accesses/egresses
59-
var ignoreVertices = zeroDistanceAccessEgress
60-
.stream()
61-
.map(nearbyStop -> nearbyStop.lastStates.getLast().getVertex())
62-
.collect(Collectors.toSet());
63-
6442
var originVertices = accessOrEgress.isAccess()
6543
? linkingContext.findVertices(request.from())
6644
: linkingContext.findVertices(request.to());
67-
var streetAccessEgress = StreetNearbyStopFinder.of(stopResolver, durationLimit, maxStopCount)
45+
return StreetNearbyStopFinder.of(stopResolver, durationLimit, maxStopCount)
6846
.withIgnoreVertices(ignoreVertices)
6947
.withExtensionRequestContexts(extensionRequestContexts)
7048
.build()
7149
.findNearbyStops(originVertices, request, streetRequest, accessOrEgress.isEgress());
72-
73-
var results = ListUtils.combine(zeroDistanceAccessEgress, streetAccessEgress);
74-
LOG.debug("Found {} {} stops", results.size(), accessOrEgress);
75-
return results;
76-
}
77-
78-
/**
79-
* Return a list of direct accesses/egresses that do not require any street search. This will
80-
* return an empty list if the source/destination is not a stopId.
81-
*/
82-
private List<NearbyStop> findAccessEgressWithZeroDistance(
83-
RouteRequest routeRequest,
84-
StreetRequest streetRequest,
85-
AccessEgressType accessOrEgress,
86-
LinkingContext linkingContext
87-
) {
88-
var transitStopVertices = accessOrEgress.isAccess()
89-
? linkingContext.fromStopVertices()
90-
: linkingContext.toStopVertices();
91-
92-
return nearbyStopFactory.nearbyStopsForTransitStopVerticesFiltered(
93-
transitStopVertices,
94-
accessOrEgress.isEgress(),
95-
routeRequest,
96-
streetRequest
97-
);
9850
}
9951
}

0 commit comments

Comments
 (0)