Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ public record InsertionCandidate(
int pickupPosition,
int dropoffPosition,
List<GraphPath<State, Edge, Vertex>> routeSegments,
Duration baselineDuration,
Duration durationBetweenOriginAndDestination,
Duration totalDuration
) {
/**
* Calculates the additional duration caused by inserting this passenger.
* Calculates the difference between the total duration when inserting this passenger,
* and the duration when driving directly from the start to the end of the trip.
*/
public Duration additionalDuration() {
return totalDuration.minus(baselineDuration);
return totalDuration.minus(durationBetweenOriginAndDestination);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.opentripplanner.ext.carpooling.routing;

import static org.opentripplanner.ext.carpooling.util.GraphPathUtils.calculateCumulativeDurations;
import static org.opentripplanner.ext.carpooling.util.GraphPathUtils.calculateDuration;

import java.time.Duration;
import java.util.ArrayList;
Expand Down Expand Up @@ -57,24 +58,18 @@ public InsertionEvaluator(
}

/**
* Routes all baseline segments and caches the results.
* Routes all segments of routePoints.
*
* @return Array of routed segments, or null if any segment fails to route
*/
@SuppressWarnings("unchecked")
private GraphPath<State, Edge, Vertex>[] routeBaselineSegments(List<WgsCoordinate> routePoints) {
private GraphPath<State, Edge, Vertex>[] routeSegments(List<WgsCoordinate> routePoints) {
GraphPath<State, Edge, Vertex>[] segments = new GraphPath[routePoints.size() - 1];

for (int i = 0; i < routePoints.size() - 1; i++) {
var fromCoord = routePoints.get(i);
var toCoord = routePoints.get(i + 1);
GenericLocation from = GenericLocation.fromCoordinate(
fromCoord.latitude(),
fromCoord.longitude()
);
GenericLocation to = GenericLocation.fromCoordinate(toCoord.latitude(), toCoord.longitude());

GraphPath<State, Edge, Vertex> segment = routingFunction.route(from, to, linkingContext);
GraphPath<State, Edge, Vertex> segment = routeSegment(fromCoord, toCoord);
if (segment == null) {
LOG.debug("Baseline routing failed for segment {} → {}", i, i + 1);
return null;
Expand All @@ -86,6 +81,23 @@ private GraphPath<State, Edge, Vertex>[] routeBaselineSegments(List<WgsCoordinat
return segments;
}

/**
* Routes from start to stop
Copy link
Contributor

Choose a reason for hiding this comment

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

Start to stop here too. Please avoid this.

*
* @return route from coordinate from to coordinate to, or null if routing function fails
*/
private GraphPath<State, Edge, Vertex> routeSegment(WgsCoordinate from, WgsCoordinate to) {
GenericLocation fromGenericLocation = GenericLocation.fromCoordinate(
from.latitude(),
from.longitude()
);
GenericLocation toGenericLocation = GenericLocation.fromCoordinate(
to.latitude(),
to.longitude()
);
return routingFunction.route(fromGenericLocation, toGenericLocation, linkingContext);
}

/**
* Evaluates pre-filtered insertion positions using A* routing.
* <p>
Expand All @@ -107,17 +119,28 @@ public InsertionCandidate findBestInsertion(
WgsCoordinate passengerPickup,
WgsCoordinate passengerDropoff
) {
GraphPath<State, Edge, Vertex>[] baselineSegments = routeBaselineSegments(trip.routePoints());
GraphPath<State, Edge, Vertex>[] baselineSegments = routeSegments(trip.routePoints());
if (baselineSegments == null) {
LOG.warn("Could not route baseline for trip {}", trip.getId());
return null;
}

Duration[] cumulativeDurations = calculateCumulativeDurations(baselineSegments);

GraphPath<State, Edge, Vertex> pathBetweenStartAndStop = routeSegment(
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, avoid start and stop

trip.stops().getFirst().getCoordinate(),
trip.stops().getLast().getCoordinate()
);

if (pathBetweenStartAndStop == null) {
LOG.warn("Could not create route between start and stop for trip {}", trip.getId());
return null;
}

Duration durationBetweenOriginAndDestination = calculateDuration(pathBetweenStartAndStop);

InsertionCandidate bestCandidate = null;
Duration minAdditionalDuration = INITIAL_ADDITIONAL_DURATION;
Duration baselineDuration = cumulativeDurations[cumulativeDurations.length - 1];

for (InsertionPosition position : viablePositions) {
InsertionCandidate candidate = evaluateInsertion(
Expand All @@ -128,7 +151,7 @@ public InsertionCandidate findBestInsertion(
passengerDropoff,
baselineSegments,
cumulativeDurations,
baselineDuration
durationBetweenOriginAndDestination
);

if (candidate == null) {
Expand Down Expand Up @@ -168,7 +191,7 @@ private InsertionCandidate evaluateInsertion(
WgsCoordinate passengerDropoff,
GraphPath<State, Edge, Vertex>[] baselineSegments,
Duration[] originalCumulativeDurations,
Duration baselineDuration
Duration durationBetweenOriginAndDestination
) {
// Build modified route segments by reusing cached baseline segments
List<GraphPath<State, Edge, Vertex>> modifiedSegments = buildModifiedSegments(
Expand Down Expand Up @@ -217,7 +240,7 @@ private InsertionCandidate evaluateInsertion(
pickupPos,
dropoffPos,
modifiedSegments,
baselineDuration,
durationBetweenOriginAndDestination,
totalDuration
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,20 @@ public static Duration[] calculateCumulativeDurations(GraphPath<State, Edge, Ver
cumulativeDurations[0] = Duration.ZERO;

for (int i = 0; i < segments.length; i++) {
Duration segmentDuration = Duration.between(
segments[i].states.getFirst().getTime(),
segments[i].states.getLast().getTime()
);
Duration segmentDuration = calculateDuration(segments[i]);
cumulativeDurations[i + 1] = cumulativeDurations[i].plus(segmentDuration);
}

return cumulativeDurations;
}

/**
* Calculates duration for a segment
*/
public static Duration calculateDuration(GraphPath<State, Edge, Vertex> segment) {
return Duration.between(
segment.states.getFirst().getTime(),
segment.states.getLast().getTime()
);
}
}
Loading
Loading