调整目录结构
This commit is contained in:
149
Needed/mini-python/Scripts/gpxinfo
Normal file
149
Needed/mini-python/Scripts/gpxinfo
Normal file
@@ -0,0 +1,149 @@
|
||||
#!C:\Users\milk\AppData\Local\Programs\Python\Python312\python.exe
|
||||
|
||||
"""
|
||||
Command line utility to extract basic statistics from gpx file(s)
|
||||
"""
|
||||
|
||||
import pdb
|
||||
|
||||
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) -> str:
|
||||
if not time_s:
|
||||
return 'n/a'
|
||||
elif args.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) -> str:
|
||||
if args.miles:
|
||||
return '{:.3f}miles'.format(length / 1000. * KM_TO_MILES)
|
||||
else:
|
||||
return '{:.3f}km'.format(length / 1000.)
|
||||
|
||||
|
||||
def format_short_length(length: float) -> str:
|
||||
if args.miles:
|
||||
return '{:.2f}ft'.format(length * M_TO_FEET)
|
||||
else:
|
||||
return '{:.2f}m'.format(length)
|
||||
|
||||
|
||||
def format_speed(speed: float) -> str:
|
||||
if not speed:
|
||||
speed = 0
|
||||
if args.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=' ') -> 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)))
|
||||
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(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)))
|
||||
print('%sTotal downhill: %s' % (indentation, format_short_length(downhill)))
|
||||
|
||||
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())))))
|
||||
|
||||
print('')
|
||||
|
||||
|
||||
def print_gpx_info(gpx: mod_gpx.GPX, gpx_file: str) -> 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_gpx_part_info(gpx)
|
||||
|
||||
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=' ')
|
||||
|
||||
|
||||
def run(gpx_files: List[str]) -> 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)
|
||||
except Exception as e:
|
||||
mod_logging.exception(e)
|
||||
print('Error processing %s' % gpx_file)
|
||||
mod_sys.exit(1)
|
||||
|
||||
|
||||
def make_parser() -> mod_argparse.ArgumentParser:
|
||||
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('-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')
|
||||
return parser
|
||||
|
||||
if __name__ == '__main__':
|
||||
args, gpx_files = make_parser().parse_known_args()
|
||||
if args.debug:
|
||||
mod_logging.basicConfig(level=mod_logging.DEBUG,
|
||||
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s')
|
||||
run(gpx_files)
|
||||
Reference in New Issue
Block a user