MATSIM
LinearInterpolatingTravelTimeGetter.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * LinearInterpolatingTravelTimeGetter.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2011 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.core.trafficmonitoring;
22 
23 class LinearInterpolatingTravelTimeGetter implements TravelTimeGetter {
24 
25  private final TimeSlotComputation travelTimeAggregator ;
26  private final int numSlots;
27  private final double travelTimeBinSize;
28  private final double halfBinSize;
29 
30  public LinearInterpolatingTravelTimeGetter( int numSlots, double travelTimeBinSize, TimeSlotComputation aggregator ) {
31  this.numSlots = numSlots;
32  this.travelTimeBinSize = travelTimeBinSize;
33  this.halfBinSize = ((double) travelTimeBinSize) / 2;
34  this.travelTimeAggregator = aggregator ;
35  }
36 
37  @Override
38  public double getTravelTime(TravelTimeData travelTimeData, double time) {
39  final int timeSlot = travelTimeAggregator.getTimeSlotIndex(time);
40 
41  // if time is in the first half of the first slot we do not interpolate
42  if (time <= halfBinSize) return travelTimeData.getTravelTime(timeSlot, time);
43 
44  // if time is in the second half of the last slot we do not interpolate
45  else if (time >= numSlots * travelTimeBinSize - halfBinSize) return travelTimeData.getTravelTime(timeSlot, time);
46 
47 
48  // time is inbetween, therefore we interpolate
49  int firstSlot;
50  int secondSlot;
51 
52  // if time lies in the first half of the time slot
53  if (timeSlot * travelTimeBinSize + halfBinSize > time) {
54  firstSlot = timeSlot - 1;
55  secondSlot = timeSlot;
56  } else {
57  firstSlot = timeSlot;
58  secondSlot = timeSlot + 1;
59  }
60 
61  // calculate travel times for both time slots
62  double firstTravelTime = travelTimeData.getTravelTime(firstSlot, time);
63  double secondTravelTime = travelTimeData.getTravelTime(secondSlot, time);
64 
65  // interpolate travel time
66  double dx = time - (firstSlot * travelTimeBinSize + halfBinSize);
67 // double dy = (secondTravelTime - firstTravelTime) * (travelTimeBinSize - dx) / travelTimeBinSize;
68  /*
69  * The line above was a bug: we need to divide the change in travel time (i.e. second minus first travel time) by the change in time (i.e. the time bin size)
70  * to get the gradient of the line between the midpoint of the first interval and the midpoint of the second interval.
71  * Then we have to multiply it by dx to get dy. The last part was wrong (it was multiplied by time bin size minus dx).
72  * The test (TravelTimeCalculatorTest) only tests one value in each time bin -- namely the starting time of each time bin, which is unfortunately
73  * always the midpoint on the interpolated lines, i.e. the only time per time bin where the bug has no influence... theresa, sep'17
74  */
75  double dy = (secondTravelTime - firstTravelTime) * dx / travelTimeBinSize;
76 
77  return firstTravelTime + dy;
78  }
79 
80 }