def build_total(self, track, splits): ''' Build a total TrackSplit from a list of splits ''' total = TrackSplit(track=track, position=0) total.distance = 0 total.time = 0 for s in splits: # Update totals total.distance += s.distance total.time += s.time s.distance_total = total.distance s.time_total = total.time s.track = track s.save() logger.debug("%s split #%d added split %d"% (self.NAME, track.pk, s.position)) # Save main split nb = len(splits) total.distance_total = total.distance total.time_total = total.time if nb > 0: total.speed = sum([s.speed for s in splits]) / nb total.speed_max = min([s.speed_max for s in splits]) total.elevation_min = min([s.elevation_min for s in splits]) total.elevation_max = max([s.elevation_max for s in splits]) total.elevation_gain = sum([s.elevation_gain for s in splits]) total.elevation_loss = sum([s.elevation_loss for s in splits]) total.energy = sum([s.energy for s in splits]) if nb >= 2: start = splits[0] total.date_start = start.date_start total.position_start = start.position_start end = splits[nb - 1] total.date_end = end.date_end total.position_end = end.position_end total.save() track.split_total = total track.save() return total
def build_splits(self, activity): # Load details details = self.get_file(activity, 'details', format_json=True) if 'splits_metric' not in details: return [] # Import every metric split out = [] for s in details['splits_metric']: split = TrackSplit(position=s['split']) split.time = s['elapsed_time'] split.distance = s['distance'] if split.time > 0: split.speed = split.distance / split.time if s['elevation_difference'] > 0: split.elevation_gain = s['elevation_difference'] else: split.elevation_loss = abs(s['elevation_difference']) out.append(split) return out
def build_splits(self, activity): # Load laps laps = self.get_file(activity, 'laps', format_json=True) if not laps or 'activity' not in laps or 'totalLaps' not in laps['activity']: return [] laps = laps['activity']['totalLaps']['lapSummaryList'] def _convert_speed(lap, name): # Convert a speed in m/s if name not in lap: return 0.0 s = lap[name] if s['uom'] == 'kph': return float(s['value']) / 3.6 if s['uom'] == 'hmph': # hetcometer per hour return float(s['value']) / 36 return float(s['value']) def _convert_distance(lap, name): # Convert a distance in meters if name not in lap: return 0.0 d = lap[name] if d['uom'] == 'kilometer': return float(d['value']) * 1000.0 return float(d['value']) def _convert_date(lap, name): # Convert a timestamp to a datetime if name not in lap: return 0.0 d = lap[name] tz_name = d['uom'] == 'gmt' and 'Etc/GMT' or d['uom'] tz = pytz.timezone(tz_name) return make_aware(datetime.fromtimestamp(float(d['value']) / 1000.0), tz) def _convert_point(lap, name_lat, name_lng): # Build a point from lat,lng if name_lat not in lap or name_lng not in lap: return None return Point(float(lap[name_lat]['value']), float(lap[name_lng]['value'])) def _convert_float(lap, name): # Convert to float a value if name not in lap: return 0.0 return float(lap[name]['value']) # Build every split out = [] for i, lap in enumerate(laps): split = TrackSplit(position=i+1) split.elevation_min = _convert_float(lap, 'MinElevation') split.elevation_max = _convert_float(lap, 'MaxElevation') split.elevation_gain = _convert_float(lap, 'GainElevation') split.elevation_loss = _convert_float(lap, 'LossElevation') split.speed_max = _convert_speed(lap, 'MaxSpeed') split.speed = _convert_speed(lap, 'WeightedMeanSpeed') split.distance = _convert_distance(lap, 'SumDistance') split.time = _convert_float(lap, 'SumDuration') split.energy = _convert_float(lap, 'SumEnergy') split.date_start = _convert_date(lap, 'BeginTimestamp') split.date_end = _convert_date(lap, 'EndTimestamp') split.position_start = _convert_point(lap, 'BeginLatitude', 'BeginLongitude') split.position_end = _convert_point(lap, 'EndLatitude', 'EndLongitude') out.append(split) return out
def build_total(self, track, splits): ''' Build a total TrackSplit from a list of splits ''' total = TrackSplit(position=0) total.track_id = track.pk total.distance = 0 total.time = 0 # List all current splits per positions positions = dict([(s['position'], s['pk']) for s in track.splits.values('pk', 'position')]) positions_updated = [] for s in splits: # Update totals total.distance += s.distance total.time += s.time s.distance_total = total.distance s.time_total = total.time # Update existing split ? if s.position in positions: s.id = positions[s.position] positions_updated.append(s.position) s.track_id = track.pk s.save() logger.debug("%s track #%d added split %d"% (self.NAME, s.track_id, s.position)) # Save main split nb = len(splits) total.distance_total = total.distance total.time_total = total.time if nb > 0: total.speed = sum([s.speed for s in splits]) / nb total.speed_max = min([s.speed_max for s in splits]) total.elevation_min = min([s.elevation_min for s in splits]) total.elevation_max = max([s.elevation_max for s in splits]) total.elevation_gain = sum([s.elevation_gain for s in splits]) total.elevation_loss = sum([s.elevation_loss for s in splits]) total.energy = sum([s.energy for s in splits]) if nb >= 2: start = splits[0] total.date_start = start.date_start total.position_start = start.position_start end = splits[nb - 1] total.date_end = end.date_end total.position_end = end.position_end # Update total split ? total_pk = positions.get(0) if total_pk: total.pk = total_pk positions_updated.append(0) total.save() track.split_total = total track.save() # Cleanup useless splits diff = set(positions.keys()).difference(positions_updated) if positions and diff: logger.debug('Cleanup splits on positions %s' % diff) track.splits.filter(position__in=diff).delete() return total