def calc_speed(self): segment_speeds = [] # ignore the first point if it's not within the moving threshold points = self[1:] if len(self) > 1 and not Path.linked(self[0], self[1]) else self[:] # dont consider paths that we really didnt capture (aka teleporting) if len(points) < 2: self.speed = None return # calc segment speeds for i, point in enumerate(points[:-1]): next = points[i+1] d = science.geo_distance(point.location, next.location, True) t = abs(point.t - next.t) if t > 0.0: segment_speeds.append(d / t) # we are using the second-to-fastest segment, if possible, as the speed for this path. cars also go slow; by not using the fastest we're filtering subway travel. segment_speeds.sort() self.speed = None index = -2 while self.speed is None and index <= 0: try: self.speed = segment_speeds[index] * 60 * 60 # mph except IndexError as e: index += 1
def bake(self): self.start_point = self[0] self.end_point = self[-1] self.distance = science.geo_distance(self.start_point.location, self.end_point.location) self.start_time = self[1].date if len(self) > 1 and not Path.linked(self[0], self[1]) else self[0].date # dont use the start_point date as the path start_time if we've been at the start_point for awhile self.end_time = self[-1].date self.calc_speed()
def get_closest(point): # in theory, a point in a cluster could be closer to the centroid of a different cluster (maybe?). however, I dont think doing things this way will be detrimental min_d = float('inf') for cluster in clusters: d = science.geo_distance((point.lon, point.lat), cluster.vector) if d < min_d: closest_cluster = cluster min_d = d return closest_cluster
def build(cls, data, start, end, center=None): log.info("Loading OpenPaths data...") if center is not None: points = [Point(i, float(d['lon']), float(d['lat']), d['t']) for i, d in enumerate(data) if d['t'] >= start and d['t'] <= end and science.geo_distance((float(d['lon']), float(d['lat'])), center) <= RADIUS] else: points = [Point(i, float(d['lon']), float(d['lat']), d['t']) for i, d in enumerate(data) if d['t'] >= start and d['t'] <= end] points.sort(key=lambda p: p.t) log.info("Generating graph...") start_clock = time.clock() paths = Path.find_paths(points) places = Place.find_places(paths, CLUSTER_RADIUS) cities = City.find_cities(places, CITY_RADIUS) almanac = Almanac(points, paths, places, cities) # almanac.label() print("(%ss)" % (time.clock() - start_clock)) return almanac