예제 #1
0
파일: BusTrack.py 프로젝트: cbick/gps2gtfs
  def getTimesAtLocation(self,stoploc,tol=10.0,starttime=None,findjustone=False):
    """
    Given a (lat,lon), returns a list of (begin,end,dist) intervals of the
    (estimated) times that the bus was within tol meters of that
    location, starting at starttime. The 'dist' part of each interval 
    indicates the estimated minimum distance of the bus from stoploc during 
    that interval.

    If starttime is None, then defaults to the beginning of the track.

    If findjustone is True, returns after finding the first complete interval.
    """
    in_range = False
    current_interval = None # will be [begin,end,dist] holder
    ret = []

    if starttime is None: starttime = self.min_time;
    starttime = max(starttime,self.min_time);
    if starttime > self.max_time:
      return ret

    ## Process intersection at first sub-segment
    startloc = self.getLocationAtTime(starttime);
    ll1 = startloc
    ll2 = self.interpolation[self.cached_index+1][:2]
    t1,t2 = starttime, self.interpolation[self.cached_index+1][2]
    overall_min_dist = gis.distance_from_segment_meters( ll1, ll2, stoploc )
    intersect = gis.distance_intersect( ll1, ll2, stoploc, tol )

    if intersect:
      enter_frac,exit_frac,min_dist = intersect
      enter_time = gis.timefrac_helper( t1,t2,enter_frac )
      exit_time = gis.timefrac_helper( t1,t2,exit_frac )
      if exit_frac == 1.0:
        current_interval = [ enter_time, exit_time, min_dist ]
        in_range = True
      else:
        ret.append([ enter_time, exit_time, min_dist ])

    ## Process subsequent segments
    for i in range(self.cached_index+1, len(self.interpolation)-1):
      llt1 = self.interpolation[i]
      llt2 = self.interpolation[i+1]
      ll1,ll2 = llt1[:2],llt2[:2]

      if len(ret) > 0 and findjustone:
        return ret

      overall_min_dist = min( overall_min_dist, 
                              gis.distance_from_segment_meters(ll1,ll2,stoploc))

      intersect = gis.distance_intersect( ll1,ll2,stoploc,tol )
      if intersect is None:
        if in_range:
          ret.append(current_interval)
          in_range = False
          current_interval = None
        else:
          pass

      else: # intersect is not None
        enter_frac,exit_frac,min_dist = intersect
        enter_time = gis.timefrac_helper( llt1[2],llt2[2],enter_frac )
        exit_time  = gis.timefrac_helper( llt1[2],llt2[2],exit_frac )

        if not in_range: # just entered range of stoploc
          if exit_frac == 1.0:
            current_interval = [ enter_time, exit_time, min_dist ]
            in_range = True
          else:
            ret.append([ enter_time, exit_time, min_dist ])

        else: # in_range
          if enter_frac != 0.0:
            raise Exception, "While in range, found enter_frac of %f" % (enter_frac,)
          else:
            current_interval[1] = exit_time
            current_interval[2] = min(current_interval[2],min_dist)
            if exit_frac == 1.0: # we're still in range
              pass
            else:
              ret.append( current_interval )
              in_range = False
              current_interval = None

    else: # end "for i in range..."
      if in_range:
        ret.append(current_interval)
    
    if not ret: # empty list
      print "--- No arrival, min dist was:",overall_min_dist

    return ret
예제 #2
0
    def getTimesAtLocation(self,
                           stoploc,
                           tol=10.0,
                           starttime=None,
                           findjustone=False):
        """
    Given a (lat,lon), returns a list of (begin,end,dist) intervals of the
    (estimated) times that the bus was within tol meters of that
    location, starting at starttime. The 'dist' part of each interval 
    indicates the estimated minimum distance of the bus from stoploc during 
    that interval.

    If starttime is None, then defaults to the beginning of the track.

    If findjustone is True, returns after finding the first complete interval.
    """
        in_range = False
        current_interval = None  # will be [begin,end,dist] holder
        ret = []

        if starttime is None: starttime = self.min_time
        starttime = max(starttime, self.min_time)
        if starttime > self.max_time:
            return ret

        ## Process intersection at first sub-segment
        startloc = self.getLocationAtTime(starttime)
        ll1 = startloc
        ll2 = self.interpolation[self.cached_index + 1][:2]
        t1, t2 = starttime, self.interpolation[self.cached_index + 1][2]
        overall_min_dist = gis.distance_from_segment_meters(ll1, ll2, stoploc)
        intersect = gis.distance_intersect(ll1, ll2, stoploc, tol)

        if intersect:
            enter_frac, exit_frac, min_dist = intersect
            enter_time = gis.timefrac_helper(t1, t2, enter_frac)
            exit_time = gis.timefrac_helper(t1, t2, exit_frac)
            if exit_frac == 1.0:
                current_interval = [enter_time, exit_time, min_dist]
                in_range = True
            else:
                ret.append([enter_time, exit_time, min_dist])

        ## Process subsequent segments
        for i in range(self.cached_index + 1, len(self.interpolation) - 1):
            llt1 = self.interpolation[i]
            llt2 = self.interpolation[i + 1]
            ll1, ll2 = llt1[:2], llt2[:2]

            if len(ret) > 0 and findjustone:
                return ret

            overall_min_dist = min(
                overall_min_dist,
                gis.distance_from_segment_meters(ll1, ll2, stoploc))

            intersect = gis.distance_intersect(ll1, ll2, stoploc, tol)
            if intersect is None:
                if in_range:
                    ret.append(current_interval)
                    in_range = False
                    current_interval = None
                else:
                    pass

            else:  # intersect is not None
                enter_frac, exit_frac, min_dist = intersect
                enter_time = gis.timefrac_helper(llt1[2], llt2[2], enter_frac)
                exit_time = gis.timefrac_helper(llt1[2], llt2[2], exit_frac)

                if not in_range:  # just entered range of stoploc
                    if exit_frac == 1.0:
                        current_interval = [enter_time, exit_time, min_dist]
                        in_range = True
                    else:
                        ret.append([enter_time, exit_time, min_dist])

                else:  # in_range
                    if enter_frac != 0.0:
                        raise Exception, "While in range, found enter_frac of %f" % (
                            enter_frac, )
                    else:
                        current_interval[1] = exit_time
                        current_interval[2] = min(current_interval[2],
                                                  min_dist)
                        if exit_frac == 1.0:  # we're still in range
                            pass
                        else:
                            ret.append(current_interval)
                            in_range = False
                            current_interval = None

        else:  # end "for i in range..."
            if in_range:
                ret.append(current_interval)

        if not ret:  # empty list
            print "--- No arrival, min dist was:", overall_min_dist

        return ret
예제 #3
0
파일: BusTrack.py 프로젝트: cbick/gps2gtfs
  def getArrivalTimeAtLocation(self,stoploc,tol=10.0,starttime=None):
    """
    Given a stop location (lat,lon), a tolerance in meters, and a starting
    time, does the following:
    
    Finds the first time interval (t1,t2) within which the line segments
    of this track are all within tol meters of stoploc, and t1>starttime.
    
    Returns the time t such that t1<=t<=t2 at which this track was closest
    to stoploc.

    If this track was never within tol meters of the location, then 
    returns None.
    """
    ## We'll use the internal cached index here, just as in the
    ## getLocationAtTime method, in order to speed up sequential
    ## requests to this method.

    # Some might consider this bad programming practice,
    # in that we rely on the behavior of another method
    # to correcty implement this one.
    # If this ends up causing breakage, then there should
    # be some kind of "setInternalTime()" method for this class.
    if starttime is None: starttime = self.min_time;
    starttime = max(starttime,self.min_time);
    if starttime > self.max_time:
      return None

    startloc = self.getLocationAtTime(starttime);
    ll1 = startloc
    ll2 = self.interpolation[self.cached_index+1][:2]
    min_dist,frac = gis.interp_helper(ll1,ll2,stoploc);
    min_time = gis.timefrac_helper(starttime,
                               self.interpolation[self.cached_index+1][2],
                               frac);
    within_tol = (min_dist < tol);
    if str(min_time) == 'nan':
      raise Exception, "WTF"

    for idx in range(self.cached_index+1, len(self.interpolation)-1):
      pt1 = self.interpolation[idx];
      pt2 = self.interpolation[idx+1];
      ll1 = pt1[:2]
      ll2 = pt2[:2]
      dist,frac = gis.interp_helper(ll1,ll2,stoploc);
      
      if dist < min_dist:
        min_dist = dist;
        min_time = gis.timefrac_helper(pt1[2],pt2[2],frac);
        if str(min_time) == 'nan':
          raise Exception, "WTF"

      if (dist > tol) and within_tol:
        #We've left the tolerance zone, so we should have an answer
        break

      if (dist > tol):
        # We haven't found the tolerance zone yet
        continue

      within_tol = True;
      

    if not within_tol:
      # We never entered a tolerance zone
      print "XXX No arrival, min dist was:",min_dist
      return None  
    
    print "OOO Arrival with distance:",min_dist
    return min_time
예제 #4
0
    def getArrivalTimeAtLocation(self, stoploc, tol=10.0, starttime=None):
        """
    Given a stop location (lat,lon), a tolerance in meters, and a starting
    time, does the following:
    
    Finds the first time interval (t1,t2) within which the line segments
    of this track are all within tol meters of stoploc, and t1>starttime.
    
    Returns the time t such that t1<=t<=t2 at which this track was closest
    to stoploc.

    If this track was never within tol meters of the location, then 
    returns None.
    """
        ## We'll use the internal cached index here, just as in the
        ## getLocationAtTime method, in order to speed up sequential
        ## requests to this method.

        # Some might consider this bad programming practice,
        # in that we rely on the behavior of another method
        # to correcty implement this one.
        # If this ends up causing breakage, then there should
        # be some kind of "setInternalTime()" method for this class.
        if starttime is None: starttime = self.min_time
        starttime = max(starttime, self.min_time)
        if starttime > self.max_time:
            return None

        startloc = self.getLocationAtTime(starttime)
        ll1 = startloc
        ll2 = self.interpolation[self.cached_index + 1][:2]
        min_dist, frac = gis.interp_helper(ll1, ll2, stoploc)
        min_time = gis.timefrac_helper(
            starttime, self.interpolation[self.cached_index + 1][2], frac)
        within_tol = (min_dist < tol)
        if str(min_time) == 'nan':
            raise Exception, "WTF"

        for idx in range(self.cached_index + 1, len(self.interpolation) - 1):
            pt1 = self.interpolation[idx]
            pt2 = self.interpolation[idx + 1]
            ll1 = pt1[:2]
            ll2 = pt2[:2]
            dist, frac = gis.interp_helper(ll1, ll2, stoploc)

            if dist < min_dist:
                min_dist = dist
                min_time = gis.timefrac_helper(pt1[2], pt2[2], frac)
                if str(min_time) == 'nan':
                    raise Exception, "WTF"

            if (dist > tol) and within_tol:
                #We've left the tolerance zone, so we should have an answer
                break

            if (dist > tol):
                # We haven't found the tolerance zone yet
                continue

            within_tol = True

        if not within_tol:
            # We never entered a tolerance zone
            print "XXX No arrival, min dist was:", min_dist
            return None

        print "OOO Arrival with distance:", min_dist
        return min_time