Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-gpxpy for openSUSE:Factory checked in at 2022-09-29 18:14:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-gpxpy (Old) and /work/SRC/openSUSE:Factory/.python-gpxpy.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-gpxpy" Thu Sep 29 18:14:08 2022 rev:6 rq:1006891 version:1.5.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-gpxpy/python-gpxpy.changes 2021-06-01 10:38:50.880954656 +0200 +++ /work/SRC/openSUSE:Factory/.python-gpxpy.new.2275/python-gpxpy.changes 2022-09-29 18:15:03.199454347 +0200 @@ -1,0 +2,11 @@ +Wed Sep 28 21:49:42 UTC 2022 - Yogalakshmi Arunachalam <[email protected]> + +- v1.5.0 + * Typos #239 + * Number formating bug #230 + * Add python 3.9 in travis #214 + * Option to get raw speed data + * missing valid option for type of gpx speed ('3') + * Added type definitions + +------------------------------------------------------------------- Old: ---- gpxpy-1.4.2.tar.gz New: ---- gpxpy-1.5.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-gpxpy.spec ++++++ --- /var/tmp/diff_new_pack.aSoMW1/_old 2022-09-29 18:15:03.735455399 +0200 +++ /var/tmp/diff_new_pack.aSoMW1/_new 2022-09-29 18:15:03.751455429 +0200 @@ -1,7 +1,7 @@ # # spec file for package python-gpxpy # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-gpxpy -Version: 1.4.2 +Version: 1.5.0 Release: 0 Summary: GPX file parser and GPS track manipulation library License: Apache-2.0 ++++++ gpxpy-1.4.2.tar.gz -> gpxpy-1.5.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/PKG-INFO new/gpxpy-1.5.0/PKG-INFO --- old/gpxpy-1.4.2/PKG-INFO 2020-06-22 08:57:48.000000000 +0200 +++ new/gpxpy-1.5.0/PKG-INFO 2021-11-04 18:42:20.972627200 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: gpxpy -Version: 1.4.2 +Version: 1.5.0 Summary: GPX file parser and GPS track manipulation library Home-page: https://github.com/tkrajina/gpxpy Author: Tomo Krajina @@ -92,6 +92,14 @@ The GPX version is automatically determined when parsing by reading the version attribute in the gpx node. If this attribute is not present then the version is assumed to be 1.0. A specific version can be forced by setting the `version` parameter in the parse function. Possible values for the 'version' parameter are `1.0`, `1.1` and `None`. + ## GPX max speed + + Gpxpy is a GPX parser and by using it you have access to all the data from the original GPX file. The additional methods to calculate stats have some additional heuristics to remove common GPS errors. For example, to calculate `max_speed` it removes the top `5%` of speeds and points with nonstandard distance (those are usually GPS errors). + + "Raw" max speed can be calculated with: + + moving_data = gpx.get_moving_data(raw=True) + ## Pull requests Branches: @@ -111,22 +119,13 @@ Gpxpy runs only with python 3.6+. The code must have type hints and must pass all the mypy checks. - ## GPXInfo + ## GPX tools - The repository contains a little command line utility to extract basic statistics from a file. - Example usage: + Additional command-line tools for GPX files can be downloaded here <https://github.com/tkrajina/gpx-cmd-tools> or installed with: - $ gpxinfo voznjica.gpx - File: voznjica.gpx - Length 2D: 63.6441229018 - Length 3D: 63.8391428454 - Moving time: 02:56:03 - Stopped time: 00:21:38 - Max speed: 14.187909492m/s = 51.0764741713km/h - Total uphill: 1103.1626183m - Total downhill: 1087.7812703m - Started: 2013-06-01 06:46:53 - Ended: 2013-06-01 10:23:45 + ``` + pip install gpx-cmd-tools + ``` ## License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/README.md new/gpxpy-1.5.0/README.md --- old/gpxpy-1.4.2/README.md 2020-05-16 08:46:48.000000000 +0200 +++ new/gpxpy-1.5.0/README.md 2021-11-04 18:37:32.000000000 +0100 @@ -84,6 +84,14 @@ The GPX version is automatically determined when parsing by reading the version attribute in the gpx node. If this attribute is not present then the version is assumed to be 1.0. A specific version can be forced by setting the `version` parameter in the parse function. Possible values for the 'version' parameter are `1.0`, `1.1` and `None`. +## GPX max speed + +Gpxpy is a GPX parser and by using it you have access to all the data from the original GPX file. The additional methods to calculate stats have some additional heuristics to remove common GPS errors. For example, to calculate `max_speed` it removes the top `5%` of speeds and points with nonstandard distance (those are usually GPS errors). + +"Raw" max speed can be calculated with: + + moving_data = gpx.get_moving_data(raw=True) + ## Pull requests Branches: @@ -103,22 +111,13 @@ Gpxpy runs only with python 3.6+. The code must have type hints and must pass all the mypy checks. -## GPXInfo +## GPX tools -The repository contains a little command line utility to extract basic statistics from a file. -Example usage: +Additional command-line tools for GPX files can be downloaded here <https://github.com/tkrajina/gpx-cmd-tools> or installed with: - $ gpxinfo voznjica.gpx - File: voznjica.gpx - Length 2D: 63.6441229018 - Length 3D: 63.8391428454 - Moving time: 02:56:03 - Stopped time: 00:21:38 - Max speed: 14.187909492m/s = 51.0764741713km/h - Total uphill: 1103.1626183m - Total downhill: 1087.7812703m - Started: 2013-06-01 06:46:53 - Ended: 2013-06-01 10:23:45 +``` +pip install gpx-cmd-tools +``` ## License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/gpxinfo new/gpxpy-1.5.0/gpxinfo --- old/gpxpy-1.4.2/gpxinfo 2020-06-17 07:01:30.000000000 +0200 +++ new/gpxpy-1.5.0/gpxinfo 2021-11-04 18:37:32.000000000 +0100 @@ -64,12 +64,12 @@ print('%sLength 3D: %s' % (indentation, format_long_length(length_3d))) moving_data = gpx_part.get_moving_data() + raw_moving_data = gpx_part.get_moving_data(raw=True) if moving_data: - print('%sMoving time: %s' % (indentation, format_time(moving_data.moving_time))) - print('%sStopped time: %s' % (indentation, format_time(moving_data.stopped_time))) - #print('%sStopped distance: %s' % (indentation, format_short_length(stopped_distance))) - print('%sMax speed: %s' % (indentation, format_speed(moving_data.max_speed))) - print('%sAvg speed: %s' % (indentation, format_speed(moving_data.moving_distance / moving_data.moving_time) if moving_data.moving_time > 0 else "?")) + print(f'{indentation}Moving time: {format_time(moving_data.moving_time)}') + print(f'{indentation}Stopped time: {format_time(moving_data.stopped_time)}') + print(f'{indentation}Max speed: {format_speed(moving_data.max_speed)} (raw: {format_speed(raw_moving_data.max_speed) if raw_moving_data else "?"})') + print(f'{indentation}Avg speed: {format_speed(moving_data.moving_distance / moving_data.moving_time) if moving_data.moving_time > 0 else "?"}') uphill, downhill = gpx_part.get_uphill_downhill() print('%sTotal uphill: %s' % (indentation, format_short_length(uphill))) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/gpxpy/__init__.py new/gpxpy-1.5.0/gpxpy/__init__.py --- old/gpxpy-1.4.2/gpxpy/__init__.py 2020-06-22 08:57:11.000000000 +0200 +++ new/gpxpy-1.5.0/gpxpy/__init__.py 2021-11-04 18:42:01.000000000 +0100 @@ -16,7 +16,7 @@ from . import gpx as mod_gpx -__version__ = '1.4.2' +__version__ = '1.5.0' def parse(xml_or_file: Union[AnyStr, IO[str]], version: Optional[str] = None) -> mod_gpx.GPX: """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/gpxpy/geo.py new/gpxpy-1.5.0/gpxpy/geo.py --- old/gpxpy-1.4.2/gpxpy/geo.py 2020-05-13 12:02:43.000000000 +0200 +++ new/gpxpy-1.5.0/gpxpy/geo.py 2021-11-04 18:37:32.000000000 +0100 @@ -120,7 +120,7 @@ return length(locations, True) -def calculate_max_speed(speeds_and_distances: List[Tuple[float, float]]) -> Optional[float]: +def calculate_max_speed(speeds_and_distances: List[Tuple[float, float]], extreemes_percentile: float, ignore_nonstandard_distances: bool) -> Optional[float]: """ Compute average distance and standard deviation for distance. Extremes in distances are usually extremes in speeds, so we will ignore them, @@ -128,6 +128,9 @@ speeds_and_distances must be a list containing pairs of (speed, distance) for every point in a track segment. + + In many cases the top speeds are measurement errors. For that reason extreme speeds can be removed + with the extreemes_percentile (for example, a value of 0.05 will remove top 5%). """ assert speeds_and_distances if len(speeds_and_distances) > 0: @@ -135,29 +138,30 @@ # ... assert len(speeds_and_distances[-1]) == 2 + if not ignore_nonstandard_distances: + return max(x[0] or 0 for x in speeds_and_distances) + size = len(speeds_and_distances) - if size < 20: - log.debug('Segment too small to compute speed, size=%s', size) + if size < 2: + # log.debug('Segment too small to compute speed, size=%s', size) return None - distances = list(map(lambda x: x[1], speeds_and_distances)) + distances = [x[1] for x in speeds_and_distances] average_distance = sum(distances) / float(size) - standard_distance_deviation = mod_math.sqrt(sum(map(lambda distance: (distance-average_distance)**2, distances))/float(size)) + standard_distance_deviation = mod_math.sqrt(sum((distance - average_distance) ** 2 for distance in distances) / float(size)) # Ignore items where the distance is too big: - filtered_speeds_and_distances = filter(lambda speed_and_distance: abs(speed_and_distance[1] - average_distance) <= standard_distance_deviation * 1.5, speeds_and_distances) + filtered_speeds_and_distances = [x for x in speeds_and_distances if abs(x[1] - average_distance) <= standard_distance_deviation * 1.5] # sort by speed: - speeds = list(map(lambda speed_and_distance: speed_and_distance[0], filtered_speeds_and_distances)) - if not isinstance(speeds, list): # python3 - speeds = list(speeds) + speeds = [x[0] for x in filtered_speeds_and_distances] if not speeds: return None speeds.sort() # Even here there may be some extremes => ignore the last 5%: - index = int(len(speeds) * 0.95) + index = int(len(speeds) * (1-extreemes_percentile)) if index >= len(speeds): index = -1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/gpxpy/gpx.py new/gpxpy-1.5.0/gpxpy/gpx.py --- old/gpxpy-1.4.2/gpxpy/gpx.py 2020-06-22 08:55:50.000000000 +0200 +++ new/gpxpy-1.5.0/gpxpy/gpx.py 2021-11-04 18:37:32.000000000 +0100 @@ -30,6 +30,8 @@ log = mod_logging.getLogger(__name__) +IGNORE_TOP_SPEED_PERCENTILES = 0.05 + # GPX date format to be used when writing the GPX output: DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ' @@ -63,7 +65,7 @@ mod_gpxfield.GPXField('link_text', 'urlname'), mod_gpxfield.GPXField('symbol', 'sym'), mod_gpxfield.GPXField('type'), - mod_gpxfield.GPXField('type_of_gpx_fix', 'fix', possible=('none', '2d', '3d', 'dgps', 'pps',)), + mod_gpxfield.GPXField('type_of_gpx_fix', 'fix', possible=('none', '2d', '3d', 'dgps', 'pps', '3',)), mod_gpxfield.GPXField('satellites', 'sat', type=mod_gpxfield.INT_TYPE), mod_gpxfield.GPXField('horizontal_dilution', 'hdop', type=mod_gpxfield.FLOAT_TYPE), mod_gpxfield.GPXField('vertical_dilution', 'vdop', type=mod_gpxfield.FLOAT_TYPE), @@ -90,7 +92,7 @@ '/link', mod_gpxfield.GPXField('symbol', 'sym'), mod_gpxfield.GPXField('type'), - mod_gpxfield.GPXField('type_of_gpx_fix', 'fix', possible=('none', '2d', '3d', 'dgps', 'pps',)), + mod_gpxfield.GPXField('type_of_gpx_fix', 'fix', possible=('none', '2d', '3d', 'dgps', 'pps', '3',)), mod_gpxfield.GPXField('satellites', 'sat', type=mod_gpxfield.INT_TYPE), mod_gpxfield.GPXField('horizontal_dilution', 'hdop', type=mod_gpxfield.FLOAT_TYPE), mod_gpxfield.GPXField('vertical_dilution', 'vdop', type=mod_gpxfield.FLOAT_TYPE), @@ -834,7 +836,7 @@ self.points += track_segment.points def remove_point(self, point_no: int) -> None: - """ Removes a point specificed by index from the segment """ + """ Removes a point specified by index from the segment """ if point_no < 0 or point_no >= len(self.points): return @@ -843,7 +845,7 @@ self.points = part_1 + part_2 - def get_moving_data(self, stopped_speed_threshold: Optional[float]=None) -> Optional[MovingData]: + def get_moving_data(self, stopped_speed_threshold: Optional[float]=None, raw: bool=False, speed_extreemes_percentiles: float=IGNORE_TOP_SPEED_PERCENTILES, ignore_nonstandard_distances: bool = True) -> Optional[MovingData]: """ Return a tuple of (moving_time, stopped_time, moving_distance, stopped_distance, max_speed) that may be used for detecting the time @@ -876,6 +878,10 @@ if not stopped_speed_threshold: stopped_speed_threshold = DEFAULT_STOPPED_SPEED_THRESHOLD + if raw: + speed_extreemes_percentiles=0 + ignore_nonstandard_distances=False + moving_time = 0. stopped_time = 0. @@ -917,7 +923,7 @@ max_speed = None if speeds_and_distances: - max_speed = mod_geo.calculate_max_speed(speeds_and_distances) + max_speed = mod_geo.calculate_max_speed(speeds_and_distances, speed_extreemes_percentiles, ignore_nonstandard_distances) return MovingData(moving_time, stopped_time, moving_distance, stopped_distance, max_speed or 0.0) @@ -1103,9 +1109,8 @@ assert len(interval) == len(distances) - return list(map( - lambda distance: (distance / from_start_to_end) if from_start_to_end else 0, - distances)) + return [(distance / from_start_to_end) if from_start_to_end else 0 + for distance in distances] def get_duration(self) -> Optional[float]: """ @@ -1155,7 +1160,7 @@ if not self.points: return UphillDownhill(0, 0) - elevations = list(map(lambda point: point.elevation, self.points)) + elevations = [point.elevation for point in self.points] uphill, downhill = mod_geo.calculate_uphill_downhill(elevations) return UphillDownhill(uphill, downhill) @@ -1175,12 +1180,10 @@ if not self.points: return MinimumMaximum(None, None) - elevations = map(lambda location: location.elevation, self.points) - elevations = filter(lambda elevation: elevation is not None, elevations) - l = list(elevations) - if len(l) == 0: + elevations = [x.elevation for x in self.points if x.elevation is not None] + if not elevations: return MinimumMaximum(None, None) - return MinimumMaximum(min(l), max(l)) + return MinimumMaximum(min(elevations), max(elevations)) def get_location_at(self, time: mod_datetime.datetime) -> Optional[GPXTrackPoint]: """ @@ -1559,7 +1562,7 @@ point : GPXTrackPoint Point in the track segment_no : integer - Index of segment containint point. This is suppressed if only_points + Index of segment containing point. This is suppressed if only_points is True. point_no : integer Index of point. This is suppressed if only_points is True. @@ -1664,7 +1667,7 @@ new_segments.append(segment) self.segments = new_segments - def get_moving_data(self, stopped_speed_threshold: Optional[float]=None) -> MovingData: + def get_moving_data(self, stopped_speed_threshold: Optional[float]=None, raw: bool=False, speed_extreemes_percentiles: float=IGNORE_TOP_SPEED_PERCENTILES, ignore_nonstandard_distances: bool = True) -> MovingData: """ Return a tuple of (moving_time, stopped_time, moving_distance, stopped_distance, max_speed) that may be used for detecting the time @@ -1703,7 +1706,7 @@ max_speed = 0. for segment in self.segments: - moving_data = segment.get_moving_data(stopped_speed_threshold) + moving_data = segment.get_moving_data(stopped_speed_threshold, raw, speed_extreemes_percentiles, ignore_nonstandard_distances) if moving_data: moving_time += moving_data.moving_time stopped_time += moving_data.stopped_time @@ -2198,7 +2201,7 @@ for track in self.tracks: track.remove_empty() - def get_moving_data(self, stopped_speed_threshold: Optional[float]=None) -> MovingData: + def get_moving_data(self, stopped_speed_threshold: Optional[float]=None, raw: bool=False, speed_extreemes_percentiles: float=IGNORE_TOP_SPEED_PERCENTILES, ignore_nonstandard_distances: bool=True) -> MovingData: """ Return a tuple of (moving_time, stopped_time, moving_distance, stopped_distance, max_speed) that may be used for detecting the time stopped, and max speed. Not that those values are not @@ -2227,7 +2230,7 @@ max_speed = 0. for track in self.tracks: - track_moving_time, track_stopped_time, track_moving_distance, track_stopped_distance, track_max_speed = track.get_moving_data(stopped_speed_threshold) + track_moving_time, track_stopped_time, track_moving_distance, track_stopped_distance, track_max_speed = track.get_moving_data(stopped_speed_threshold, raw=raw, speed_extreemes_percentiles=speed_extreemes_percentiles, ignore_nonstandard_distances=ignore_nonstandard_distances) moving_time += track_moving_time stopped_time += track_stopped_time moving_distance += track_moving_distance @@ -2306,10 +2309,10 @@ point : GPXTrackPoint Point in the track track_no : integer - Index of track containint point. This is suppressed if only_points + Index of track containing point. This is suppressed if only_points is True. segment_no : integer - Index of segment containint point. This is suppressed if only_points + Index of segment containing point. This is suppressed if only_points is True. point_no : integer Index of point. This is suppressed if only_points is True. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/gpxpy/gpxfield.py new/gpxpy-1.5.0/gpxpy/gpxfield.py --- old/gpxpy-1.4.2/gpxpy/gpxfield.py 2020-05-10 18:24:26.000000000 +0200 +++ new/gpxpy-1.5.0/gpxpy/gpxfield.py 2021-11-04 18:37:32.000000000 +0100 @@ -90,7 +90,7 @@ def format_time(time: mod_datetime.datetime) -> str: offset = time.utcoffset() - if not offset or offset == 0: + if not offset: tz = 'Z' else: tz = time.strftime('%z') @@ -166,11 +166,13 @@ if tag and attribute: from . import gpx as mod_gpx raise mod_gpx.GPXException('Only tag *or* attribute may be given!') + + self.tag: Optional[str] = None if attribute: self.tag = None self.attribute = attribute elif tag: - self.tag = name if tag is True else tag + self.tag = name if (tag is True) else tag # type: ignore self.attribute = None else: self.tag = name @@ -603,9 +605,9 @@ instance = classs() try: - attributes = list(filter(lambda x : x[0] != '_', dir(instance))) - attributes = list(filter(lambda x : not callable(getattr(instance, x)), attributes)) - attributes = list(filter(lambda x : not x.startswith('gpx_'), attributes)) + attributes = [x for x in dir(instance) + if not x.startswith(('_', 'gpx_')) + and not callable(getattr(instance, x))] except Exception as e: raise Exception(f'Error reading attributes for {classs.__name__}: {e}') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/gpxpy/gpxxml.py new/gpxpy-1.5.0/gpxpy/gpxxml.py --- old/gpxpy-1.4.2/gpxpy/gpxxml.py 2020-05-10 18:24:26.000000000 +0200 +++ new/gpxpy-1.5.0/gpxpy/gpxxml.py 2021-11-04 18:37:32.000000000 +0100 @@ -1,4 +1,4 @@ -import xml.dom.minidom as mod_minidom # type: ignore +import xml.dom.minidom as mod_minidom from typing import Any, AnyStr, Iterable diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/gpxpy/utils.py new/gpxpy-1.5.0/gpxpy/utils.py --- old/gpxpy-1.4.2/gpxpy/utils.py 2020-05-16 08:48:16.000000000 +0200 +++ new/gpxpy-1.5.0/gpxpy/utils.py 2021-11-04 18:37:32.000000000 +0100 @@ -81,5 +81,5 @@ if not 'e' in result: return result # scientific notation is illegal in GPX 1/1 - return format(s, '.10f').rstrip('0.') + return format(s, '.10f').rstrip('0').rstrip('.') return str(s) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/gpxpy.egg-info/PKG-INFO new/gpxpy-1.5.0/gpxpy.egg-info/PKG-INFO --- old/gpxpy-1.4.2/gpxpy.egg-info/PKG-INFO 2020-06-22 08:57:48.000000000 +0200 +++ new/gpxpy-1.5.0/gpxpy.egg-info/PKG-INFO 2021-11-04 18:42:20.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: gpxpy -Version: 1.4.2 +Version: 1.5.0 Summary: GPX file parser and GPS track manipulation library Home-page: https://github.com/tkrajina/gpxpy Author: Tomo Krajina @@ -92,6 +92,14 @@ The GPX version is automatically determined when parsing by reading the version attribute in the gpx node. If this attribute is not present then the version is assumed to be 1.0. A specific version can be forced by setting the `version` parameter in the parse function. Possible values for the 'version' parameter are `1.0`, `1.1` and `None`. + ## GPX max speed + + Gpxpy is a GPX parser and by using it you have access to all the data from the original GPX file. The additional methods to calculate stats have some additional heuristics to remove common GPS errors. For example, to calculate `max_speed` it removes the top `5%` of speeds and points with nonstandard distance (those are usually GPS errors). + + "Raw" max speed can be calculated with: + + moving_data = gpx.get_moving_data(raw=True) + ## Pull requests Branches: @@ -111,22 +119,13 @@ Gpxpy runs only with python 3.6+. The code must have type hints and must pass all the mypy checks. - ## GPXInfo + ## GPX tools - The repository contains a little command line utility to extract basic statistics from a file. - Example usage: + Additional command-line tools for GPX files can be downloaded here <https://github.com/tkrajina/gpx-cmd-tools> or installed with: - $ gpxinfo voznjica.gpx - File: voznjica.gpx - Length 2D: 63.6441229018 - Length 3D: 63.8391428454 - Moving time: 02:56:03 - Stopped time: 00:21:38 - Max speed: 14.187909492m/s = 51.0764741713km/h - Total uphill: 1103.1626183m - Total downhill: 1087.7812703m - Started: 2013-06-01 06:46:53 - Ended: 2013-06-01 10:23:45 + ``` + pip install gpx-cmd-tools + ``` ## License diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/gpxpy.egg-info/SOURCES.txt new/gpxpy-1.5.0/gpxpy.egg-info/SOURCES.txt --- old/gpxpy-1.4.2/gpxpy.egg-info/SOURCES.txt 2020-06-22 08:57:48.000000000 +0200 +++ new/gpxpy-1.5.0/gpxpy.egg-info/SOURCES.txt 2021-11-04 18:42:20.000000000 +0100 @@ -11,12 +11,14 @@ gpxpy/gpxfield.py gpxpy/gpxxml.py gpxpy/parser.py +gpxpy/py.typed gpxpy/utils.py gpxpy.egg-info/PKG-INFO gpxpy.egg-info/SOURCES.txt gpxpy.egg-info/dependency_links.txt gpxpy.egg-info/top_level.txt test_files/Mojstrovka.gpx +test_files/around-visnjan-with-car.gpx test_files/cerknicko-jezero-no-creator.gpx test_files/cerknicko-jezero-with-elevations-zero.gpx test_files/cerknicko-jezero-without-elevations.gpx diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/setup.py new/gpxpy-1.5.0/setup.py --- old/gpxpy-1.4.2/setup.py 2020-06-17 07:01:30.000000000 +0200 +++ new/gpxpy-1.5.0/setup.py 2021-11-03 17:24:26.000000000 +0100 @@ -35,6 +35,7 @@ author='Tomo Krajina', author_email='[email protected]', url='https://github.com/tkrajina/gpxpy', + package_data={"gpxpy": ["py.typed"]}, packages=['gpxpy', ], python_requires=">=3.6", classifiers=[ @@ -43,5 +44,5 @@ "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", ], - scripts=['gpxinfo'] + scripts=['gpxinfo'], ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/test.py new/gpxpy-1.5.0/test.py --- old/gpxpy-1.4.2/test.py 2020-06-22 08:55:50.000000000 +0200 +++ new/gpxpy-1.5.0/test.py 2021-11-04 18:37:32.000000000 +0100 @@ -34,7 +34,7 @@ import math as mod_math import sys as mod_sys import unittest as mod_unittest -import xml.dom.minidom as mod_minidom # type: ignore +import xml.dom.minidom as mod_minidom try: # Load LXML or fallback to cET or ET @@ -101,8 +101,8 @@ return True -def cca(number1: float, number2: float) -> bool: - return 1 - number1 / number2 < 0.999 +def almostEqual(number1: float, number2: float) -> bool: + return 1 - number1 / number2 < 0.999999 def get_dom_node(dom: Any, path: str) -> Any: @@ -887,6 +887,40 @@ self.assertEqual(gpx.tracks[0].segments[0].points[1].speed, 2.2) self.assertEqual(gpx.tracks[0].segments[0].points[2].speed, 3.2) + def test_speed_ignore_top_speed_percentiles(self) -> None: + gpx = self.parse('cerknicko-jezero-with-elevations-zero.gpx') + + moving_data_1 = gpx.get_moving_data() + moving_data_2 = gpx.get_moving_data(speed_extreemes_percentiles=0.05) + self.assertEqual(moving_data_1.max_speed, moving_data_2.max_speed) + + for i in range(0, 11, 1): + data_1 = gpx.get_moving_data(speed_extreemes_percentiles=0.1*(i-1)) + data_2 = gpx.get_moving_data(speed_extreemes_percentiles=0.1*i) + print(0.1*i, data_2.max_speed) + self.assertTrue(data_1.max_speed >= data_2.max_speed) + + def test_raw_max_speed(self) -> None: + for gpx_file in ("around-visnjan-with-car.gpx", "korita-zbevnica.gpx"): + gpx = self.parse(gpx_file) + + raw_moving_data = gpx.get_moving_data(speed_extreemes_percentiles=0, ignore_nonstandard_distances=False) + + max_speed = 0.0 + for track in gpx.tracks: + for segment in track.segments: + for pt_no, pt in enumerate(segment.points): + if pt_no > 0: + speed = segment.points[pt_no].speed_between(segment.points[pt_no - 1]) + #print(speed) + if speed: + max_speed = max(speed, max_speed) + print(max_speed) + + print("raw=", raw_moving_data.max_speed) + print("calculated=", max_speed) + self.assertEqual(max_speed, raw_moving_data.max_speed) + def test_dilutions(self) -> None: gpx = self.parse('track_with_dilution_errors.gpx') gpx2 = self.reparse(gpx) @@ -896,7 +930,6 @@ self.assertTrue(equals(gpx.tracks, gpx2.tracks)) self.assertTrue(equals(gpx, gpx2)) - for test_gpx in (gpx, gpx2): self.assertTrue(test_gpx.waypoints[0].horizontal_dilution == 100.1) self.assertTrue(test_gpx.waypoints[0].vertical_dilution == 101.1) @@ -1288,7 +1321,7 @@ # Too few points: mod_logging.debug('max_speed = %s', max_speed_with_too_small_segment) - self.assertFalse(max_speed_with_too_small_segment) + self.assertTrue(max_speed_with_too_small_segment > 0) tmp_longitude = 0. segment_2 = mod_gpx.GPXTrackSegment() @@ -1674,7 +1707,7 @@ #'-2001-10-26T21:32:52', '2001-10-26T21:32:52.12679', ] - timestamps_without_tz = list(map(lambda x: x.replace('T', ' ').replace('Z', ''), timestamps)) + timestamps_without_tz = [x.replace('T', ' ').replace('Z', '') for x in timestamps] for t in timestamps_without_tz: timestamps.append(t) for timestamp in timestamps: @@ -1779,7 +1812,7 @@ location = mod_geo.Location(-20, -50) location_2 = location + mod_geo.LocationDelta(angle=45, distance=100) - self.assertTrue(cca(location_2.latitude - location.latitude, location_2.longitude - location.longitude)) + self.assertTrue(almostEqual(location_2.latitude - location.latitude, location_2.longitude - location.longitude)) def test_location_equator_delta_distance_111120(self) -> None: self.__test_location_delta(mod_geo.Location(0, 13), 111120) @@ -1799,8 +1832,8 @@ location_2 = location + delta location.move(delta) - self.assertTrue(cca(location.latitude, location_2.latitude)) - self.assertTrue(cca(location.longitude, location_2.longitude)) + self.assertTrue(almostEqual(location.latitude, location_2.latitude)) + self.assertTrue(almostEqual(location.longitude, location_2.longitude)) def test_parse_gpx_with_node_with_comments(self) -> None: with open('test_files/gpx-with-node-with-comments.gpx') as f: @@ -1817,7 +1850,7 @@ for angle in angles: new_location = location + mod_geo.LocationDelta(angle=angle, distance=distance) # All locations same distance from center - self.assertTrue(cca(location.distance_2d(new_location), distance)) # type: ignore + self.assertTrue(almostEqual(location.distance_2d(new_location), distance)) # type: ignore if previous_location: distances_between_points.append(new_location.distance_2d(previous_location)) previous_location = new_location @@ -1825,7 +1858,7 @@ print(distances_between_points) # All points should be equidistant on a circle: for i in range(1, len(distances_between_points)): - self.assertTrue(cca(distances_between_points[0], distances_between_points[i])) + self.assertTrue(almostEqual(distances_between_points[0], distances_between_points[i])) def test_gpx_10_fields(self) -> None: """ Test (de) serialization all gpx1.0 fields """ @@ -3428,6 +3461,23 @@ self.assertEqual(35, gpx.tracks[0].segments[0].points[0].latitude) self.assertEqual(-5.832745, gpx.tracks[0].segments[0].points[0].longitude) + def test_large_float_values(self) -> None: + gpx = mod_gpx.GPX() + waypoint_orig = mod_gpx.GPXWaypoint( + latitude=10000000000000000.0, + longitude=10000000000000000.0, + elevation=10000000000000000.0 + ) + gpx.waypoints.append(waypoint_orig) + + xml = gpx.to_xml() + + gpx = mod_gpxpy.parse(xml) + waypoint = gpx.waypoints[0] + self.assertAlmostEqual(waypoint_orig.latitude, waypoint.latitude) + self.assertAlmostEqual(waypoint_orig.longitude, waypoint.longitude) + self.assertAlmostEqual(waypoint_orig.elevation, waypoint.elevation) + class LxmlTest(mod_unittest.TestCase): @mod_unittest.skipIf(mod_os.environ.get('XMLPARSER')!="LXML", "LXML not installed") def test_checklxml(self) -> None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/gpxpy-1.4.2/test_files/around-visnjan-with-car.gpx new/gpxpy-1.5.0/test_files/around-visnjan-with-car.gpx --- old/gpxpy-1.4.2/test_files/around-visnjan-with-car.gpx 1970-01-01 01:00:00.000000000 +0100 +++ new/gpxpy-1.5.0/test_files/around-visnjan-with-car.gpx 2021-11-04 18:37:32.000000000 +0100 @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no" ?><gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxx="http://www.garmin.com/xmlschemas/GpxExtensions/v3" xmlns:gpxtrkx="http://www.garmin.com/xmlschemas/TrackStatsExtension/v1" xmlns:wptx1="http://www.garmin.com/xmlschemas/WaypointExtension/v1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" creator="eTrex 20x" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www8.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackStatsExtension/v1 http://www8.garmin.com/xmlschemas/TrackStatsExtension.xsd http://www.garmin.com/xmlschemas/WaypointExtension/v1 http://www8.garmin.com/xmlschemas/WaypointExtensionv1.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensio nv1.xsd"><metadata><link href="http://www.garmin.com"><text>Garmin International</text></link><time>2020-12-18T06:24:32Z</time></metadata><trk><name>2020-12-18 07:24:29</name><extensions><gpxx:TrackExtension><gpxx:DisplayColor>Red</gpxx:DisplayColor></gpxx:TrackExtension></extensions><trkseg><trkpt lat="45.2735188510" lon="13.7142099626"><ele>211.15</ele><time>2020-12-18T06:15:50Z</time></trkpt><trkpt lat="45.2734133229" lon="13.7141885050"><ele>211.63</ele><time>2020-12-18T06:16:00Z</time></trkpt><trkpt lat="45.2733669709" lon="13.7141719926"><ele>212.11</ele><time>2020-12-18T06:16:12Z</time></trkpt><trkpt lat="45.2733422443" lon="13.7141567376"><ele>212.11</ele><time>2020-12-18T06:16:27Z</time></trkpt><trkpt lat="45.2734113950" lon="13.7141328491"><ele>212.11</ele><time>2020-12-18T06:16:43Z</time></trkpt><trkpt lat="45.2734805457" lon="13.7140590046"><ele>212.11</ele><time>2020-12-18T06:16:48Z</time></trkpt><trkpt lat="45.2734844852" lon="13.7140279077"><ele>212.11</ele><time>2020 -12-18T06:16:49Z</time></trkpt><trkpt lat="45.2734798752" lon="13.7139740121"><ele>212.11</ele><time>2020-12-18T06:16:50Z</time></trkpt><trkpt lat="45.2734659612" lon="13.7139264867"><ele>212.11</ele><time>2020-12-18T06:16:51Z</time></trkpt><trkpt lat="45.2734447550" lon="13.7138696574"><ele>212.11</ele><time>2020-12-18T06:16:52Z</time></trkpt><trkpt lat="45.2734212019" lon="13.7138032727"><ele>212.11</ele><time>2020-12-18T06:16:53Z</time></trkpt><trkpt lat="45.2732143365" lon="13.7135986704"><ele>209.70</ele><time>2020-12-18T06:16:55Z</time></trkpt><trkpt lat="45.2725250088" lon="13.7124552112"><ele>206.34</ele><time>2020-12-18T06:17:05Z</time></trkpt><trkpt lat="45.2724903915" lon="13.7123416364"><ele>205.38</ele><time>2020-12-18T06:17:06Z</time></trkpt><trkpt lat="45.2724756394" lon="13.7122288160"><ele>204.42</ele><time>2020-12-18T06:17:07Z</time></trkpt><trkpt lat="45.2724855300" lon="13.7121125590"><ele>202.98</ele><time>2020-12-18T06:17:08Z</time></trkpt><trkpt lat="45.272524 0868" lon="13.7120070308"><ele>201.53</ele><time>2020-12-18T06:17:09Z</time></trkpt><trkpt lat="45.2725872025" lon="13.7119256426"><ele>200.57</ele><time>2020-12-18T06:17:10Z</time></trkpt><trkpt lat="45.2726696804" lon="13.7118678913"><ele>199.61</ele><time>2020-12-18T06:17:11Z</time></trkpt><trkpt lat="45.2727608755" lon="13.7118318491"><ele>198.65</ele><time>2020-12-18T06:17:12Z</time></trkpt><trkpt lat="45.2728583571" lon="13.7118009198"><ele>198.17</ele><time>2020-12-18T06:17:13Z</time></trkpt><trkpt lat="45.2729529049" lon="13.7117580883"><ele>197.69</ele><time>2020-12-18T06:17:14Z</time></trkpt><trkpt lat="45.2730364725" lon="13.7117073778"><ele>197.21</ele><time>2020-12-18T06:17:15Z</time></trkpt><trkpt lat="45.2731081378" lon="13.7116509676"><ele>196.73</ele><time>2020-12-18T06:17:16Z</time></trkpt><trkpt lat="45.2731667273" lon="13.7115950603"><ele>196.25</ele><time>2020-12-18T06:17:17Z</time></trkpt><trkpt lat="45.2732126601" lon="13.7115481216"><ele>195.77</ele><time>202 0-12-18T06:17:18Z</time></trkpt><trkpt lat="45.2733494528" lon="13.7115180306"><ele>195.77</ele><time>2020-12-18T06:17:23Z</time></trkpt><trkpt lat="45.2733849082" lon="13.7115573417"><ele>195.77</ele><time>2020-12-18T06:17:24Z</time></trkpt><trkpt lat="45.2738018241" lon="13.7120958790"><ele>197.21</ele><time>2020-12-18T06:17:31Z</time></trkpt><trkpt lat="45.2747437824" lon="13.7131041382"><ele>200.57</ele><time>2020-12-18T06:17:39Z</time></trkpt><trkpt lat="45.2762353420" lon="13.7142698094"><ele>203.46</ele><time>2020-12-18T06:17:48Z</time></trkpt><trkpt lat="45.2783617470" lon="13.7160487846"><ele>204.42</ele><time>2020-12-18T06:17:59Z</time></trkpt><trkpt lat="45.2798055299" lon="13.7177372351"><ele>211.63</ele><time>2020-12-18T06:18:07Z</time></trkpt><trkpt lat="45.2806127071" lon="13.7190883141"><ele>220.28</ele><time>2020-12-18T06:18:14Z</time></trkpt><trkpt lat="45.2809007093" lon="13.7198194675"><ele>224.61</ele><time>2020-12-18T06:18:19Z</time></trkpt><trkpt lat="45.28091 47071" lon="13.7199410051"><ele>225.09</ele><time>2020-12-18T06:18:20Z</time></trkpt><trkpt lat="45.2809076663" lon="13.7200549152"><ele>225.57</ele><time>2020-12-18T06:18:21Z</time></trkpt><trkpt lat="45.2808748093" lon="13.7201650534"><ele>226.05</ele><time>2020-12-18T06:18:22Z</time></trkpt><trkpt lat="45.2808222547" lon="13.7202596013"><ele>227.01</ele><time>2020-12-18T06:18:23Z</time></trkpt><trkpt lat="45.2807536069" lon="13.7203504611"><ele>227.49</ele><time>2020-12-18T06:18:24Z</time></trkpt><trkpt lat="45.2806798462" lon="13.7204394769"><ele>227.49</ele><time>2020-12-18T06:18:25Z</time></trkpt><trkpt lat="45.2802416403" lon="13.7209278904"><ele>229.89</ele><time>2020-12-18T06:18:30Z</time></trkpt><trkpt lat="45.2801641915" lon="13.7210449856"><ele>230.37</ele><time>2020-12-18T06:18:31Z</time></trkpt><trkpt lat="45.2800970525" lon="13.7211750727"><ele>230.85</ele><time>2020-12-18T06:18:32Z</time></trkpt><trkpt lat="45.2798213717" lon="13.7217182200"><ele>232.78</ele><time>20 20-12-18T06:18:37Z</time></trkpt><trkpt lat="45.2797609381" lon="13.7217932381"><ele>233.26</ele><time>2020-12-18T06:18:38Z</time></trkpt><trkpt lat="45.2796989121" lon="13.7218602933"><ele>233.74</ele><time>2020-12-18T06:18:39Z</time></trkpt><trkpt lat="45.2796227206" lon="13.7219291087"><ele>233.74</ele><time>2020-12-18T06:18:40Z</time></trkpt><trkpt lat="45.2795377281" lon="13.7219938170"><ele>234.22</ele><time>2020-12-18T06:18:41Z</time></trkpt><trkpt lat="45.2788409404" lon="13.7224451825"><ele>237.58</ele><time>2020-12-18T06:18:49Z</time></trkpt><trkpt lat="45.2787696104" lon="13.7224403210"><ele>238.06</ele><time>2020-12-18T06:18:50Z</time></trkpt><trkpt lat="45.2787095122" lon="13.7223979924"><ele>238.06</ele><time>2020-12-18T06:18:51Z</time></trkpt><trkpt lat="45.2780560590" lon="13.7217258476"><ele>235.66</ele><time>2020-12-18T06:18:59Z</time></trkpt><trkpt lat="45.2775454335" lon="13.7212325726"><ele>235.18</ele><time>2020-12-18T06:19:06Z</time></trkpt><trkpt lat="45.2774 896938" lon="13.7211731449"><ele>235.18</ele><time>2020-12-18T06:19:07Z</time></trkpt><trkpt lat="45.2769502345" lon="13.7203841563"><ele>235.18</ele><time>2020-12-18T06:19:18Z</time></trkpt><trkpt lat="45.2769132704" lon="13.7203253992"><ele>234.70</ele><time>2020-12-18T06:19:19Z</time></trkpt><trkpt lat="45.2768747974" lon="13.7202719226"><ele>235.18</ele><time>2020-12-18T06:19:20Z</time></trkpt><trkpt lat="45.2767994441" lon="13.7201820686"><ele>235.18</ele><time>2020-12-18T06:19:22Z</time></trkpt><trkpt lat="45.2767564449" lon="13.7201577611"><ele>235.18</ele><time>2020-12-18T06:19:23Z</time></trkpt><trkpt lat="45.2767147869" lon="13.7201456074"><ele>235.18</ele><time>2020-12-18T06:19:24Z</time></trkpt><trkpt lat="45.2765431255" lon="13.7199522369"><ele>235.66</ele><time>2020-12-18T06:19:31Z</time></trkpt><trkpt lat="45.2765110228" lon="13.7198996823"><ele>236.14</ele><time>2020-12-18T06:19:32Z</time></trkpt><trkpt lat="45.2764779143" lon="13.7198591977"><ele>236.14</ele><time>2 020-12-18T06:19:33Z</time></trkpt><trkpt lat="45.2764433809" lon="13.7198313698"><ele>236.14</ele><time>2020-12-18T06:19:34Z</time></trkpt><trkpt lat="45.2764085121" lon="13.7198117562"><ele>236.62</ele><time>2020-12-18T06:19:35Z</time></trkpt><trkpt lat="45.2763800975" lon="13.7197960820"><ele>236.62</ele><time>2020-12-18T06:19:36Z</time></trkpt><trkpt lat="45.2763594780" lon="13.7197886221"><ele>237.10</ele><time>2020-12-18T06:19:37Z</time></trkpt><trkpt lat="45.2763438039" lon="13.7197924778"><ele>237.10</ele><time>2020-12-18T06:19:38Z</time></trkpt><trkpt lat="45.2763319854" lon="13.7197979260"><ele>237.58</ele><time>2020-12-18T06:19:39Z</time></trkpt><trkpt lat="45.2763222624" lon="13.7197942380"><ele>238.54</ele><time>2020-12-18T06:19:56Z</time></trkpt><trkpt lat="45.2763222624" lon="13.7198120914"><ele>238.06</ele><time>2020-12-18T06:20:37Z</time></trkpt><trkpt lat="45.2763158921" lon="13.7197734509"><ele>241.91</ele><time>2020-12-18T06:21:26Z</time></trkpt><trkpt lat="45.276 2968652" lon="13.7198025361"><ele>240.95</ele><time>2020-12-18T06:21:37Z</time></trkpt><trkpt lat="45.2762854658" lon="13.7198266760"><ele>240.95</ele><time>2020-12-18T06:21:38Z</time></trkpt><trkpt lat="45.2762649301" lon="13.7198565155"><ele>240.95</ele><time>2020-12-18T06:21:39Z</time></trkpt><trkpt lat="45.2762370184" lon="13.7198840920"><ele>240.95</ele><time>2020-12-18T06:21:40Z</time></trkpt><trkpt lat="45.2762006409" lon="13.7199039571"><ele>240.95</ele><time>2020-12-18T06:21:41Z</time></trkpt><trkpt lat="45.2761546243" lon="13.7199099921"><ele>240.95</ele><time>2020-12-18T06:21:42Z</time></trkpt><trkpt lat="45.2760945261" lon="13.7199086510"><ele>239.99</ele><time>2020-12-18T06:21:43Z</time></trkpt><trkpt lat="45.2760227770" lon="13.7198962457"><ele>239.51</ele><time>2020-12-18T06:21:44Z</time></trkpt><trkpt lat="45.2759484295" lon="13.7198709324"><ele>239.51</ele><time>2020-12-18T06:21:45Z</time></trkpt><trkpt lat="45.2757122274" lon="13.7197652366"><ele>237.58</ele><time> 2020-12-18T06:21:48Z</time></trkpt><trkpt lat="45.2756342757" lon="13.7197070662"><ele>237.10</ele><time>2020-12-18T06:21:49Z</time></trkpt><trkpt lat="45.2753456030" lon="13.7194294576"><ele>235.66</ele><time>2020-12-18T06:21:53Z</time></trkpt><trkpt lat="45.2752794698" lon="13.7193289585"><ele>235.18</ele><time>2020-12-18T06:21:54Z</time></trkpt><trkpt lat="45.2752263285" lon="13.7192286272"><ele>234.70</ele><time>2020-12-18T06:21:55Z</time></trkpt><trkpt lat="45.2751757856" lon="13.7191137951"><ele>234.22</ele><time>2020-12-18T06:21:56Z</time></trkpt><trkpt lat="45.2751293499" lon="13.7189873960"><ele>233.74</ele><time>2020-12-18T06:21:57Z</time></trkpt><trkpt lat="45.2745928243" lon="13.7170127872"><ele>223.64</ele><time>2020-12-18T06:22:11Z</time></trkpt><trkpt lat="45.2740180772" lon="13.7149131205"><ele>218.36</ele><time>2020-12-18T06:22:25Z</time></trkpt><trkpt lat="45.2739570569" lon="13.7147928402"><ele>217.88</ele><time>2020-12-18T06:22:26Z</time></trkpt><trkpt lat="45.27 38915943" lon="13.7146829534"><ele>217.40</ele><time>2020-12-18T06:22:27Z</time></trkpt><trkpt lat="45.2734488621" lon="13.7140272371"><ele>214.03</ele><time>2020-12-18T06:22:36Z</time></trkpt><trkpt lat="45.2734180167" lon="13.7140385527"><ele>214.03</ele><time>2020-12-18T06:22:37Z</time></trkpt><trkpt lat="45.2733911108" lon="13.7140660454"><ele>214.03</ele><time>2020-12-18T06:22:38Z</time></trkpt><trkpt lat="45.2733654622" lon="13.7141018361"><ele>214.03</ele><time>2020-12-18T06:22:39Z</time></trkpt><trkpt lat="45.2733391430" lon="13.7141377944"><ele>214.03</ele><time>2020-12-18T06:22:40Z</time></trkpt><trkpt lat="45.2733212058" lon="13.7141618505"><ele>214.51</ele><time>2020-12-18T06:22:41Z</time></trkpt><trkpt lat="45.2733364608" lon="13.7141542230"><ele>214.51</ele><time>2020-12-18T06:22:45Z</time></trkpt><trkpt lat="45.2733259834" lon="13.7140594237"><ele>213.07</ele><time>2020-12-18T06:23:00Z</time></trkpt><trkpt lat="45.2733036038" lon="13.7140420731"><ele>212.11</ele><time >2020-12-18T06:23:21Z</time></trkpt><trkpt lat="45.2733260673" >lon="13.7139913626"><ele>210.67</ele><time>2020-12-18T06:23:56Z</time></trkpt><trkpt > lat="45.2733349521" >lon="13.7139970623"><ele>210.67</ele><time>2020-12-18T06:24:24Z</time></trkpt></trkseg></trk></gpx> \ No newline at end of file
