Skip to content

Instantly share code, notes, and snippets.

@ClemRz
Last active March 14, 2019 22:11
Show Gist options
  • Select an option

  • Save ClemRz/262fc5c20d93f42ca20587927d3ca18e to your computer and use it in GitHub Desktop.

Select an option

Save ClemRz/262fc5c20d93f42ca20587927d3ca18e to your computer and use it in GitHub Desktop.

Revisions

  1. ClemRz revised this gist Mar 14, 2019. 1 changed file with 23 additions and 10 deletions.
    33 changes: 23 additions & 10 deletions script.py
    Original file line number Diff line number Diff line change
    @@ -28,7 +28,7 @@ def extract(filename, tz, threshold, verbose):
    print(f"Processing {placemarks_count} points")

    with open(outfile, 'w') as csv_file:
    csv_file.write("TimeStamp,Elapsed Time (s),Distance (km),Speed (km/h),Elevation (m),Elev. gain (m), Elev. loss (m),Stop time (min)\n")
    csv_file.write("TimeStamp,Elapsed Time (s),Distance (km),Speed (km/h),Elevation (m),Elev. gain (m),Elev. loss (m),Stop time (min)\n")

    for placemark in placemarks:
    timestamp = datetime.datetime.strptime(placemark.find("kml:TimeStamp/kml:when", ns).text, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=datetime.timezone(datetime.timedelta(hours=0)))
    @@ -42,21 +42,23 @@ def extract(filename, tz, threshold, verbose):

    if last_coordinates is not None and last_timestamp is not None:
    delta_km = geodesic(last_coordinates, (latitude, longitude)).km
    distance = distance + delta_km
    time_spent = (timestamp - last_timestamp).total_seconds()
    speed = 3600 * delta_km / time_spent
    if speed < threshold:
    stop_time = stop_time + time_spent
    if last_elevation is not None:
    delta_elev = elevation - last_elevation
    if delta_elev >= 0:
    elev_gain += delta_elev
    else:
    elev_loss += delta_elev
    else:
    distance = distance + delta_km
    if last_elevation is not None:
    delta_elev = elevation - last_elevation
    if delta_elev >= 0:
    elev_gain += delta_elev
    else:
    elev_loss += delta_elev
    elapsed_time = timestamp - first_timestamp
    formatted_stop_time = (datetime.datetime(1,1,1) + datetime.timedelta(seconds=stop_time)).strftime("%H:%M:%S")
    elapsed_time = (datetime.datetime(1,1,1) + (timestamp - first_timestamp)).strftime("%H:%M:%S")
    formatted_elapsed_time = (datetime.datetime(1,1,1) + elapsed_time).strftime("%H:%M:%S")
    formatted_timestamp = timestamp.astimezone(datetime.timezone(datetime.timedelta(hours=tz))).strftime("%Y-%m-%d %H:%M:%S")
    line = "{},{},{:.3f},{:.1f},{},{:.0f},{:.0f},{}".format(formatted_timestamp, elapsed_time, distance, speed, elevation, elev_gain, elev_loss, formatted_stop_time)
    line = "{},{},{:.3f},{:.1f},{},{:.0f},{:.0f},{}".format(formatted_timestamp, formatted_elapsed_time, distance, speed, elevation, elev_gain, elev_loss, formatted_stop_time)
    if verbose:
    print(line)

    @@ -67,6 +69,17 @@ def extract(filename, tz, threshold, verbose):
    last_timestamp = timestamp
    last_elevation = elevation

    run_time = elapsed_time - datetime.timedelta(seconds=stop_time)
    avg_speed = distance / run_time.total_seconds() * 3600
    formatted_run_time = (datetime.datetime(1,1,1) + run_time).strftime("%H:%M:%S")
    line = "{},{},,{},,{:.2f}km,,+{:.0f}m{:.0f}m,{:.2f}km/h".format(formatted_elapsed_time, formatted_run_time, formatted_stop_time, distance, elev_gain, elev_loss, avg_speed)
    if verbose:
    print(line)

    with open(outfile, 'a+') as csv_file:
    csv_file.write("\ntime,run time,,stop time,,distance,,elev. gain-loss,avg. speed\n")
    csv_file.write(f"{line}\n")

    print(f"File {outfile} created.")

    def get_options():
  2. ClemRz revised this gist Mar 13, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # Extracts a CSV speed, elevation and distance table from a KML file.

    This is a Python script that extracts a table with several columns from a KML file: timestamp, elapsed time, distance, speed, elevation and stop time.
    This is a Python script that extracts a table with several columns from a KML file: timestamp, elapsed time, distance, speed, elevation, elev. gain, elev. loss and stop time.

    ## How to use this script

  3. ClemRz revised this gist Mar 13, 2019. 1 changed file with 15 additions and 5 deletions.
    20 changes: 15 additions & 5 deletions script.py
    Original file line number Diff line number Diff line change
    @@ -15,17 +15,20 @@ def extract(filename, tz, threshold, verbose):
    points = track1.find("kml:Folder[@id='track 1 points']", ns)
    placemarks = points.findall("kml:Placemark", ns)
    placemarks_count = len(placemarks)
    last_elevation = None
    last_coordinates = None
    last_timestamp = None
    first_timestamp = None
    distance = 0.0
    stop_time = 0
    elev_gain = 0
    elev_loss = 0

    if verbose:
    print(f"Processing {placemarks_count} points")

    with open(outfile, 'w') as csv_file:
    csv_file.write("TimeStamp,Elapsed Time (s),Distance (km),Speed (km/h),Elevation (m),Stop time (min)\n")
    csv_file.write("TimeStamp,Elapsed Time (s),Distance (km),Speed (km/h),Elevation (m),Elev. gain (m), Elev. loss (m),Stop time (min)\n")

    for placemark in placemarks:
    timestamp = datetime.datetime.strptime(placemark.find("kml:TimeStamp/kml:when", ns).text, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=datetime.timezone(datetime.timedelta(hours=0)))
    @@ -38,16 +41,22 @@ def extract(filename, tz, threshold, verbose):
    first_timestamp = timestamp

    if last_coordinates is not None and last_timestamp is not None:
    delta = geodesic(last_coordinates, (latitude, longitude)).km
    distance = distance + delta
    delta_km = geodesic(last_coordinates, (latitude, longitude)).km
    distance = distance + delta_km
    time_spent = (timestamp - last_timestamp).total_seconds()
    speed = 3600 * delta / time_spent
    speed = 3600 * delta_km / time_spent
    if speed < threshold:
    stop_time = stop_time + time_spent
    if last_elevation is not None:
    delta_elev = elevation - last_elevation
    if delta_elev >= 0:
    elev_gain += delta_elev
    else:
    elev_loss += delta_elev
    formatted_stop_time = (datetime.datetime(1,1,1) + datetime.timedelta(seconds=stop_time)).strftime("%H:%M:%S")
    elapsed_time = (datetime.datetime(1,1,1) + (timestamp - first_timestamp)).strftime("%H:%M:%S")
    formatted_timestamp = timestamp.astimezone(datetime.timezone(datetime.timedelta(hours=tz))).strftime("%Y-%m-%d %H:%M:%S")
    line = "{},{},{:.3f},{:.1f},{},{}".format(formatted_timestamp, elapsed_time, distance, speed, elevation, formatted_stop_time)
    line = "{},{},{:.3f},{:.1f},{},{:.0f},{:.0f},{}".format(formatted_timestamp, elapsed_time, distance, speed, elevation, elev_gain, elev_loss, formatted_stop_time)
    if verbose:
    print(line)

    @@ -56,6 +65,7 @@ def extract(filename, tz, threshold, verbose):

    last_coordinates = (latitude, longitude)
    last_timestamp = timestamp
    last_elevation = elevation

    print(f"File {outfile} created.")

  4. ClemRz revised this gist Oct 2, 2018. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,6 @@
    # Extracts a CSV speed, elevation and distance table from a KML file.

    This is a Python script that extracts a table with several columns from a KML file: timestamp, elapsed time, distance, speed and elevation
    This is a Python script that extracts a table with several columns from a KML file: timestamp, elapsed time, distance, speed, elevation and stop time.

    ## How to use this script

  5. ClemRz revised this gist Oct 2, 2018. 1 changed file with 12 additions and 7 deletions.
    19 changes: 12 additions & 7 deletions script.py
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@
    import re
    import argparse

    def extract(filename, tz, verbose):
    def extract(filename, tz, threshold, verbose):
    ns = {"kml": "http://www.opengis.net/kml/2.2"}

    outfile = filename.split(".")[0] + ".csv"
    @@ -19,12 +19,13 @@ def extract(filename, tz, verbose):
    last_timestamp = None
    first_timestamp = None
    distance = 0.0
    stop_time = 0

    if verbose:
    print(f"Processing {placemarks_count} points")

    with open(outfile, 'w') as csv_file:
    csv_file.write("TimeStamp,Elapsed Time (s),Distance (km),Speed (km/h),Elevation (m)\n")
    csv_file.write("TimeStamp,Elapsed Time (s),Distance (km),Speed (km/h),Elevation (m),Stop time (min)\n")

    for placemark in placemarks:
    timestamp = datetime.datetime.strptime(placemark.find("kml:TimeStamp/kml:when", ns).text, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=datetime.timezone(datetime.timedelta(hours=0)))
    @@ -39,11 +40,14 @@ def extract(filename, tz, verbose):
    if last_coordinates is not None and last_timestamp is not None:
    delta = geodesic(last_coordinates, (latitude, longitude)).km
    distance = distance + delta
    time_spent = (timestamp - last_timestamp).total_seconds() / 3600
    speed = delta / time_spent
    elapsed_time = (timestamp - first_timestamp).total_seconds()
    time_spent = (timestamp - last_timestamp).total_seconds()
    speed = 3600 * delta / time_spent
    if speed < threshold:
    stop_time = stop_time + time_spent
    formatted_stop_time = (datetime.datetime(1,1,1) + datetime.timedelta(seconds=stop_time)).strftime("%H:%M:%S")
    elapsed_time = (datetime.datetime(1,1,1) + (timestamp - first_timestamp)).strftime("%H:%M:%S")
    formatted_timestamp = timestamp.astimezone(datetime.timezone(datetime.timedelta(hours=tz))).strftime("%Y-%m-%d %H:%M:%S")
    line = "{0},{1:.0f},{2:.3f},{3:.1f},{4}".format(formatted_timestamp, elapsed_time, distance, speed, elevation)
    line = "{},{},{:.3f},{:.1f},{},{}".format(formatted_timestamp, elapsed_time, distance, speed, elevation, formatted_stop_time)
    if verbose:
    print(line)

    @@ -59,12 +63,13 @@ def get_options():
    parser = argparse.ArgumentParser(prog='SpeedTable by ClemRz', description='Extracts a CSV speed, elevation and distance table from a KML file.')
    parser.add_argument('filename', help='The path to the KML file')
    parser.add_argument('-tz', '--timezone', dest='timezone', default='0', help='The destination timezone')
    parser.add_argument('-th', '--threshold', dest='threshold', default='3', help='The speed threshold in km/h')
    parser.add_argument('-v', '--verbose', dest='verbose', help='Enables verbose output', action='store_true')
    return parser.parse_args()

    def main():
    options = get_options()
    extract(options.filename, float(options.timezone), options.verbose)
    extract(options.filename, float(options.timezone), float(options.threshold), options.verbose)

    if __name__ == '__main__':
    main()
  6. ClemRz created this gist Oct 1, 2018.
    21 changes: 21 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    # Extracts a CSV speed, elevation and distance table from a KML file.

    This is a Python script that extracts a table with several columns from a KML file: timestamp, elapsed time, distance, speed and elevation

    ## How to use this script

    Open a terminal and run:

    ```bash
    python3 script.py /path/to/your/file.kml
    ```

    For more help just run:

    ```bash
    python script.py -h
    ```

    ## Resulting file

    The output file is located in the same folder than the input one.
    70 changes: 70 additions & 0 deletions script.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,70 @@
    import xml.etree.ElementTree as etree
    import datetime
    from geopy.distance import geodesic
    import re
    import argparse

    def extract(filename, tz, verbose):
    ns = {"kml": "http://www.opengis.net/kml/2.2"}

    outfile = filename.split(".")[0] + ".csv"
    tree = etree.parse(filename)
    root = tree.getroot()

    track1 = root.find("kml:Document/kml:Folder[@id='Tracks']/kml:Folder[@id='track 1']", ns)
    points = track1.find("kml:Folder[@id='track 1 points']", ns)
    placemarks = points.findall("kml:Placemark", ns)
    placemarks_count = len(placemarks)
    last_coordinates = None
    last_timestamp = None
    first_timestamp = None
    distance = 0.0

    if verbose:
    print(f"Processing {placemarks_count} points")

    with open(outfile, 'w') as csv_file:
    csv_file.write("TimeStamp,Elapsed Time (s),Distance (km),Speed (km/h),Elevation (m)\n")

    for placemark in placemarks:
    timestamp = datetime.datetime.strptime(placemark.find("kml:TimeStamp/kml:when", ns).text, "%Y-%m-%dT%H:%M:%SZ").replace(tzinfo=datetime.timezone(datetime.timedelta(hours=0)))
    lng_lat_elev = placemark.find("kml:Point/kml:coordinates", ns).text.split(",")
    longitude = float(lng_lat_elev[0])
    latitude = float(lng_lat_elev[1])
    elevation = float(lng_lat_elev[2])

    if first_timestamp is None:
    first_timestamp = timestamp

    if last_coordinates is not None and last_timestamp is not None:
    delta = geodesic(last_coordinates, (latitude, longitude)).km
    distance = distance + delta
    time_spent = (timestamp - last_timestamp).total_seconds() / 3600
    speed = delta / time_spent
    elapsed_time = (timestamp - first_timestamp).total_seconds()
    formatted_timestamp = timestamp.astimezone(datetime.timezone(datetime.timedelta(hours=tz))).strftime("%Y-%m-%d %H:%M:%S")
    line = "{0},{1:.0f},{2:.3f},{3:.1f},{4}".format(formatted_timestamp, elapsed_time, distance, speed, elevation)
    if verbose:
    print(line)

    with open(outfile, 'a+') as csv_file:
    csv_file.write(f"{line}\n")

    last_coordinates = (latitude, longitude)
    last_timestamp = timestamp

    print(f"File {outfile} created.")

    def get_options():
    parser = argparse.ArgumentParser(prog='SpeedTable by ClemRz', description='Extracts a CSV speed, elevation and distance table from a KML file.')
    parser.add_argument('filename', help='The path to the KML file')
    parser.add_argument('-tz', '--timezone', dest='timezone', default='0', help='The destination timezone')
    parser.add_argument('-v', '--verbose', dest='verbose', help='Enables verbose output', action='store_true')
    return parser.parse_args()

    def main():
    options = get_options()
    extract(options.filename, float(options.timezone), options.verbose)

    if __name__ == '__main__':
    main()