def compute_tracks_length(tracks): """Computes the total distance of the tracks. :param tracks: List of GPX tracks :type tracks: [gpxpy.gpx.GPXTrack] :returns: Track length in meters :rtype: float """ length = 0 for track in tracks: for segment in track.segments: prev_point = None for point in segment.points: if prev_point: length += geo.length_3d((prev_point, point)) prev_point = point return length
def fill(self): """Performs the fill mode processing. Adds time and/or heart rate values. """ in_file_name = self._opts['input'] pace = self._opts.get('pace') start_time = end_time = duration_total = speed_ms = None hr = self._opts.get('hr') soft_mode = self._opts.get('soft') limit = self._opts.get('limit') # validations and variables settings if not pace and not hr: raise StravaGpxException( "ERROR: Nothing tho set (no HR or pace specified in program parameters)" ) if pace: pace_re = re.search(PACE_RE_PATTERN, pace) if not pace_re: raise StravaGpxException( "Invalid format of pace: {}. Should be in format MM:SS.". format(pace)) if not self._opts['start_time'] or not self._opts['end_time']: raise StravaGpxException( "\"start-time\" and \"end-time\" arguments must be set for filling the pace." ) # process start and end dates try: start_time = dateutil.parser.parse( self._opts.get('start_time')) except ValueError as e: raise StravaGpxException( "Invalid \"start_time\" parameter: {}".format( self._opts.get('start_time'))) try: end_time = dateutil.parser.parse(self._opts.get('end_time')) except ValueError as e: raise StravaGpxException( "Invalid \"end_time\" parameter: {}".format( self._opts.get('end_time'))) if self._opts['start_time'] >= self._opts['end_time']: raise StravaGpxException( "End date is not higher than start date.") duration_total = (end_time - start_time).total_seconds() speed_ms = 1000.0 / (int(pace_re.group(1)) * 60 + int(pace_re.group(2))) # open input file in_file = open(in_file_name, 'r') in_gpx = gpx_parse(in_file) total_length = 0 total_length_current = 0 pace_last_time = start_time moving_time = None # read and store HR input file if self._opts['hr_file']: hr_file = open(self._opts['hr_file'], 'r') hr_gpx = gpx_parse(hr_file) for track in hr_gpx.tracks: for segment in track.segments: for point in segment.points: if point.extensions: for extension_record in point.extensions: if extension_record[0].text: self._time_hr_array.append( (point.time, extension_record[0].text)) print("Stored {} point(s) with HR information from the file {}.". format(len(self._time_hr_array), self._opts['hr_file'])) # compute variables based on overall distance if pace: total_length = StravaGpxTool.compute_tracks_length(in_gpx.tracks) moving_time = total_length / speed_ms pause_time = duration_total - moving_time log.info("Moving time: {}, speed (m/s): {}, total dist: {}".format( moving_time, speed_ms, total_length)) # process all points from input file i = 0 for track in in_gpx.tracks: for segment in track.segments: prev_point = None length_from_prev = 0 current_length_for_pause = 0 for point in segment.points: duplicated_point = None if prev_point: length_from_prev = geo.length_3d((prev_point, point)) total_length_current += length_from_prev if pace: log.debug(" DISTANCE: {}".format(length_from_prev)) if length_from_prev > 0: # compute the arrival time to this point next_time = pace_last_time + datetime.timedelta( seconds=round(length_from_prev / speed_ms)) pace_last_time = min(next_time, end_time) log.debug("Time moved to: {} (after move)".format( pace_last_time)) point.time = pace_last_time # add the waiting time (proportionally from pause_time) to new duplicated point if current_length_for_pause >= PAUSE_LIMIT_METERS: next_time = pace_last_time + datetime.timedelta( seconds=round(pause_time * ( (1.0 * current_length_for_pause) / total_length))) pace_last_time = min(next_time, end_time) log.debug( "Time moved to: {} (after pause)".format( pace_last_time)) duplicated_point = deepcopy(point) duplicated_point.time = pace_last_time current_length_for_pause = 0 else: current_length_for_pause += length_from_prev else: point.time = pace_last_time elif not point.time: raise StravaGpxException( 'No pace was set, but there is no time for the point: {}' .format(point)) if hr: if point.extensions and not soft_mode: raise StravaGpxException( "Existing *extension* value found." + "Consider running with --soft parameter. Value found: {}" .format(point.extensions)) extension_element = ElementTree.Element(HR_BASE_TAG) extension_element.text = "" hr_element = ElementTree.Element(HR_TAG) hr_element.text = str( self.get_hr_for_time(point.time, hr)) extension_element.append(hr_element) point.extensions.append(extension_element) self.add_point(point) if duplicated_point: self.add_point(duplicated_point) prev_point = point i += 1 if i == limit: log.debug( "Limit of processed trackpoints ({}) reached, ending." .format(limit)) break log.info("Total distance: {}".format(total_length_current))
def running(ar, N): retval = [] for i in xrange(len(ar)): if i < N: retval += [sum(ar[0:i + N]) / len(ar[0:i + N])] elif i + N >= len(ar): retval += [sum(ar[i - N:-1]) / len(ar[i - N:-1])] else: retval += [sum(ar[i - N:i + N]) / len(ar[i - N:i + N])] return retval for p in xrange(len(firstrace.segments[0].points)): xraceone += [mod_geo.length_3d(firstrace.segments[0].points[0:p + 1])] try: hraceone += [firstrace.segments[0].points[p].extensions['hr']] xhraceone += [xraceone[-1]] except: pass yraceone += [firstrace.segments[0].points[p].elevation] traceone += [firstrace.segments[0].points[p].time] try: nt = traceone[-1] pt = traceone[-2] dt = nt - pt nx = xraceone[-1] px = xraceone[-2] ny = yraceone[-1] py = yraceone[-2]