|
1 | 1 | package org.opentripplanner.routing.api.request; |
2 | 2 |
|
3 | 3 | import java.time.Duration; |
4 | | -import java.util.Collection; |
5 | 4 | import java.util.List; |
6 | | -import java.util.Objects; |
7 | 5 | import javax.annotation.Nullable; |
8 | | -import org.opentripplanner.framework.time.DurationUtils; |
9 | | -import org.opentripplanner.framework.tostring.ToStringBuilder; |
| 6 | +import org.opentripplanner.framework.geometry.WgsCoordinate; |
10 | 7 | import org.opentripplanner.transit.model.framework.FeedScopedId; |
11 | 8 |
|
12 | 9 | /** |
13 | | - * Defines a via location which the journey must route through. |
| 10 | + * Defines a via location which the journey must route through. At least one stop location or |
| 11 | + * coordinate must exist. When routing, the via-location is visited if at least one of the stops |
| 12 | + * or coordinates is visited, before the journey continues. There is no need to visit any other |
| 13 | + * stop location or coordinate. |
| 14 | + * <p> |
| 15 | + * The stop locations and coordinates are distinct locations. In earlier versions of OTP the |
| 16 | + * coordinates were used as a fallback for when a stop was not found. But in this version, a |
| 17 | + * {@link org.opentripplanner.transit.model.framework.EntityNotFoundException} is thrown if |
| 18 | + * one of the stops does not exist. The search does NOT try to be smart and recover from an |
| 19 | + * entity no found exception. |
14 | 20 | */ |
15 | | -public final class ViaLocation { |
16 | | - |
17 | | - private static final Duration MINIMUM_WAIT_TIME_MAX_LIMIT = Duration.ofHours(24); |
18 | | - |
19 | | - private final String label; |
20 | | - private final boolean allowAsPassThroughPoint; |
21 | | - private final Duration minimumWaitTime; |
22 | | - private final List<ViaConnection> connections; |
23 | | - |
24 | | - @SuppressWarnings("DataFlowIssue") |
25 | | - private ViaLocation( |
26 | | - @Nullable String label, |
27 | | - boolean allowAsPassThroughPoint, |
28 | | - @Nullable Duration minimumWaitTime, |
29 | | - Collection<ViaConnection> connections |
30 | | - ) { |
31 | | - this.label = label; |
32 | | - this.allowAsPassThroughPoint = allowAsPassThroughPoint; |
33 | | - this.minimumWaitTime = |
34 | | - DurationUtils.requireNonNegative( |
35 | | - minimumWaitTime == null ? Duration.ZERO : minimumWaitTime, |
36 | | - MINIMUM_WAIT_TIME_MAX_LIMIT, |
37 | | - "minimumWaitTime" |
38 | | - ); |
39 | | - this.connections = List.copyOf(connections); |
40 | | - |
41 | | - if (allowAsPassThroughPoint && !minimumWaitTime.isZero()) { |
42 | | - throw new IllegalArgumentException( |
43 | | - "'allowAsPassThroughPoint' can not be used with minimumWaitTime for " + label + "." |
44 | | - ); |
45 | | - } |
46 | | - if (allowAsPassThroughPoint && connections.stream().anyMatch(ViaConnection::hasCoordinate)) { |
47 | | - throw new IllegalArgumentException( |
48 | | - "'allowAsPassThroughPoint' can not be used with coordinates for " + label + "." |
49 | | - ); |
50 | | - } |
51 | | - } |
52 | | - |
| 21 | +public interface ViaLocation { |
53 | 22 | /** |
54 | | - * A pass-through-location instructs the router to visit the location either by boarding, |
55 | | - * alighting or on-board a transit. |
56 | | - * @param label The name/label for this location. This is used for debugging and logging and is pass-through information. |
57 | | - * @param locationIds The ID for the stop, station or multimodal station or groupOfStopPlace. |
| 23 | + * Get an optional name/label of for debugging and logging. Not used in business logic. |
58 | 24 | */ |
59 | | - public static ViaLocation passThroughLocation( |
60 | | - @Nullable String label, |
61 | | - List<FeedScopedId> locationIds |
62 | | - ) { |
63 | | - return new ViaLocation(label, true, Duration.ZERO, ViaConnection.connections(locationIds)); |
64 | | - } |
| 25 | + @Nullable |
| 26 | + String label(); |
65 | 27 |
|
66 | 28 | /** |
67 | | - * If set to {@code true} this location can be visited as a pass-through-point. Only |
68 | | - * collections of stops are supported, not coordinates. Also, the minWaitTime must be |
69 | | - * zero(0). |
| 29 | + * The minimum wait time is used to force the trip to stay the given duration at the via location |
| 30 | + * before the trip is continued. This cannot be used together with allow-pass-through, since a |
| 31 | + * pass-through stop is visited on-board. |
70 | 32 | */ |
71 | | - public boolean allowAsPassThroughPoint() { |
72 | | - return allowAsPassThroughPoint; |
| 33 | + default Duration minimumWaitTime() { |
| 34 | + return Duration.ZERO; |
73 | 35 | } |
74 | 36 |
|
75 | 37 | /** |
76 | | - * The minimum wait time is used to force the trip to stay the given duration at the via |
77 | | - * location before the trip is continued. This cannot be used together with allow-pass-through, |
78 | | - * since a pass-through stop is visited on-board. |
| 38 | + * Returns {@code true} if this location is a pass-through-point. Only stops can be visited and |
| 39 | + * the {@code minimumWaitTime} must be zero. |
79 | 40 | */ |
80 | | - public Duration minimumWaitTime() { |
81 | | - return minimumWaitTime; |
82 | | - } |
| 41 | + boolean isPassThroughLocation(); |
83 | 42 |
|
84 | 43 | /** |
85 | | - * Get an optional name/label of for debugging and logging. |
| 44 | + * A list of stop witch can be used as via location together with the {@code coordinates}.A stop |
| 45 | + * location can be a stop, a station, a multimodal station or a group of stations. |
86 | 46 | */ |
87 | | - @Nullable |
88 | | - public String label() { |
89 | | - return label; |
90 | | - } |
| 47 | + List<FeedScopedId> stopLocationIds(); |
91 | 48 |
|
92 | 49 | /** |
93 | | - * Get the one or multiple locations of which only one is required to route through. |
| 50 | + * Get the one or multiple stop locations. This is optional to implement, an empty |
| 51 | + * list is returned if this is not available. |
94 | 52 | */ |
95 | | - public List<ViaConnection> connections() { |
96 | | - return connections; |
97 | | - } |
98 | | - |
99 | | - @Override |
100 | | - public boolean equals(Object o) { |
101 | | - if (this == o) return true; |
102 | | - if (o == null || getClass() != o.getClass()) return false; |
103 | | - ViaLocation that = (ViaLocation) o; |
104 | | - return ( |
105 | | - allowAsPassThroughPoint == that.allowAsPassThroughPoint && |
106 | | - Objects.equals(minimumWaitTime, that.minimumWaitTime) && |
107 | | - Objects.equals(label, that.label) && |
108 | | - Objects.equals(connections, that.connections) |
109 | | - ); |
110 | | - } |
111 | | - |
112 | | - @Override |
113 | | - public int hashCode() { |
114 | | - return Objects.hash(allowAsPassThroughPoint, minimumWaitTime, label, connections); |
115 | | - } |
116 | | - |
117 | | - @Override |
118 | | - public String toString() { |
119 | | - return ToStringBuilder |
120 | | - .of(ViaLocation.class) |
121 | | - .addBoolIfTrue(label, label != null) |
122 | | - .addBoolIfTrue("allowAsPassThroughPoint", allowAsPassThroughPoint) |
123 | | - .addDuration("minimumWaitTime", minimumWaitTime, Duration.ZERO) |
124 | | - .addObj("connections", connections) |
125 | | - .toString(); |
| 53 | + default List<WgsCoordinate> coordinates() { |
| 54 | + return List.of(); |
126 | 55 | } |
127 | 56 | } |
0 commit comments