-
Notifications
You must be signed in to change notification settings - Fork 2
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
Send bus notifications if first leg is bus #264
Changes from 4 commits
89d5074
4df263b
f135775
188f531
2b3e003
820584f
eeea569
c0d0672
b6a8536
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -57,20 +57,20 @@ public static String getInstruction( | |
) { | ||
if (hasRequiredWalkLeg(travelerPosition)) { | ||
if (hasRequiredTripStatus(tripStatus)) { | ||
TripInstruction tripInstruction = alignTravelerToTrip(travelerPosition, isStartOfTrip, tripStatus); | ||
TripInstruction tripInstruction = alignTravelerToTrip(travelerPosition, isStartOfTrip); | ||
if (tripInstruction != null) { | ||
return tripInstruction.build(); | ||
} | ||
} | ||
|
||
if (tripStatus.equals(TripStatus.DEVIATED)) { | ||
TripInstruction tripInstruction = getBackOnTrack(travelerPosition, isStartOfTrip, tripStatus); | ||
TripInstruction tripInstruction = getBackOnTrack(travelerPosition, isStartOfTrip); | ||
if (tripInstruction != null) { | ||
return tripInstruction.build(); | ||
} | ||
} | ||
} else if (hasRequiredTransitLeg(travelerPosition) && hasRequiredTripStatus(tripStatus)) { | ||
TripInstruction tripInstruction = alignTravelerToTransitTrip(travelerPosition); | ||
TripInstruction tripInstruction = alignTravelerToTransitTrip(travelerPosition, isStartOfTrip); | ||
if (tripInstruction != null) { | ||
return tripInstruction.build(); | ||
} | ||
|
@@ -111,10 +111,9 @@ private static boolean hasRequiredTripStatus(TripStatus tripStatus) { | |
@Nullable | ||
private static TripInstruction getBackOnTrack( | ||
TravelerPosition travelerPosition, | ||
boolean isStartOfTrip, | ||
TripStatus tripStatus | ||
boolean isStartOfTrip | ||
) { | ||
TripInstruction instruction = alignTravelerToTrip(travelerPosition, isStartOfTrip, tripStatus); | ||
TripInstruction instruction = alignTravelerToTrip(travelerPosition, isStartOfTrip); | ||
if (instruction != null && instruction.hasInstruction()) { | ||
return instruction; | ||
} | ||
|
@@ -130,16 +129,12 @@ private static TripInstruction getBackOnTrack( | |
@Nullable | ||
public static TripInstruction alignTravelerToTrip( | ||
TravelerPosition travelerPosition, | ||
boolean isStartOfTrip, | ||
TripStatus tripStatus | ||
boolean isStartOfTrip | ||
) { | ||
Locale locale = travelerPosition.locale; | ||
|
||
if (isApproachingEndOfLeg(travelerPosition)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is at the start of a trip where the first leg is transit, there is no approaching the end of the leg. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @binh-dam-ibigroup If possible can you provide a trip which starts with a transit leg? I'm going to edit an existing trip (walk-to-bus-transition.json) to test with, but would prefer a real-world exampl There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @binh-dam-ibigroup this has grown a bit from my initial take on it! I think this covers the what is needed. |
||
if (isBusLeg(travelerPosition.nextLeg) && isWithinOperationalNotifyWindow(travelerPosition)) { | ||
BusOperatorActions | ||
.getDefault() | ||
.handleSendNotificationAction(tripStatus, travelerPosition); | ||
if (sendBusNotification(travelerPosition, isStartOfTrip)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might have misinterpreted There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @binh-dam-ibigroup I have updated, I hope it meets expectations. |
||
// Regardless of whether the notification is sent or qualifies, provide a 'wait for bus' instruction. | ||
return new WaitForTransitInstruction(travelerPosition.nextLeg, travelerPosition.currentTime, locale); | ||
} | ||
|
@@ -157,15 +152,57 @@ public static TripInstruction alignTravelerToTrip( | |
return null; | ||
} | ||
|
||
/** | ||
* Send bus notification if the first leg is a bus leg or approaching a bus leg and within the notify window. | ||
*/ | ||
public static boolean sendBusNotification( | ||
TravelerPosition travelerPosition, | ||
boolean isStartOfTrip | ||
) { | ||
Leg busLeg = (isStartOfTrip) ? travelerPosition.expectedLeg : travelerPosition.nextLeg; | ||
if (shouldNotifyBusOperator(travelerPosition, busLeg)) { | ||
BusOperatorActions | ||
.getDefault() | ||
.handleSendNotificationAction(travelerPosition, busLeg); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* Given the traveler's position and leg type, check if bus notification should be sent. | ||
*/ | ||
public static boolean shouldNotifyBusOperator(TravelerPosition travelerPosition, Leg busLeg) { | ||
return isBusLeg(busLeg) && isWithinOperationalNotifyWindow(travelerPosition.currentTime, busLeg); | ||
} | ||
|
||
/** | ||
* A trip which starts with a transit leg. | ||
*/ | ||
private static boolean tripStartsWithTransitLeg(TravelerPosition travelerPosition, boolean isStartOfTrip) { | ||
return isStartOfTrip && travelerPosition.expectedLeg.transitLeg; | ||
} | ||
|
||
/** | ||
* Align the traveler's position to the nearest transit stop or destination. | ||
*/ | ||
@Nullable | ||
public static TripInstruction alignTravelerToTransitTrip(TravelerPosition travelerPosition) { | ||
public static TripInstruction alignTravelerToTransitTrip( | ||
TravelerPosition travelerPosition, | ||
boolean isStartOfTrip | ||
) { | ||
Locale locale = travelerPosition.locale; | ||
Leg expectedLeg = travelerPosition.expectedLeg; | ||
String finalStop = expectedLeg.to.name; | ||
|
||
if ( | ||
tripStartsWithTransitLeg(travelerPosition, isStartOfTrip) && | ||
sendBusNotification(travelerPosition, isStartOfTrip) | ||
) { | ||
// Regardless of whether the notification is sent or qualifies, provide a 'wait for bus' instruction. | ||
return new WaitForTransitInstruction(expectedLeg, travelerPosition.currentTime, locale); | ||
} | ||
|
||
if (isApproachingEndOfLeg(travelerPosition)) { | ||
return new GetOffHereTransitInstruction(finalStop, locale); | ||
} | ||
|
@@ -222,11 +259,11 @@ public static boolean isAtEndOfLeg(TravelerPosition travelerPosition) { | |
* Make sure the traveler is on schedule or ahead of schedule (but not too far) to be within an operational window | ||
* for the bus service. | ||
*/ | ||
public static boolean isWithinOperationalNotifyWindow(TravelerPosition travelerPosition) { | ||
var busDepartureTime = getBusDepartureTime(travelerPosition.nextLeg); | ||
public static boolean isWithinOperationalNotifyWindow(Instant currentTime, Leg busLeg) { | ||
var busDepartureTime = getBusDepartureTime(busLeg); | ||
return | ||
(travelerPosition.currentTime.equals(busDepartureTime) || travelerPosition.currentTime.isBefore(busDepartureTime)) && | ||
ACCEPTABLE_AHEAD_OF_SCHEDULE_IN_MINUTES >= getMinutesAheadOfDeparture(travelerPosition.currentTime, busDepartureTime); | ||
(currentTime.equals(busDepartureTime) || currentTime.isBefore(busDepartureTime)) && | ||
ACCEPTABLE_AHEAD_OF_SCHEDULE_IN_MINUTES >= getMinutesAheadOfDeparture(currentTime, busDepartureTime); | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
package org.opentripplanner.middleware.triptracker.interactions.busnotifiers; | ||
|
||
import org.opentripplanner.middleware.otp.response.Leg; | ||
import org.opentripplanner.middleware.triptracker.TravelerPosition; | ||
import org.opentripplanner.middleware.triptracker.TripStatus; | ||
|
||
public interface BusOperatorInteraction { | ||
|
||
void sendNotification(TripStatus tripStatus, TravelerPosition travelerPosition); | ||
void sendNotification(TravelerPosition travelerPosition, Leg busLeg); | ||
|
||
void cancelNotification(TravelerPosition travelerPosition); | ||
void cancelNotification(TravelerPosition travelerPosition, Leg busLeg); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bonus points question: I didn't see an equivalent to "Head to " on an itinerary where the first leg is bus and tracking is started at a location away from the bus stop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@binh-dam-ibigroup Update here: eeea569
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@binh-dam-ibigroup I will hold off merging until you have "approved" this addition.