Example #1
0
def populate_trip_stop_information(trip_id, stops):
    """
  Given a GTFS trip ID, populates information about each stop in that trip
  into the database.
  Returns total length of the trip in meters.
  """
    cumulative_dist = 0.0
    prev_stop_loc = None

    for i, gstop in enumerate(stops):
        stop_loc = gstop['stop_lat'], gstop['stop_lon']
        stop_arrive = gstop['arrival_time_seconds']
        stop_depart = gstop['departure_time_seconds']
        stop_seq = gstop['stop_sequence']

        if prev_stop_loc is None:
            prev_stop_dist = None
            sched_travel_time = None
        else:
            prev_stop_dist = gis.distance_meters(prev_stop_loc, stop_loc)
            cumulative_dist += prev_stop_dist
            if prev_stop_depart is None:
                sched_travel_time = stop_arrive - prev_stop_arrive
            else:
                sched_travel_time = stop_arrive - prev_stop_depart

        db.export_trip_stop_information(trip_id, stop_seq, i, prev_stop_dist,
                                        cumulative_dist, sched_travel_time)

        prev_stop_loc = stop_loc
        prev_stop_arrive = stop_arrive
        prev_stop_depart = stop_depart

    return cumulative_dist
Example #2
0
def populate_trip_stop_information(trip_id,stops):
  """
  Given a GTFS trip ID, populates information about each stop in that trip
  into the database.
  Returns total length of the trip in meters.
  """
  cumulative_dist = 0.0
  prev_stop_loc = None  
  
  for i,gstop in enumerate(stops):
    stop_loc=gstop['stop_lat'],gstop['stop_lon']
    stop_arrive=gstop['arrival_time_seconds']
    stop_depart = gstop['departure_time_seconds']
    stop_seq = gstop['stop_sequence']

    if prev_stop_loc is None:
      prev_stop_dist = None
      sched_travel_time = None
    else:
      prev_stop_dist = gis.distance_meters(prev_stop_loc,stop_loc);
      cumulative_dist += prev_stop_dist
      if prev_stop_depart is None:
        sched_travel_time = stop_arrive - prev_stop_arrive
      else:
        sched_travel_time = stop_arrive - prev_stop_depart

    db.export_trip_stop_information(trip_id,stop_seq, i, 
                                    prev_stop_dist,cumulative_dist,
                                    sched_travel_time);

    prev_stop_loc = stop_loc
    prev_stop_arrive = stop_arrive
    prev_stop_depart = stop_depart

  return cumulative_dist
 def findLaunchTime(self,tol=50):
   """
   Finds the time that the bus moved tol meters from start point.
   If there is no shape data, then the start point is the first
   point in the dataset. Otherwise, the start point is defined by
   the first point in the shape. In this case, we first find the 
   time that the bus arrived at the start point, then search for
   the launch from there.
   """
   if self.segment.shape:
     arrived = False
     begin_pt = self.segment.shape.points[0];
   else:
     arrived = True
     begin_pt = self.interpolation[0][:2];
   for i,interp_pt in enumerate(self.interpolation):
     dist = gis.distance_meters(begin_pt,interp_pt[:2]);
     #print i,"dist:",dist
     if not arrived and dist <= tol:
       print "arrived at",interp_pt[2],"(%d steps)..."%(i,),
       arrived = True
     elif arrived and dist > tol:
       print "launched at",interp_pt[2]
       return interp_pt[2];
   return None
def calcDistance(lation1,lation2):                      
    """
    Caclulate distance between two lat lons in meters
    """
    return gis.distance_meters( map(float,lation1), 
                                map(float,lation2) )
  def measureDistanceFromGTFSTrip(self,trip_id,
                                  offset_seconds=0,
                                  penalize_gps_oob=True,
                                  penalize_gtfs_oob=True):
    """
    Given a GTFS Trip ID and an offset in seconds, returns
    
    (distance, oob_frac)

    where dist measures the distance of this trip from that one 
    as described below, and oob_frac is the fraction of scheduled
    stops (out of total number of stops) whose times are outside 
    the time window of this GPS segment.

    The penalize_xxx_oob parameters are used to indicate whether
    to penalize for special out-of-bounds cases. See below for details.
    
    Let n = # of timepoints for the GTFS trip
    For each timepoint T_i in the GTFS trip, let
      G(T_i) = location of GTFS scheduled stop at T_i
      B(T_i) = location of GPS signal at T_i+offset_seconds
    
    Then this function will return as the distance
      Sqrt( 1/n * Sum over i=1:n of Distance[G(T_i),B(T_i)]**2 )
    
    Note that the normalization factor of 1/n is necessary
    to prevent favoring of shorter routes.

    Typically the offset will be set to 86400 (24 hours) in cases
    where the GTFS trip is a "late night" (after midnight) schedule
    which means its times will be greater than 86400 (in seconds).


    The 'penalize_xxx_oob' parameters are used to determine what special
    treatment will be given to cases where bounding time window of
    the GPS trip is not well-matched to that of the GTFS trip. 
    (That is, whether or not to penalize periods of time where the gtfs 
    or gps data is "out of bounds" of the other).

    This breaks down into two basic cases:

    1. Periods of time where GPS data exists but the GTFS schedule does not.
       That is, the GPS data is out of bounds of the GTFS time window.
    
    2. Periods of time where the GTFS trip has schedule data but the GPS
       trip does not. That is, the GPS trip starts after the GTFS schedule,
       and/or it ends before the GTFS schedule, and so the GTFS data is
       out of bounds of the GPS time window.

    If penalize_gtfs_oob is False, then for periods where the GTFS trip 
    exists but the GPS trip does not, the GTFS is truncated to match the
    GPS time window. Otherwise, it is not truncated.

    If penalize_gps_oob is False, then for periods where the GPS trip exists
    but the GTFS trip does not, the GPS trip is truncated to match the GTFS
    time window. Otherwise, it is not truncated.

    The costs for non-truncated out-of-bound segments are handled as follows:

    - For timepoints T_i where GTFS exists and GPS does not, the distance
      between them is measured as though the GPS was found at the location
      of its first (or last) point. That is, if there is a GTFS timepoint
      before the beginning of the GPS trip, we use the first point in the
      GPS trip; if there is a GTFS timepoint after the end of the GPS trip,
      we use the last point in the GPS trip.

    - For cases where GPS exists and GTFS does not, we fabricate evenly
      spaced time points T_k for k = 1 to n, where 
    
      n = (GTFS_stops / GTFS_time) * GPS_OOB_time
      GTFS_time = time span of GTFS trip
      GTFS_stops = number of stops in GTFS trip
      GPS_OOB_time = amount of time GPS trip exists before/after GTFS trip

      For each of this times T_k the GTFS location is calculated as for
      the GPS trip in the case above. 

    This is used, for example, in a case where the GPS signal was 
    turned on several minutes late into the trip, the trip can match 
    very well with the GTFS schedule during that time the signal
    is alive, but during the beginning of the GTFS schedule
    there is no data. 

    In other cases, the GPS signal has been turned on several minutes
    early, before it has even arrived at the beginning of its route.

    You may wish to penalize this kind of behavior, or ignore it.

    WARNING: if penalize_gtfs_oob=False and penalize_gps_oob=False, 
    then the distance returned from this route with a GTFS trip 
    with no overlap in time will be 0!
    """
    schedule = GTFSBusSchedule(trip_id,offset=offset_seconds);
    #'bounding boxes' of our time interval and of the GTFS trip's time interval
    bbox = self.getRouteTimeInterval(); 
    sched_bbox = schedule.getRouteTimeInterval();
    oob_count = 0 #count of gtfs stop times that are out of bounds
    vstops = 0 #number of virtual stops that we penalized for

    ret = 0.0
    

    if penalize_gps_oob:
      ## To penalize for being too far outside the GTFS window,
      ## we need to calculate a number of "virtual stops" for which
      ## we were outside of that window, based on the number of stops
      ## the GTFS schedule makes in its time window.
      ## For each of these virtual stops, we penalize the square of
      ## the distance from our position at that time, to the closest-
      ## in-time position of the GTFS trip.
      
      # We use the total number of stops in the GTFS schedule divided
      # by the length in time of the schedule to approximate how many
      # virtual stops we should penalize for.
      stops_per_time = len(schedule.interpolation)/float(sched_bbox[1]
                                                         -sched_bbox[0])
      # If we start before the GTFS trip
      if bbox[0] < sched_bbox[0]:
        # oob_box is the out-of-bounds window
        oob_box=( bbox[0] , min(sched_bbox[0],bbox[1]) )
        # oob_time is the time spent out of bounds
        oob_time = oob_box[1] - oob_box[0]
        # loc1 is the starting location of the GTFS trip
        loc1 = schedule.interpolation[0][:2];
        # n is the number of 'virtual stops' we're penalizing for
        n = int( stops_per_time * oob_time );
        for i in range(n):
          T_i = bbox[0] + i * float(oob_time)/n
          loc2 = self.getLocationAtTime(T_i);
          if not loc2: print "ERROR SOMETHING IS TERRIBLY WRONG"
          ret += gis.distance_meters(loc2[:2],loc1)**2
        vstops += n


      # If we end after the GTFS trip
      if bbox[1] > sched_bbox[1]:
        # oob_box is the out-of-bounds window
        oob_box=( max(sched_bbox[1],bbox[0]) , bbox[1] )
        # oob_time is the time spent out of bounds
        oob_time = oob_box[1] - oob_box[0]
        # loc1 is the ending location of the GTFS trip
        loc1 = schedule.interpolation[-1][:2]
        # n is the number of 'virtual stops' to penalize for
        n = int( stops_per_time * oob_time );
        for i in range(n):
          T_i = bbox[1] - i * float(oob_time)/n
          loc2 = self.getLocationAtTime(T_i);
          if not loc2: print "ERROR SOMETHING IS TERRIBLY WRONG 2"
          ret += gis.distance_meters(loc2[:2],loc1)**2
        vstops += n


    ## Now check along the GTFS route
    for i,pt in enumerate(schedule.interpolation):
      stoptime = pt[2] #- offset_seconds
      myloc = self.getLocationAtTime(stoptime);
      if myloc is None: # then GTFS is out of bounds of GPS time window
        oob_count += 1
        if penalize_gtfs_oob: # so penalize for it, if we're supposed to
          if stoptime < bbox[0]:
            myloc = self.interpolation[0]
          else:
            myloc = self.interpolation[-1]
      if myloc:
        ret += gis.distance_meters( myloc[:2], pt[:2] )**2

    ret = math.sqrt( ret/(len(schedule.interpolation)+vstops) )
    print "  Matching id",trip_id,"start time:",
    print schedule.interpolation[0][2], #-offset_seconds,
    print "  distance: %9.2f OOB count: %2d/%2d"%(ret,oob_count,
                                                  len(schedule.interpolation))
    return ret,float(oob_count)/len(schedule.interpolation)