michahe
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Hallo, ich möchte (letztlich mit einem Script) mehrere GPX-Files analysieren (nicht grafisch anzeigen!), also z.B. Auslesen von
Es kenne (und nutze) GPX-Anwendungen wie RouteConverter und GPX-Viewer (Berkemeier); aber diese sind umständlich, wenn für zehn GPX-Files (nur) die Track-Länge bestimmt werden soll. Ich habe versucht, etwas ähnliches wie MediaInfo (cli) zu finden, eben nicht für Medien- sondern für GPX-Files. Entweder habe ich unvollständig gesucht und Ihr könnt mir etwas vorschlagen. Oder ich müsste Python verstehen um zu erkennen, ob bzw. was gpxpy bzw. die darauf aufbauende "GPS Data Analysis in Python" zu meiner Aufgabenstellung beitragen können.
Moderiert von sebix: Thema in einen passenden Forenbereich verschoben. Bitte beachte die als wichtig markierten Themen („Welche Themen gehören hier her und welche nicht?“) in jedem Forenbereich. Danke.
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11261
Wohnort: München
|
Auf den ersten Blick könnte das auf gpxpy aufbauende gpxinfo aus dem gpx-cmd-tools für deinen Anwendungsfall passen. Ich denke die Haversine-Formel ist für die üblichen Geschwindigkeiten und eher kleinen Abständen zwischen den erfassten Punkten nicht unbedingt sinnvoll (die Erde is ja auch alles andere als eine perfekte Kugel, eher ein abgeflachtes Ellipsoid mit ordentlich Auffaltungen an der Oberfläche: Erdfigur) - da ist eine 3D-Distanz zwischen Punkten im Raum vermutlich mehr als ausreichend.
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Danke seahawk1986, Auf den ersten Blick könnte das auf gpxpy aufbauende gpxinfo aus dem gpx-cmd-tools für deinen Anwendungsfall passen.
Deine URL ist nicht ganz richtig: Dies bzw hier? Und was muss ich dann tun (Python3 ist installiert), um z,B. die Gesamt-Länge einer GPX-Aufzeichnung zu ermitteln?
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11261
Wohnort: München
|
Ups, da hatte ich zu viel abgeschnitten - tkrajina/gpx-cmd-tools
|
noisefloor
Anmeldungsdatum: 6. Juni 2006
Beiträge: 29567
|
Hallo, GPX Dateien sind auch "nur" XML. Wenn du was lernen willst kannst du die auch händisch Parsen und die Daten sammeln. In der Standardbibliothek ist das etree-Modul enthalten. DIE Bibliothek zum Parsen von XML für Python ist aber eher lxml. Gruß, noisefloor
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11261
Wohnort: München
|
michahe schrieb: Und was muss ich dann tun (Python3 ist installiert), um z,B. die Gesamt-Länge einer GPX-Aufzeichnung zu ermitteln?
Die gpx-cmd-tools kannst du z.B. so für deinen Nutzer installieren:
sudo apt install python3-pip
pip3 install --user gpx-cmd-tools
Und dann einfach gpxinfo mit der gewünschten gpx-Datei aufrufen - das sieht dann z.B. so aus:
$ gpxinfo '2021-05-09_364709729_Von München zum Sylvensteinspeicher, Wallgau und zurück 09.05.2021.gpx'
File: 2021-05-09_364709729_Von München zum Sylvensteinspeicher, Wallgau und zurück 09.05.2021.gpx
GPX name: Von München zum Sylvensteinspeicher, Wallgau und zurück 09.05.2021
Waypoints: 0
Routes: 0
Length 2D: 198.564km
Length 3D: 198.654km
Moving time: 10:12:22
Stopped time: 02:13:46
Max speed: 10.04m/s = 36.13km/h
Avg speed: 5.38m/s = 19.36km/h
Total uphill: 1981.02m
Total downhill: 2015.52m
Started: 2021-05-09 06:28:50.880000+00:00
Ended: 2021-05-09 18:54:59.932000+00:00
Points: 15052
Avg distance between points: 13.19m
Track #0, Segment #0
Length 2D: 198.564km
Length 3D: 198.654km
Moving time: 10:12:22
Stopped time: 02:13:46
Max speed: 10.04m/s = 36.13km/h
Avg speed: 5.38m/s = 19.36km/h
Total uphill: 1981.02m
Total downhill: 2015.52m
Started: 2021-05-09 06:28:50.880000+00:00
Ended: 2021-05-09 18:54:59.932000+00:00
Points: 15052
Avg distance between points: 13.19m
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Danke seahawk1986,
nach vielen Fehlversuchen habe ich - Dank Deiner Hilfe - erstmals einen Erfolg mit Python.
Die gpx-cmd-tools kannst du ... installieren ...
Und dann einfach gpxinfo mit der gewünschten gpx-Datei aufrufen
Das funktioniert! Es liefert aber alle Informationen in einem Block, ich müsste also wieder parsen um beispielsweise die Werte von
Length 3D TAB Moving time TAB Avg speed [km/h]
zu erhalten, also (aus dem Ergebnis von seahawk1986):
198.654 TAB 10:12:22 TAB 19.36 Deshalb habe ich meinen alten Vorschlag noch einmal angeschaut; hier mein aktuell lauffähiger Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 | #!/usr/bin/env python3
# Kommentar: GPX-Analyse Python 3
print('===== Teil 1 gpxinfo ==============================================')
import subprocess
subprocess.run(["gpxinfo", "test_files/2014-with-wpts.gpx"])
print() # Leerzeile
print() # Leerzeile
print('===== Teil 2 thatmaceguy ========================================')
import gpxpy # https://pypi.org/project/gpxpy/, vorhanden aus Installation gpxinfo
# -- Pandas Data structures and data analysis tool
# -- $ pip install pandas # https://pandas.pydata.org/pandas-docs/stable/getting_started/index.html?highlight=install
import pandas as pd
print() # Leerzeile
print('===== Teil 2.1 thatmaceguy Daten laden, Anzahl Tracks, Punkte =====')
gpx_file = open('test_files/2014-with-wpts.gpx', 'r') # open the file in read mode
gpx_data = gpxpy.parse(gpx_file)
len_tracks = len(gpx_data.tracks)
len_segments = len(gpx_data.tracks[0].segments)
len_points = len(gpx_data.tracks[0].segments[0].points)
print(f"Tracks: {len_tracks} \nSegments: {len_segments} \nPoints: {len_points} \n")
print() # Leerzeile
print('===== Teil 2.2 thatmaceguy einige Zeilen auswerten ================')
gpx_points = gpx_data.tracks[0].segments[0].points
df = pd.DataFrame(columns=['lon', 'lat', 'elev', 'time']) # create a new Pandas dataframe object with give column names
# loop through the points and append their attributes to the dataframe
for point in gpx_points:
df = df.append({'lon' : point.longitude, 'lat' : point.latitude, 'elev' : point.elevation, 'time' : point.time}, ignore_index=True)
print(f"df.head(10) displays the first 10 rows of the dataframe:\n\n{df.head(10)}\n\n")
print(f"df.info() gives a summary of the dataframe's contents and data-types:\n")
print(df.info(), "\n\n") # I had to pull this out separately because it was outputting the info table before the text, no idea why.
print(f"df.describe() gives a basic statistical summary of the numerical data:\n\n{df.describe()}")
print() # Leerzeile
print('===== Teil 2.2 thatmaceguy Distanzen ==============================')
# -- GeoPy Berechnung von Disanzen, inkl Haversine
# -- $ pip install geopy # https://geopy.readthedocs.io/en/stable/#installation
from geopy import distance
from math import sqrt, floor
import datetime
# first create lists to store the results, these will be appended ot the dataframe at the end
# Note: i'll be working from the gps_points object directly and then appending results into the dataframe. It would make a lot more sense to operate directly on the dataframe.
delta_elev = [0] # change in elevation between records
delta_time = [0] # time interval between records
delta_sph2d = [0] # segment distance from spherical geometry only
delta_sph3d = [0] # segment distance from spherical geometry, adjusted for elevation
dist_sph2d = [0] # cumulative distance from spherical geometry only
dist_sph3d = [0] # cumulative distance from spherical geometry, adjusted for elevation
delta_geo2d = [0] # segment distance from geodesic method only
delta_geo3d = [0] # segment distance from geodesic method, adjusted for elevation
dist_geo2d = [0] # cumulative distance from geodesic method only
dist_geo3d = [0] # cumulative distance from geodesic method, adjusted for elevation
for idx in range(1, len(gpx_points)): # index will count from 1 to lenght of dataframe, beginning with the second row
start = gpx_points[idx-1]
end = gpx_points[idx]
# elevation
temp_delta_elev = end.elevation - start.elevation
delta_elev.append(temp_delta_elev)
# time
temp_delta_time = (end.time - start.time).total_seconds()
delta_time.append(temp_delta_time)
# distance from spherical model
temp_delta_sph2d = distance.great_circle((start.latitude, start.longitude), (end.latitude, end.longitude)).m
delta_sph2d.append(temp_delta_sph2d)
dist_sph2d.append(dist_sph2d[-1] + temp_delta_sph2d)
temp_delta_sph3d = sqrt(temp_delta_sph2d**2 + temp_delta_elev**2)
delta_sph3d.append(temp_delta_sph3d)
dist_sph3d.append(dist_sph3d[-1] + temp_delta_sph3d)
# distance from geodesic model
temp_delta_geo2d = distance.distance((start.latitude, start.longitude), (end.latitude, end.longitude)).m
delta_geo2d.append(temp_delta_geo2d)
dist_geo2d.append(dist_geo2d[-1] + temp_delta_geo2d)
temp_delta_geo3d = sqrt(temp_delta_geo2d**2 + temp_delta_elev**2)
delta_geo3d.append(temp_delta_geo3d)
dist_geo3d.append(dist_geo3d[-1] + temp_delta_geo3d)
# dump the lists into the dataframe
df['delta_elev'] = delta_elev
df['delta_time'] = delta_time
df['delta_sph2d'] = delta_sph2d
df['delta_sph3d'] = delta_sph3d
df['dist_sph2d'] = dist_sph2d
df['dist_sph3d'] = dist_sph3d
df['delta_geo2d'] = delta_geo2d
df['delta_geo3d'] = delta_geo3d
df['dist_geo2d'] = dist_geo2d
df['dist_geo3d'] = dist_geo3d
# check bulk results
print(f"Spherical Distance 2D: {dist_sph2d[-1]/1000}km \nSpherical Distance 3D: {dist_sph3d[-1]/1000}km \nElevation Correction: {(dist_sph3d[-1]) - (dist_sph2d[-1])} meters \nGeodesic Distance 2D: {dist_geo2d[-1]/1000}km \nGeodesic Distance 3D: {dist_geo3d[-1]/1000}km \nElevation Correction: {(dist_geo3d[-1]) - (dist_geo2d[-1])} meters \nModel Difference: {(dist_geo3d[-1]) - (dist_sph3d[-1])} meters \nTotal Time: {str(datetime.timedelta(seconds=sum(delta_time)))}")
print() # Leerzeile
print('===== Teil 2.3 thatmaceguy Diagramme (im Browser)) ================')
# -- PlotlyExpress Diagramme
# -- $ pip install plotly==5.5.0 # https://plotly.com/python/getting-started/
import plotly.express as px
fig_6 = px.line(df, x='dist_geo3d', y='delta_elev', template='plotly_dark')
fig_6.show()
fig_5 = px.line(df, x='time', y='dist_geo3d', template='plotly_dark')
fig_5.show()
df['inst_mps'] = df['delta_geo3d'] / df['delta_time']
fig_8 = px.histogram(df, x='inst_mps', template='plotly_dark')
fig_8.update_traces(xbins=dict(start=0, end=12, size=0.1))
fig_8.show()
print() # Leerzeile
print('===== Teil 2.4 thatmaceguy Statistik =============================')
df.fillna(0, inplace=True) # fill in the NaN's in the first row of distances and deltas with 0. They were breaking the overall average speed calculation
df_moving = df[df['inst_mps'] >= 0.9] # make a new dataframe filtered to only records where instantaneous speed was greater than 0.9m/s
avg_mps = (sum((df['inst_mps'] * df['delta_time'])) / sum(df['delta_time']))
avg_mov_mps = (sum((df_moving['inst_mps'] * df_moving['delta_time'])) / sum(df_moving['delta_time']))
print(f"Maximum Speed: {round((2.23694 * df['inst_mps'].max(axis=0)), 2)} mph")
print(f"Average Speed: {round((2.23694 * avg_mps), 2)} mph")
print(f"Average Moving Speed: {round((2.23694 * avg_mov_mps), 2)} mph")
print(f"Moving Time: {str(datetime.timedelta(seconds=sum(df_moving['delta_time'])))}")
df['avg_mps_roll'] = df['inst_mps'].rolling(20, center=True).mean()
fig_16 = px.line(df, x='time', y=['inst_mps', 'avg_mps_roll'], template='plotly_dark') # as of 2020-05-26 Plotly 4.8 you can pass a list of columns to either x or y and plotly will figure it out
fig_16.show()
print() # Leerzeile
print('===== Teil 2.5 thatmaceguy Anstieg (Varianten) ====================')
def positive_only(x):
if x > 0:
return x
else:
return 0
pos_only = list(map(positive_only, df['delta_elev']))
print(f"Total Elevation Gain: {round(sum(pos_only), 2)}")
elev_gain = sum(list(filter(lambda x : x > 0, df['delta_elev'])))
print(f"Total Elevation Gain: {round(elev_gain, 2)}")
print(f"Elevation Gain: {round(sum(df[df['delta_elev'] > 0]['delta_elev']), 2)}")
print(f"Elevation Loss: {round(sum(df[df['delta_elev'] < 0]['delta_elev']), 2)}")
|
Dies ist mein erster Erfolg mit Python, gerne nehme ich Eure Verbesserungsvorschläge auf! Ich denke, ich kann den aktuellen Code noch so modifizieren, dass die formatierte Ausgabe erzielt wird. Auch bin ich dankbar für Hinweise, wie ich weitere Analysen-Werte separieren kann.
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11261
Wohnort: München
|
michahe schrieb: Es liefert aber alle Informationen in einem Block, ich müsste also wieder parsen um beispielsweise die Werte von
Length 3D TAB Moving time TAB Avg speed [km/h]
zu erhalten, also (aus dem Ergebnis von seahawk1986):
198.654 TAB 10:12:22 TAB 19.36
Wenn man das gpxinfo-Skript nicht modifizieren will, kann man auch seine Ausgabe weiterverarbeiten:
$ gpxinfo -t '2021-05-09_364709729_Von München zum Sylvensteinspeicher, Wallgau und zurück 09.05.2021.gpx' | awk '/Length 3D|Moving time|Avg speed/{sub("km/?h?","", $NF); print $NF}' | paste -s
198.654 10:12:22 19.36
Ob man das lieber macht als ein langes Skript zu schreiben, hängt davon ab, was man sonst noch mit den Daten vor hat...
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Danke seahawk1986, Wenn man das gpxinfo-Skript nicht modifizieren will, kann man auch seine Ausgabe weiterverarbeiten:
$ gpxinfo -t '2021-05-09_364709729_Von München zum Sylvensteinspeicher, Wallgau und zurück 09.05.2021.gpx' | awk '/Length 3D|Moving time|Avg speed/{sub("km/?h?","", $NF); print $NF}' | paste -s
198.654 10:12:22 19.36
Erst durch Deinen Hinweis habe ich erkannt, dass ich die Datei gpxtools/gpxinfo.py auf meine Anforderungen hin anpassen kann; diesen Weg möchte ich gehen, schon um Python zu lernen.Ich arbeite daran ...
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Hallo seahawk1986, Danke für die Unterstützung; ich möchte der gpxinfo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147 | """
Command line utility to extract basic statistics from gpx file(s)
"""
import sys as mod_sys
import logging as mod_logging
import math as mod_math
import argparse as mod_argparse
import gpxpy as mod_gpxpy
import gpxpy.gpx as mod_gpx
from typing import *
KM_TO_MILES = 0.621371
M_TO_FEET = 3.28084
def format_time(time_s: float, seconds: bool) -> str:
if not time_s:
return 'n/a'
elif seconds:
return str(int(time_s))
else:
minutes = mod_math.floor(time_s / 60.)
hours = mod_math.floor(minutes / 60.)
return '%s:%s:%s' % (str(int(hours)).zfill(2), str(int(minutes % 60)).zfill(2), str(int(time_s % 60)).zfill(2))
def format_long_length(length: float, miles: bool) -> str:
if miles:
return '{:.3f}miles'.format(length / 1000. * KM_TO_MILES)
else:
return '{:.3f}km'.format(length / 1000.)
def format_short_length(length: float, miles: bool) -> str:
if miles:
return '{:.2f}ft'.format(length * M_TO_FEET)
else:
return '{:.2f}m'.format(length)
def format_speed(speed: float, miles: bool) -> str:
if not speed:
speed = 0
if miles:
return '{:.2f}mph'.format(speed * KM_TO_MILES * 3600. / 1000.)
else:
return '{:.2f}m/s = {:.2f}km/h'.format(speed, speed * 3600. / 1000.)
def print_gpx_part_info(gpx_part: Union[mod_gpx.GPX, mod_gpx.GPXTrack, mod_gpx.GPXTrackSegment], indentation: str=' ', miles: bool = False, seconds: bool = False) -> None:
# gpx_part may be a track or segment.
length_2d = gpx_part.length_2d()
length_3d = gpx_part.length_3d()
print('%sLength 2D: %s' % (indentation, format_long_length(length_2d or 0, miles)))
print('%sLength 3D: %s' % (indentation, format_long_length(length_3d, miles)))
moving_data = gpx_part.get_moving_data()
if moving_data:
print('%sMoving time: %s' % (indentation, format_time(moving_data.moving_time, seconds)))
print('%sStopped time: %s' % (indentation, format_time(moving_data.stopped_time, seconds)))
#print('%sStopped distance: %s' % (indentation, format_short_length(stopped_distance)))
print('%sMax speed: %s' % (indentation, format_speed(moving_data.max_speed, miles)))
print('%sAvg speed: %s' % (indentation, format_speed(moving_data.moving_distance / moving_data.moving_time, miles) if moving_data.moving_time > 0 else "?"))
uphill, downhill = gpx_part.get_uphill_downhill()
print('%sTotal uphill: %s' % (indentation, format_short_length(uphill, miles)))
print('%sTotal downhill: %s' % (indentation, format_short_length(downhill, miles)))
start_time, end_time = gpx_part.get_time_bounds()
print('%sStarted: %s' % (indentation, start_time))
print('%sEnded: %s' % (indentation, end_time))
points_no = len(list(gpx_part.walk(only_points=True)))
print('%sPoints: %s' % (indentation, points_no))
if points_no > 0:
distances: List[float] = []
previous_point = None
for point in gpx_part.walk(only_points=True):
if previous_point:
distance = point.distance_2d(previous_point)
distances.append(distance)
previous_point = point
print('%sAvg distance between points: %s' % (indentation, format_short_length(sum(distances) / len(list(gpx_part.walk())), miles)))
print('')
def print_gpx_info(gpx: mod_gpx.GPX, gpx_file: str, miles: bool, seconds: bool, only_track: bool) -> None:
print('File: %s' % gpx_file)
if gpx.name:
print(' GPX name: %s' % gpx.name)
if gpx.description:
print(' GPX description: %s' % gpx.description)
if gpx.author_name:
print(' Author: %s' % gpx.author_name)
if gpx.author_email:
print(' Email: %s' % gpx.author_email)
print(f' Waypoints: {len(gpx.waypoints)}')
print(f' Routes: {len(gpx.routes)}')
print_gpx_part_info(gpx, miles=miles, seconds=seconds)
if only_track:
return
for track_no, track in enumerate(gpx.tracks):
for segment_no, segment in enumerate(track.segments):
print(' Track #%s, Segment #%s' % (track_no, segment_no))
print_gpx_part_info(segment, indentation=' ', miles=miles, seconds=seconds)
def run(gpx_files: List[str], miles: bool, seconds: bool, only_track: bool) -> None:
if not gpx_files:
print('No GPX files given')
mod_sys.exit(1)
for gpx_file in gpx_files:
try:
gpx = mod_gpxpy.parse(open(gpx_file))
print_gpx_info(gpx, gpx_file, miles, seconds, only_track)
except Exception as e:
mod_logging.exception(e)
print('Error processing %s' % gpx_file)
mod_sys.exit(1)
def main() -> None:
parser = mod_argparse.ArgumentParser(usage='%(prog)s [-s] [-m] [-d] [file ...]',
description='Command line utility to extract basic statistics from gpx file(s)')
parser.add_argument('-t', '--track', action='store_true', help='Only root track')
parser.add_argument('-s', '--seconds', action='store_true', help='print times as N seconds, rather than HH:MM:SS')
parser.add_argument('-m', '--miles', action='store_true', help='print distances and speeds using miles and feet')
parser.add_argument('-d', '--debug', action='store_true', help='show detailed logging')
args, gpx_files = parser.parse_known_args()
seconds = args.seconds
miles = args.miles
debug = args.debug
only_track = args.track
if debug:
mod_logging.basicConfig(level=mod_logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
run(gpx_files=gpx_files, miles=miles, seconds=seconds, only_track=only_track)
|
eine definierte Datei mitgeben, also
| dir_file = "~/gpx/GPXtest.gpx" # Pfad/Dateiname des GPX-File zur Analyse
|
und dann nur Length3D ausgeben, also
| def print_gpx_part_info(gpx_part: Union[mod_gpx.GPX, mod_gpx.GPXTrack, mod_gpx.GPXTrackSegment], indentation: str=' ', miles: bool = False, seconds: bool = False) -> None:
# gpx_part may be a track or segment.
length_3d = gpx_part.length_3d()
print('%sLength 3D: %s' % (indentation, format_long_length(length_3d, miles)))
|
Wie muss ich den Ursprungs-Code der gpxinfo.py ändern, um die definierte GPX-Datei zu analysieren? Ich glaube, ich habe die Funktionen main und run nicht verstanden ...
|
schragge
Anmeldungsdatum: 27. Januar 2022
Beiträge: 181
|
Ehrlich gesagt, ich verstehe dein Problem nicht.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 | import gpxpy as mod_gpxpy
import gpxpy.gpx as mod_gpx
KM_TO_MILES = 0.621371
def format_long_length(length: float, miles: bool):
if miles:
return '{:.3f}miles'.format(length / 1000. * KM_TO_MILES)
else:
return '{:.3f}km'.format(length / 1000.)
def print_gpx_part_info(gpx_part: mod_gpx.GPX, indentation: str=' ', miles: bool = False, seconds: bool = False):
length_3d = gpx_part.length_3d()
print('%sLength 3D: %s' % (indentation, format_long_length(length_3d, miles)))
dir_file = "GPXtest.gpx"
gpx = mod_gpxpy.parse(open(dir_file))
print_gpx_part_info(gpx)
|
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Vielen Dank schragge, Deinen Code habe ich gespeichert und
#!/usr/bin/env python3
ergänzt; erhalte aber einen Fehler:
... in <module>
def print_gpx_part_info(gpx_part: Union[mod_gpx.GPX, mod_gpx.GPXTrack, mod_gpx.GPXTrackSegment], indentation: str=' ', miles: bool = False, seconds: bool = False):
NameError: name 'Union' is not defined Wenn ich die anderen Bibliotheken
import sys as mod_sys
import logging as mod_logging
import math as mod_math
import argparse as mod_argparse
from typing import *
auch einbinde, funktioniert Dein Code ohne Fehler. Wie finde ich heraus, welche Bibliotheken mindestens nötig sind?
|
schragge
Anmeldungsdatum: 27. Januar 2022
Beiträge: 181
|
Ah, sorry. Union is ein Teil von typing. Geht auch ohne:
| #!/usr/bin/python3
import gpxpy, gpxpy.gpx
dir_file = "GPXtest.gpx"
gpx = gpxpy.parse(open(dir_file))
length_3d = gpxpy.gpx.GPX.length_3d(gpx)
print(f'Length 3D: {length_3d/1000:.3f} km')
|
|
michahe
(Themenstarter)
Anmeldungsdatum: 12. Dezember 2013
Beiträge: 857
|
Danke schragge, Union ist ein Teil von [https://docs.python.org/3/library/typing.html typing]. Geht auch ohne: ...
Super, genau das hatte ich gesucht! Ich mache Fortschritte ...
|