Example #1
0
def parse_samples(tree, move, gpx_namespace):
    all_samples = []

    tracks = tree.iterchildren(tag=gpx_namespace + GPX_TRK)
    for track in tracks:
        track_samples = []

        track_segments = track.iterchildren(tag=gpx_namespace + GPX_TRKSEG)
        for track_segment in track_segments:
            segment_samples = []

            track_points = track_segment.iterchildren(tag=gpx_namespace + GPX_TRKPT)
            for track_point in track_points:
                sample = Sample()
                sample.move = move

                # GPS position / altitude
                sample.latitude = degree_to_radian(float(track_point.attrib[GPX_TRKPT_ATTRIB_LATITUDE]))
                sample.longitude = degree_to_radian(float(track_point.attrib[GPX_TRKPT_ATTRIB_LONGITUDE]))
                sample.sample_type = "gps-base"
                if hasattr(track_point, GPX_TRKPT_ATTRIB_ELEVATION):
                    sample.gps_altitude = float(track_point.ele)
                    sample.altitude = int(round(sample.gps_altitude))

                # Time / UTC
                sample.utc = dateutil.parser.parse(str(track_point.time))
                if len(segment_samples) > 0:
                    # Accumulate time delta to previous sample to get the total duration
                    time_delta = sample.utc - segment_samples[-1].utc
                    sample.time = segment_samples[-1].time + time_delta

                    # Accumulate distance to previous sample
                    distance_delta = vincenty(
                        (radian_to_degree(sample.latitude), radian_to_degree(sample.longitude)),
                        (
                            radian_to_degree(segment_samples[-1].latitude),
                            radian_to_degree(segment_samples[-1].longitude),
                        ),
                    ).meters
                    sample.distance = segment_samples[-1].distance + distance_delta
                    if time_delta > timedelta(0):
                        sample.speed = distance_delta / time_delta.total_seconds()
                    else:
                        sample.speed = 0

                elif len(track_samples) > 0:
                    sample.time = track_samples[-1].time
                    sample.distance = track_samples[-1].distance
                    sample.speed = track_samples[-1].speed
                elif len(all_samples) > 0:
                    sample.time = all_samples[-1].time
                    sample.distance = all_samples[-1].distance
                    sample.speed = all_samples[-1].speed
                else:
                    sample.time = timedelta(0)
                    sample.distance = 0
                    sample.speed = 0

                parse_sample_extensions(sample, track_point)
                segment_samples.append(sample)

            # Insert an pause event between every tracksegment
            insert_pause(track_samples, segment_samples)
            track_samples.extend(segment_samples)

        # Insert an pause event between every track
        insert_pause(all_samples, track_samples)
        all_samples.extend(track_samples)
    return all_samples
Example #2
0
def parse_samples(tree, move, gpx_namespace, import_options):
    all_samples = []

    tracks = tree.iterchildren(tag=gpx_namespace + GPX_TRK)
    for track in tracks:
        track_samples = []

        track_segments = track.iterchildren(tag=gpx_namespace + GPX_TRKSEG)
        for track_segment in track_segments:
            segment_samples = []

            track_points = track_segment.iterchildren(tag=gpx_namespace + GPX_TRKPT)
            for track_point in track_points:
                sample = Sample()
                sample.move = move

                # GPS position / altitude
                sample.latitude = degree_to_radian(float(track_point.attrib[GPX_TRKPT_ATTRIB_LATITUDE]))
                sample.longitude = degree_to_radian(float(track_point.attrib[GPX_TRKPT_ATTRIB_LONGITUDE]))
                sample.sample_type = GPX_SAMPLE_TYPE
                if hasattr(track_point, GPX_TRKPT_ATTRIB_ELEVATION):
                    sample.gps_altitude = float(track_point.ele)
                    sample.altitude = int(round(sample.gps_altitude))

                # Time / UTC
                sample.utc = dateutil.parser.parse(str(track_point.time))

                # Option flags
                pause_detected = False

                # Track segment samples
                if len(segment_samples) > 0:
                    # Accumulate time delta to previous sample to get the total duration
                    time_delta = sample.utc - segment_samples[-1].utc
                    sample.time = segment_samples[-1].time + time_delta

                    # Accumulate distance to previous sample
                    distance_delta = distance((radian_to_degree(sample.latitude), radian_to_degree(sample.longitude)),
                                              (radian_to_degree(segment_samples[-1].latitude), radian_to_degree(segment_samples[-1].longitude))).meters

                    sample.distance = segment_samples[-1].distance + distance_delta
                    if time_delta > timedelta(0):
                        sample.speed = distance_delta / time_delta.total_seconds()
                    else:
                        sample.speed = 0

                    # Option: Pause detection based on time delta threshold
                    if GPX_IMPORT_OPTION_PAUSE_DETECTION in import_options and time_delta > import_options[GPX_IMPORT_OPTION_PAUSE_DETECTION]:
                        pause_detected = True
                        sample.distance = segment_samples[-1].distance
                        sample.speed = 0

                # Track segment -> Track (multiple track segments contained)
                elif len(track_samples) > 0:
                    sample.time = track_samples[-1].time + (sample.utc - track_samples[-1].utc)  # Time diff to last sample of the previous track segment
                    sample.distance = track_samples[-1].distance
                    sample.speed = 0
                # Track -> Full GPX (multiple tracks contained)
                elif len(all_samples) > 0:
                    sample.time = all_samples[-1].time + (sample.utc - all_samples[-1].utc)  # Time diff to last sample of the previous track
                    sample.distance = all_samples[-1].distance
                    sample.speed = 0
                # First sample
                else:
                    sample.time = timedelta(0)
                    sample.distance = 0
                    sample.speed = 0

                parse_sample_extensions(sample, track_point)
                segment_samples.append(sample)

                # Finally insert a found pause based on time delta threshold
                if pause_detected:
                    insert_pause(segment_samples, len(segment_samples) - 1, move, pause_type=GPX_IMPORT_PAUSE_TYPE_PAUSE_DETECTION)
            # end for track_points

            # Insert an pause event between every track segment
            insert_pause_idx = len(track_samples)
            track_samples.extend(segment_samples)
            insert_pause(track_samples, insert_pause_idx, move, pause_type=GPX_TRKSEG)
        # end for track_segments

        # Insert an pause event between every track
        insert_pause_idx = len(all_samples)
        all_samples.extend(track_samples)
        insert_pause(all_samples, insert_pause_idx, move, pause_type=GPX_TRK)
    # end for tracks
    return all_samples
Example #3
0
def strava_import(current_user, activity_id):
    client = get_strava_client(current_user)
    activity = client.get_activity(activity_id=activity_id)
    stream_types = [
        'time', 'distance', 'latlng', 'temp', 'heartrate', 'velocity_smooth',
        'altitude'
    ]
    streams = client.get_activity_streams(activity_id, types=stream_types)

    activity_string = map_type(activity.type)

    result = db.session.query(
        Move.activity_type).filter(Move.activity == activity_string).first()
    if result:
        activity_type, = result
    else:
        activity_type = None

    device = find_device(current_user)

    move = Move()
    move.user = current_user
    move.duration = activity.elapsed_time
    move.ascent = float(activity.total_elevation_gain)
    move.speed_avg = float(activity.average_speed)
    move.hr_avg = heart_rate(activity.average_heartrate)
    move.temperature_avg = celcius_to_kelvin(activity.average_temp)
    move.device = device
    move.date_time = activity.start_date_local
    move.activity = activity_string
    move.activity_type = activity_type
    move.distance = float(activity.distance)
    move.import_date_time = datetime.now()
    move.import_module = __name__
    move.strava_activity_id = activity_id
    move.public = False
    move.source = "Strava activity id=%d; external_id='%s'" % (
        activity_id, activity.external_id)

    if streams:
        lengths = set([len(streams[stream].data) for stream in streams])
        assert len(lengths) == 1
        length, = lengths
    else:
        length = 0

    move.speed_max = move.speed_avg

    all_samples = []
    for i in range(0, length):
        time = timedelta(seconds=streams['time'].data[i])
        distance = float(streams['distance'].data[i])

        if 'heartrate' in streams:
            hr = float(streams['heartrate'].data[i])
        else:
            hr = None

        if 'latlng' in streams:
            lat, lng = streams['latlng'].data[i]
        else:
            lat = None
            lng = None

        if 'altitude' in streams:
            altitude = float(streams['altitude'].data[i])
        else:
            altitude = None

        if 'velocity_smooth' in streams:
            speed = float(streams['velocity_smooth'].data[i])
        else:
            speed = None

        if 'temp' in streams:
            temperature = celcius_to_kelvin(streams['temp'].data[i])
        else:
            temperature = None

        sample = Sample()
        sample.sample_type = SAMPLE_TYPE
        sample.move = move
        sample.time = time
        sample.utc = (activity.start_date + time).replace(tzinfo=None)
        sample.distance = distance
        sample.latitude = degree_to_radian(lat)
        sample.longitude = degree_to_radian(lng)
        sample.hr = heart_rate(hr)
        sample.temperature = temperature
        sample.speed = speed
        sample.altitude = altitude
        move.speed_max = max(move.speed_max, speed)
        all_samples.append(sample)

    derive_move_infos_from_samples(move, all_samples)

    db.session.add(move)
    db.session.flush()
    postprocess_move(move)
    db.session.commit()
    return move
Example #4
0
def parse_samples(tree, move, gpx_namespace, import_options):
    all_samples = []

    tracks = tree.iterchildren(tag=gpx_namespace + GPX_TRK)
    for track in tracks:
        track_samples = []

        track_segments = track.iterchildren(tag=gpx_namespace + GPX_TRKSEG)
        for track_segment in track_segments:
            segment_samples = []

            track_points = track_segment.iterchildren(tag=gpx_namespace + GPX_TRKPT)
            for track_point in track_points:
                sample = Sample()
                sample.move = move

                # GPS position / altitude
                sample.latitude = degree_to_radian(float(track_point.attrib[GPX_TRKPT_ATTRIB_LATITUDE]))
                sample.longitude = degree_to_radian(float(track_point.attrib[GPX_TRKPT_ATTRIB_LONGITUDE]))
                sample.sample_type = GPX_SAMPLE_TYPE
                if hasattr(track_point, GPX_TRKPT_ATTRIB_ELEVATION):
                    sample.gps_altitude = float(track_point.ele)
                    sample.altitude = int(round(sample.gps_altitude))

                # Time / UTC
                sample.utc = dateutil.parser.parse(str(track_point.time))

                # Option flags
                pause_detected = False

                # Track segment samples
                if len(segment_samples) > 0:
                    # Accumulate time delta to previous sample to get the total duration
                    time_delta = sample.utc - segment_samples[-1].utc
                    sample.time = segment_samples[-1].time + time_delta

                    # Accumulate distance to previous sample
                    distance_delta = vincenty((radian_to_degree(sample.latitude), radian_to_degree(sample.longitude)),
                                              (radian_to_degree(segment_samples[-1].latitude), radian_to_degree(segment_samples[-1].longitude))).meters

                    sample.distance = segment_samples[-1].distance + distance_delta
                    if time_delta > timedelta(0):
                        sample.speed = distance_delta / time_delta.total_seconds()
                    else:
                        sample.speed = 0

                    # Option: Pause detection based on time delta threshold
                    if GPX_IMPORT_OPTION_PAUSE_DETECTION in import_options and time_delta > import_options[GPX_IMPORT_OPTION_PAUSE_DETECTION]:
                        pause_detected = True
                        sample.distance = segment_samples[-1].distance
                        sample.speed = 0

                # Track segment -> Track (multiple track segments contained)
                elif len(track_samples) > 0:
                    sample.time = track_samples[-1].time + (sample.utc - track_samples[-1].utc)  # Time diff to last sample of the previous track segment
                    sample.distance = track_samples[-1].distance
                    sample.speed = 0
                # Track -> Full GPX (multiple tracks contained)
                elif len(all_samples) > 0:
                    sample.time = all_samples[-1].time + (sample.utc - all_samples[-1].utc)  # Time diff to last sample of the previous track
                    sample.distance = all_samples[-1].distance
                    sample.speed = 0
                # First sample
                else:
                    sample.time = timedelta(0)
                    sample.distance = 0
                    sample.speed = 0

                parse_sample_extensions(sample, track_point)
                segment_samples.append(sample)

                # Finally insert a found pause based on time delta threshold
                if pause_detected:
                    insert_pause(segment_samples, len(segment_samples) - 1, move, pause_type=GPX_IMPORT_PAUSE_TYPE_PAUSE_DETECTION)
            # end for track_points

            # Insert an pause event between every track segment
            insert_pause_idx = len(track_samples)
            track_samples.extend(segment_samples)
            insert_pause(track_samples, insert_pause_idx, move, pause_type=GPX_TRKSEG)
        # end for track_segments

        # Insert an pause event between every track
        insert_pause_idx = len(all_samples)
        all_samples.extend(track_samples)
        insert_pause(all_samples, insert_pause_idx, move, pause_type=GPX_TRK)
    # end for tracks
    return all_samples
Example #5
0
def strava_import(current_user, activity_id):
    client = get_strava_client(current_user)
    activity = client.get_activity(activity_id=activity_id)
    stream_types = ['time', 'distance', 'latlng', 'temp', 'heartrate', 'velocity_smooth', 'altitude']
    streams = client.get_activity_streams(activity_id, types=stream_types)

    device_ids = [device_id for device_id, in db.session.query(func.distinct(Move.device_id))
        .join(User)
        .join(Device)
        .filter(Device.name != gpx_import.GPX_DEVICE_NAME)
        .filter(Move.user == current_user).all()]

    assert len(device_ids) == 1
    device_id = device_ids[0]

    device = db.session.query(Device).filter_by(id = device_id).one();

    activity_string = map_type(activity.type)

    result = db.session.query(Move.activity_type).filter(Move.activity == activity_string).first()
    if result:
        activity_type, = result
    else:
        activity_type = None

    move = Move()
    move.user = current_user
    move.duration = activity.elapsed_time
    move.ascent = float(activity.total_elevation_gain)
    move.speed_avg = float(activity.average_speed)
    move.hr_avg = heart_rate(activity.average_heartrate)
    move.temperature_avg = celcius_to_kelvin(activity.average_temp)
    move.device = device
    move.date_time = activity.start_date_local
    move.activity = activity_string
    move.activity_type = activity_type
    move.distance = float(activity.distance)
    move.import_date_time = datetime.now()
    move.import_module = __name__
    move.strava_activity_id = activity_id
    move.public = False
    move.source = "Strava activity id=%d; external_id='%s'" % (activity_id, activity.external_id)

    lengths = set([len(streams[stream].data) for stream in streams])
    assert len(lengths) == 1
    length, = lengths

    move.speed_max = move.speed_avg

    all_samples = []
    for i in range(0, length):
        time = timedelta(seconds=streams['time'].data[i])
        distance = float(streams['distance'].data[i])

        if 'heartrate' in streams:
            hr = float(streams['heartrate'].data[i])
        else:
            hr = None

        if 'latlng' in streams:
            lat, lng = streams['latlng'].data[i]
        else:
            lat = None
            lng = None

        if 'altitude' in streams:
            altitude = float(streams['altitude'].data[i])
        else:
            altitude = None

        if 'velocity_smooth' in streams:
            speed = float(streams['velocity_smooth'].data[i])
        else:
            speed = None

        if 'temp' in streams:
            temperature = celcius_to_kelvin(streams['temp'].data[i])
        else:
            temperature = None

        sample = Sample()
        sample.sample_type = SAMPLE_TYPE
        sample.move = move
        sample.time = time
        sample.utc = (activity.start_date + time).replace(tzinfo=None)
        sample.distance = distance
        sample.latitude = degree_to_radian(lat)
        sample.longitude = degree_to_radian(lng)
        sample.hr = heart_rate(hr)
        sample.temperature = temperature
        sample.speed = speed
        sample.altitude = altitude
        move.speed_max = max(move.speed_max, speed)
        all_samples.append(sample)

    derive_move_infos_from_samples(move, all_samples)

    db.session.add(move)
    db.session.commit()
    return move