Ejemplo n.º 1
0
def cut_points_by_distance(scs, n=10, max_distance=45, \
                           min_distance=1.0, min_length=10):
  """ Cuts points into tracks according to some distance criterion.
  Arguments:
   - scs: a list of StateCollection items corresponding to a run
   - n: index shift, > 0. The algorithm will compare the distance between
      sc[i] and sc[i+n]. If this distance is found to be greater than
      n * max_distance, the trjactory is cut at i.
   - max_distance: the maximum distance between two points. Two points
     separated by more than this distance are cut.
   - min_distance: minimum distance between two point. Below this distance,
     the new point is discard for beeing too close.
   - min_length: the minimum length of a track.
  n: 
  """
  # Meters, corresponds to 1-second probe data
  N = len(scs)
  # Compute the n-cut distance first to get an idea of long-terms cuts
  dsn = [mm_dis(scs[i].gps_pos, scs[i+n].gps_pos) for i in xrange(N-n)]
  # Distance cuts:
  d_cuts = [i for i in xrange(N-n) if dsn[i] > n*max_distance]
  points = [0] + d_cuts + [N]
  res = []
  for (start, end) in zip(points[:-1], points[1:]):
    all_points = scs[start:end]
    all_points.reverse()
    l = [all_points[-1]]
    while all_points:
      x = all_points.pop()
      if mm_dis(x.gps_pos, l[-1].gps_pos) > min_distance:
        l.append(x)
    if len(l) >= min_length:
      res.append(l)
  return res
Ejemplo n.º 2
0
def remove_spurious_points(scs, n=3, max_distance=45, \
                           min_distance=1.0, min_length=10):
  """ Removes a number of points that are of no interest or may cause trouble:
  - points that correspond to no move (stationary vehicle)
  - far points that correspond to GPS errors that make the trajectory jump
  Arguments:
  scs: a list of StateCollection items corresponding to a run
  n: the maximum number of points that may group as a GPS error
  max_distance: that maximum distance between points corresponding to a valid
    travel. Over this distance, the point is assumed to be disconnected.
  min_distance: under this distance, the vehicle is assumed to be stationary
  min_length: minimum size of groups of points to correspond to a valid
    trajectory chunk.
  
  Returns: a list of list of valid tracks.
  """
  res = []
  # This is a queue that will contain the points
  # Each point will be popped out and compared to the head of the 
  # current track.
  all_scs = list(scs)
  all_scs.reverse() # Need to reverse, since we will pop() from the start.
  current_track = []
  current_junk = []
  while all_scs:
    current_sc = all_scs.pop()
    if not current_track:
      current_track = [current_sc]
    else:
      last_sc = current_track[-1]
      assert last_sc.time < current_sc.time
      # Compare the distance
      d = mm_dis(last_sc.gps_pos, current_sc.gps_pos)
      # If too far, add to the junk
      if d < min_distance:
        continue
      if d > max_distance:
        current_junk.append(current_sc)
        # If junk if full, discard it, cut the track and start again
        if len(current_junk) > n:
          current_junk = []
          # If the cut track is long enough, keep it
          if len(current_track) >= min_length:
            res.append(current_track)
          current_track = []
      else:
        current_track.append(current_sc)
  # And take care of the last track
  if len(current_track) >= min_length:
    res.append(current_track)
  return res