# -*- coding: utf-8 -*- from google.colab import drive drive.mount('/content/drive') import math import os import re DIR = '/content/drive/MyDrive/ul/python' with open(os.path.join(DIR, "route-ea1d16ac.gpx"), encoding='utf8') as rawData: pattern = r'[\S\n ]*?(?P[\d]+)' reCompiled = re.compile(pattern) lines = rawData.readlines() text = "".join(lines) result = re.findall(reCompiled, text) counter = 0 if result: with open(os.path.join(DIR, "data.csv"), 'w') as fileOut: for lat, lon, elev in result: record = f"{lat},{lon},{elev}\n" fileOut.write(record) counter += 1 print(counter) constants = { "DEG_TO_RAD": math.pi/180.0, "phase1": True, "phase2": True } ''' This uses the ‘haversine’ formula. From: https://www.movable-type.co.uk/scripts/latlong.html ''' def distance(lat1, lon1, lat2, lon2, constants): R = 6371000.0 phi1 = lat1 * constants["DEG_TO_RAD"] phi2 = lat2 * constants["DEG_TO_RAD"] deltaPhi = (lat2-lat1) * constants["DEG_TO_RAD"]; deltaLambda = (lon2-lon1) * constants["DEG_TO_RAD"]; a = (math.sin(deltaPhi/2.0) * math.sin(deltaPhi/2.0) + math.cos(phi1) * math.cos(phi2) * math.sin(deltaLambda/2.0) * math.sin(deltaLambda/2.0)) c = 2.0 * math.atan2(math.sqrt(a), math.sqrt(1-a)) d = R * c return d def extraDistance(elev): # 100m of ascent = 1000m on flat surface # 1m of ascent = 10m on flat surface # return tuple: # (abs_elev, ascent, descent) return (abs(elev * 10.0), elev if elev > 0 else 0, -elev if elev < 0 else 0) def calculateSlope(dist,elev): if dist == 0: return 0 return elev / dist * 100.0 def phase(distanceAccPlusExtra, constants): if constants["phase1"] and (distanceAccPlusExtra/1000.0 > 973.0/3.0): constants["phase1"] = False return True if constants["phase2"] and (distanceAccPlusExtra/1000.0 > (973.0/3.0) * 2.0): constants["phase2"] = False return True return False fileInPath = os.path.join(DIR, "data.csv") fileOutPath = os.path.join(DIR, "results.csv") constants["phase1"] = True constants["phase2"] = True with open(fileInPath, encoding='utf8') as fileIn: with open(fileOutPath, "wt", encoding='utf8') as fileOut: line = fileIn.readline() line = line.strip() data = line.split(",") lat = data[0] lon = data[1] elev = data[2] distanceExtraTotal = 0 ascentTotal = 0 descentTotal = 0 distanceAcc = 0 d = 0 e = 0 ascent = 0 descent = 0 distanceExtra = 0 distanceAccPlusExtra = 0 slope = calculateSlope(float(d), float(e)) record = f"latitude,longitude,elevation,distance,accumulated distanceAcc,delta elevation,slope,ascent,descent,distance extra,accumulated distance + extra distance\n" fileOut.write(record) record = f"{lat},{lon},{elev},{d},{distanceAcc},{e},{slope},{ascent},{descent},{distanceExtra},{distanceAccPlusExtra}\n" fileOut.write(record) lastElev = elev lastLat = lat lastLon = lon counter = 1 while line: data = line.split(",") lat = data[0] lon = data[1] elev = data[2] d = distance(float(lat), float(lon), float(lastLat), float(lastLon), constants) e = int(elev)-int(lastElev) distanceExtra, ascent, descent = extraDistance(e) distanceExtraTotal += distanceExtra ascentTotal += ascent descentTotal += descent distanceAcc += d distanceAccPlusExtra += d + distanceExtra slope = calculateSlope(float(d), float(e)) record = f"{lat},{lon},{elev},{d},{distanceAcc},{e},{slope},{ascent},{descent},{distanceExtra},{distanceAccPlusExtra}\n" fileOut.write(record) lastElev = elev lastLat = lat lastLon = lon counter += 1 if phase(distanceAccPlusExtra, constants): print(f"{counter},{lat},{lon},{elev},{d},{distanceAcc/1000.0}km,{e},{slope},{ascent},{descent},{distanceExtra},{distanceAccPlusExtra/1000.0}km") line = fileIn.readline() line = line.strip() print("Done") print("Lines = ", counter, sep='') print("Total distance = ", distanceAcc/1000.0, "km", sep='') print("distanceExtraTotal = ", distanceExtraTotal/1000.0,"km", sep='') print("ascentTotal = ", ascentTotal/1000.0,"km", sep='') print("descentTotal = ", descentTotal/1000.0,"km", sep='') print("distanceAccPlusExtra = ", distanceAccPlusExtra/1000.0,"km", sep='') import pandas as pd fileDataCSV = os.path.join(DIR, "results.csv") df=pd.read_csv(fileDataCSV)#, sep=",", header = None) df df.info() df['slope'] slope = df['slope'] slope.hist() slope.hist(bins=50) slope.hist(bins=150) slope.hist(bins=500) slopeMean = slope.mean() slopeMean slopeMode = slope.mode() slopeMode