def findMatchingShapeIndex(self,stop,begin_idx=0,tol=20): ## Given a stop, finds the first shape segment at ## index i >= begin_idx that is within tol meters ## of the stop's location. last_pt = self.shape[begin_idx] min_dist,min_pt = 1e10,None for i,pt in enumerate(self.shape[begin_idx+1:]): dist = gis.distance_from_segment_meters( (last_pt['shape_pt_lat'], last_pt['shape_pt_lon']), (pt['shape_pt_lat'], pt['shape_pt_lon']), (stop['stop_lat'], stop['stop_lon']) ); if dist <= tol: return i+begin_idx; #really it's i+begin_idx+1 - 1 if dist < min_dist: min_dist,min_pt = dist,pt last_pt = pt print "Returning none (DOH!)" print " Min dist was %f meters" % (min_dist,) return None
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
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