List<StopTimeEntryImpl> stopTimes)
throws DistanceAlongShapeException {
PointAndIndex[] stopTimePoints = new PointAndIndex[stopTimes.size()];
UTMProjection projection = UTMLibrary.getProjectionForPoint(
shapePoints.getLats()[0], shapePoints.getLons()[0]);
List<XYPoint> projectedShapePoints = _shapePointsLibrary.getProjectedShapePoints(
shapePoints, projection);
double[] shapePointsDistTraveled = shapePoints.getDistTraveled();
List<List<PointAndIndex>> possibleAssignments = computePotentialAssignments(
projection, projectedShapePoints, shapePointsDistTraveled, stopTimes);
pruneUnnecessaryAssignments(possibleAssignments);
assignmentSanityCheck(shapePoints, stopTimes, possibleAssignments);
double maxDistanceTraveled = shapePointsDistTraveled[shapePointsDistTraveled.length - 1];
List<PointAndIndex> bestAssignment = computeBestAssignment(shapePoints,
stopTimes, possibleAssignments, projection, projectedShapePoints);
for (int i = 0; i < stopTimePoints.length; i++) {
PointAndIndex pindex = bestAssignment.get(i);
if (pindex.distanceAlongShape > maxDistanceTraveled) {
int index = projectedShapePoints.size() - 1;
XYPoint point = projectedShapePoints.get(index);
StopEntryImpl stop = stopTimes.get(i).getStop();
XYPoint stopPoint = projection.forward(stop.getStopLocation());
double d = stopPoint.getDistance(point);
pindex = new PointAndIndex(point, index, d, maxDistanceTraveled);
}
stopTimePoints[i] = pindex;
}