def _is_tracking_restarted(last_place, start_loc, timeseries):
    return eaisr.is_tracking_restarted_in_range(last_place.enter_ts,
                                                start_loc.ts, timeseries)
Beispiel #2
0
    def has_trip_ended(self, prev_point, curr_point, timeseries,
                       last10PointsDistances, last5MinsDistances,
                       last5MinTimes):
        # Another mismatch between phone and server. Phone stops tracking too soon,
        # so the distance is still greater than the threshold at the end of the trip.
        # But then the next point is a long time away, so we can split again (similar to a distance filter)
        if prev_point is None:
            logging.debug("prev_point is None, continuing trip")
        else:
            timeDelta = curr_point.ts - prev_point.ts
            distDelta = pf.calDistance(prev_point, curr_point)
            if timeDelta > 0:
                speedDelta = old_div(distDelta, timeDelta)
            else:
                speedDelta = np.nan
            speedThreshold = old_div(float(self.distance_threshold),
                                     self.time_threshold)

            if eaisr.is_tracking_restarted_in_range(prev_point.ts,
                                                    curr_point.ts, timeseries):
                logging.debug("tracking was restarted, ending trip")
                return True

            ongoing_motion_check = len(
                eaisr.get_ongoing_motion_in_range(prev_point.ts, curr_point.ts,
                                                  timeseries)) > 0
            if timeDelta > 2 * self.time_threshold and not ongoing_motion_check:
                logging.debug(
                    "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip"
                    % (prev_point.ts, curr_point.ts, self.time_threshold,
                       curr_point.ts - prev_point.ts, ongoing_motion_check))
                return True

            # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html
            # Longest flight is 17 hours, which is the longest you can go without cell reception
            # And even if you split an air flight that long into two, you will get some untracked time in the
            # middle, so that's good.
            TWELVE_HOURS = 12 * 60 * 60
            if timeDelta > TWELVE_HOURS:
                logging.debug(
                    "prev_point.ts = %s, curr_point.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip"
                    % (prev_point.ts, curr_point.ts, TWELVE_HOURS,
                       curr_point.ts - prev_point.ts))
                return True

            if (timeDelta > 2 * self.time_threshold
                    and  # We have been here for a while
                    speedDelta < speedThreshold):  # we haven't moved very much
                logging.debug(
                    "prev_point.ts = %s, curr_point.ts = %s, threshold = %s, large gap = %s, ending trip"
                    % (prev_point.ts, curr_point.ts, self.time_threshold,
                       curr_point.ts - prev_point.ts))
                return True
            else:
                logging.debug(
                    "prev_point.ts = %s, curr_point.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip"
                    % (prev_point.ts, curr_point.ts, timeDelta,
                       self.time_threshold, distDelta, self.distance_threshold,
                       speedDelta, speedThreshold))

        # The -30 is a fuzz factor intended to compensate for older clients
        # where data collection stopped after 5 mins, so that we never actually
        # see 5 mins of data

        if (len(last10PointsDistances) < self.point_threshold - 1
                or len(last5MinsDistances) == 0
                or last5MinTimes.max() < self.time_threshold - 30):
            logging.debug("Too few points to make a decision, continuing")
            return False

        # Normal end-of-trip case
        logging.debug(
            "last5MinsDistances.max() = %s, last10PointsDistance.max() = %s" %
            (last5MinsDistances.max(), last10PointsDistances.max()))
        if (last5MinsDistances.max() < self.distance_threshold
                and last10PointsDistances.max() < self.distance_threshold):
            return True
    def has_trip_ended(self, lastPoint, currPoint, timeseries):
        # So we must not have been moving for the last _time filter_
        # points. So the trip must have ended
        # Since this is a distance filter, we detect that the last
        # trip has ended at the time that the new trip starts. So
        # if the last_trip_end_point is lastPoint, then
        # curr_trip_start_point should be currPoint. But then we will
        # have problems with the spurious, noisy points that are
        # generated until the geofence is turned on, if ever
        # So we will continue to defer new trip starting until we
        # have worked through all of those.
        timeDelta = currPoint.ts - lastPoint.ts
        distDelta = pf.calDistance(lastPoint, currPoint)
        logging.debug(
            "lastPoint = %s, time difference = %s dist difference %s" %
            (lastPoint, timeDelta, distDelta))
        if timeDelta > self.time_threshold:
            # We have been at this location for more than the time filter.
            # This could be because we have not been moving for the last
            # _time filter_ points, or because we didn't get points for
            # that duration, (e.g. because we were underground)
            if timeDelta > 0:
                speedDelta = old_div(distDelta, timeDelta)
            else:
                speedDelta = np.nan
            # this is way too slow. On ios, we use 5meters in 10 minutes.
            # On android, we use 10 meters in 5 mins, which seems to work better
            # for this kind of test
            speedThreshold = old_div(float(self.distance_threshold * 2),
                                     (old_div(self.time_threshold, 2)))

            if eaisr.is_tracking_restarted_in_range(lastPoint.ts, currPoint.ts,
                                                    timeseries):
                logging.debug("tracking was restarted, ending trip")
                return True

            # In general, we get multiple locations between each motion activity. If we see a bunch of motion activities
            # between two location points, and there is a large gap between the last location and the first
            # motion activity as well, let us just assume that there was a restart
            ongoing_motion_in_range = eaisr.get_ongoing_motion_in_range(
                lastPoint.ts, currPoint.ts, timeseries)
            ongoing_motion_check = len(ongoing_motion_in_range) > 0
            if timeDelta > self.time_threshold and not ongoing_motion_check:
                logging.debug(
                    "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip"
                    % (lastPoint.ts, currPoint.ts, self.time_threshold,
                       currPoint.ts - lastPoint.ts, ongoing_motion_check))
                return True

            # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html
            # Longest flight is 17 hours, which is the longest you can go without cell reception
            # And even if you split an air flight that long into two, you will get some untracked time in the
            # middle, so that's good.
            TWELVE_HOURS = 12 * 60 * 60
            if timeDelta > TWELVE_HOURS:
                logging.debug(
                    "lastPoint.ts = %s, currPoint.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip"
                    % (lastPoint.ts, currPoint.ts, TWELVE_HOURS,
                       currPoint.ts - lastPoint.ts))
                return True

            if (timeDelta > self.time_threshold
                    and  # We have been here for a while
                    speedDelta < speedThreshold):  # we haven't moved very much
                # This can happen even during ongoing trips due to spurious points
                # generated on some iOS phones
                # https://github.com/e-mission/e-mission-server/issues/577#issuecomment-376379460
                if eaistc.is_huge_invalid_ts_offset(self, lastPoint, currPoint,
                                                    timeseries,
                                                    ongoing_motion_in_range):
                    # invalidate from memory and the database.
                    logging.debug("About to set valid column for index = %s" %
                                  (currPoint.idx))
                    self.filtered_points_df.valid.iloc[currPoint.idx] = False
                    logging.debug("After dropping %d, filtered points = %s" %
                                  (currPoint.idx, self.filtered_points_df.
                                   iloc[currPoint.idx - 5:currPoint.idx +
                                        5][["valid", "fmt_time"]]))
                    logging.debug("remove huge invalid ts offset point = %s" %
                                  currPoint)
                    timeseries.invalidate_raw_entry(currPoint["_id"])
                    # We currently re-retrieve the last point every time, so
                    # searching upwards is good enough but if we use
                    # lastPoint = currPoint, we should update currPoint here
                    return False
                else:
                    logging.debug(
                        "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ending trip"
                        % (lastPoint.ts, currPoint.ts, self.time_threshold,
                           currPoint.ts - lastPoint.ts))
                    return True
            else:
                logging.debug(
                    "lastPoint.ts = %s, currPoint.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip"
                    % (lastPoint.ts, currPoint.ts, timeDelta,
                       self.time_threshold, distDelta, self.distance_threshold,
                       speedDelta, speedThreshold))
                return False
    def has_trip_ended(self, prev_point, curr_point, timeseries, last10PointsDistances, last5MinsDistances, last5MinTimes):
        # Another mismatch between phone and server. Phone stops tracking too soon,
        # so the distance is still greater than the threshold at the end of the trip.
        # But then the next point is a long time away, so we can split again (similar to a distance filter)
        if prev_point is None:
            logging.debug("prev_point is None, continuing trip")
        else:
            timeDelta = curr_point.ts - prev_point.ts
            distDelta = pf.calDistance(prev_point, curr_point)
            if timeDelta > 0:
                speedDelta = old_div(distDelta, timeDelta)
            else:
                speedDelta = np.nan
            speedThreshold = old_div(float(self.distance_threshold), self.time_threshold)

            if eaisr.is_tracking_restarted_in_range(prev_point.ts, curr_point.ts, timeseries):
                logging.debug("tracking was restarted, ending trip")
                return True

            ongoing_motion_check = len(eaisr.get_ongoing_motion_in_range(prev_point.ts, curr_point.ts, timeseries)) > 0
            if timeDelta > 2 * self.time_threshold and not ongoing_motion_check:
                logging.debug("lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip" %
                              (prev_point.ts, curr_point.ts,self.time_threshold, curr_point.ts - prev_point.ts, ongoing_motion_check))
                return True

            # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html
            # Longest flight is 17 hours, which is the longest you can go without cell reception
            # And even if you split an air flight that long into two, you will get some untracked time in the
            # middle, so that's good.
            TWELVE_HOURS = 12 * 60 * 60
            if timeDelta > TWELVE_HOURS:
                logging.debug("prev_point.ts = %s, curr_point.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip" %
                              (prev_point.ts, curr_point.ts, TWELVE_HOURS, curr_point.ts - prev_point.ts))
                return True

            if (timeDelta > 2 * self.time_threshold and # We have been here for a while
                 speedDelta < speedThreshold): # we haven't moved very much
                logging.debug("prev_point.ts = %s, curr_point.ts = %s, threshold = %s, large gap = %s, ending trip" %
                              (prev_point.ts, curr_point.ts,self.time_threshold, curr_point.ts - prev_point.ts))
                return True
            else:
                logging.debug("prev_point.ts = %s, curr_point.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip" %
                              (prev_point.ts, curr_point.ts,
                               timeDelta, self.time_threshold,
                               distDelta, self.distance_threshold,
                               speedDelta, speedThreshold))

        # The -30 is a fuzz factor intended to compensate for older clients
        # where data collection stopped after 5 mins, so that we never actually
        # see 5 mins of data

        if (len(last10PointsDistances) < self.point_threshold - 1 or
                    len(last5MinsDistances) == 0 or
                    last5MinTimes.max() < self.time_threshold - 30):
            logging.debug("Too few points to make a decision, continuing")
            return False

        # Normal end-of-trip case
        logging.debug("last5MinsDistances.max() = %s, last10PointsDistance.max() = %s" %
                      (last5MinsDistances.max(), last10PointsDistances.max()))
        if (last5MinsDistances.max() < self.distance_threshold and
            last10PointsDistances.max() < self.distance_threshold):
                return True
Beispiel #5
0
    def has_trip_ended(self, lastPoint, currPoint, timeseries):
        # So we must not have been moving for the last _time filter_
        # points. So the trip must have ended
        # Since this is a distance filter, we detect that the last
        # trip has ended at the time that the new trip starts. So
        # if the last_trip_end_point is lastPoint, then
        # curr_trip_start_point should be currPoint. But then we will
        # have problems with the spurious, noisy points that are
        # generated until the geofence is turned on, if ever
        # So we will continue to defer new trip starting until we
        # have worked through all of those.
        timeDelta = currPoint.ts - lastPoint.ts
        distDelta = pf.calDistance(lastPoint, currPoint)
        logging.debug(
            "lastPoint = %s, time difference = %s dist difference %s" %
            (lastPoint, timeDelta, distDelta))
        if timeDelta > self.time_threshold:
            # We have been at this location for more than the time filter.
            # This could be because we have not been moving for the last
            # _time filter_ points, or because we didn't get points for
            # that duration, (e.g. because we were underground)
            if timeDelta > 0:
                speedDelta = distDelta / timeDelta
            else:
                speedDelta = np.nan
            # this is way too slow. On ios, we use 5meters in 10 minutes.
            # On android, we use 10 meters in 5 mins, which seems to work better
            # for this kind of test
            speedThreshold = float(
                self.distance_threshold * 2) / (self.time_threshold / 2)

            if eaisr.is_tracking_restarted_in_range(lastPoint.ts, currPoint.ts,
                                                    timeseries):
                logging.debug("tracking was restarted, ending trip")
                return True

            # In general, we get multiple locations between each motion activity. If we see a bunch of motion activities
            # between two location points, and there is a large gap between the last location and the first
            # motion activity as well, let us just assume that there was a restart
            ongoing_motion_check = len(
                eaisr.get_ongoing_motion_in_range(lastPoint.ts, currPoint.ts,
                                                  timeseries)) > 0
            if timeDelta > self.time_threshold and not ongoing_motion_check:
                logging.debug(
                    "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip"
                    % (lastPoint.ts, currPoint.ts, self.time_threshold,
                       currPoint.ts - lastPoint.ts, ongoing_motion_check))
                return True

            # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html
            # Longest flight is 17 hours, which is the longest you can go without cell reception
            # And even if you split an air flight that long into two, you will get some untracked time in the
            # middle, so that's good.
            TWELVE_HOURS = 12 * 60 * 60
            if timeDelta > TWELVE_HOURS:
                logging.debug(
                    "lastPoint.ts = %s, currPoint.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip"
                    % (lastPoint.ts, currPoint.ts, TWELVE_HOURS,
                       currPoint.ts - lastPoint.ts))
                return True

            if (timeDelta > self.time_threshold
                    and  # We have been here for a while
                    speedDelta < speedThreshold):  # we haven't moved very much
                logging.debug(
                    "lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ending trip"
                    % (lastPoint.ts, currPoint.ts, self.time_threshold,
                       currPoint.ts - lastPoint.ts))
                return True
            else:
                logging.debug(
                    "lastPoint.ts = %s, currPoint.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip"
                    % (lastPoint.ts, currPoint.ts, timeDelta,
                       self.time_threshold, distDelta, self.distance_threshold,
                       speedDelta, speedThreshold))
                return False
def _is_tracking_restarted(last_place, start_loc, timeseries):
    return eaisr.is_tracking_restarted_in_range(last_place.enter_ts, start_loc.ts, timeseries)
    def has_trip_ended(self, lastPoint, currPoint, timeseries):
        # So we must not have been moving for the last _time filter_
        # points. So the trip must have ended
        # Since this is a distance filter, we detect that the last
        # trip has ended at the time that the new trip starts. So
        # if the last_trip_end_point is lastPoint, then
        # curr_trip_start_point should be currPoint. But then we will
        # have problems with the spurious, noisy points that are
        # generated until the geofence is turned on, if ever
        # So we will continue to defer new trip starting until we
        # have worked through all of those.
        timeDelta = currPoint.ts - lastPoint.ts
        distDelta = pf.calDistance(lastPoint, currPoint)
        logging.debug("lastPoint = %s, time difference = %s dist difference %s" %
                      (lastPoint, timeDelta, distDelta))
        if timeDelta > self.time_threshold:
            # We have been at this location for more than the time filter.
            # This could be because we have not been moving for the last
            # _time filter_ points, or because we didn't get points for
            # that duration, (e.g. because we were underground)
            if timeDelta > 0:
                speedDelta = distDelta / timeDelta
            else:
                speedDelta = np.nan
            # this is way too slow. On ios, we use 5meters in 10 minutes.
            # On android, we use 10 meters in 5 mins, which seems to work better
            # for this kind of test
            speedThreshold = float(self.distance_threshold * 2) / (self.time_threshold / 2)

            if eaisr.is_tracking_restarted_in_range(lastPoint.ts, currPoint.ts, timeseries):
                logging.debug("tracking was restarted, ending trip")
                return True

            # In general, we get multiple locations between each motion activity. If we see a bunch of motion activities
            # between two location points, and there is a large gap between the last location and the first
            # motion activity as well, let us just assume that there was a restart
            ongoing_motion_check = len(eaisr.get_ongoing_motion_in_range(lastPoint.ts, currPoint.ts, timeseries)) > 0
            if timeDelta > self.time_threshold and not ongoing_motion_check:
                logging.debug("lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ongoing_motion_in_range = %s, ending trip" %
                              (lastPoint.ts, currPoint.ts,self.time_threshold, currPoint.ts - lastPoint.ts, ongoing_motion_check))
                return True

            # http://www.huffingtonpost.com/hoppercom/the-worlds-20-longest-non-stop-flights_b_5994268.html
            # Longest flight is 17 hours, which is the longest you can go without cell reception
            # And even if you split an air flight that long into two, you will get some untracked time in the
            # middle, so that's good.
            TWELVE_HOURS = 12 * 60 * 60
            if timeDelta > TWELVE_HOURS:
                logging.debug("lastPoint.ts = %s, currPoint.ts = %s, TWELVE_HOURS = %s, large gap = %s, ending trip" %
                              (lastPoint.ts, currPoint.ts, TWELVE_HOURS, currPoint.ts - lastPoint.ts))
                return True

            if (timeDelta > self.time_threshold and # We have been here for a while
                        speedDelta < speedThreshold): # we haven't moved very much
                logging.debug("lastPoint.ts = %s, currPoint.ts = %s, threshold = %s, large gap = %s, ending trip" %
                              (lastPoint.ts, currPoint.ts,self.time_threshold, currPoint.ts - lastPoint.ts))
                return True
            else:
                logging.debug("lastPoint.ts = %s, currPoint.ts = %s, time gap = %s (vs %s), distance_gap = %s (vs %s), speed_gap = %s (vs %s) continuing trip" %
                              (lastPoint.ts, currPoint.ts,
                               timeDelta, self.time_threshold,
                               distDelta, self.distance_threshold,
                               speedDelta, speedThreshold))
                return False