#!/usr/bin/perl
# programming by Jochen Puchalla (c) 2007-2010
# mail at puchalla dash online dot de
# License: GPL V2
$pi=3.141592;
$g=9.81; # gravitation
$cw=0.4; # air resistance
$rho=1.2; # air density
$roll=0.003; # roll resistance
$every=3;
$bergmin=100;
$W=90; # kg total
foreach $file (@ARGV)
{
if (! open(INPUT,"<$file") )
{
print STDERR "Can't open input file $file\n";
next;
}
print STDOUT "\n$file:\n";
$filecore=$file;
$filecore =~ s/.gpx$//g;
if ($file eq $filecore)
{
print STDERR "$file is not a gpx file\n";
next;
}
# set values to 0 for every new file:
$sum_rise=0; # Steigmeter
$sum_fall=0; # Fallmeter
$sum_h=0; # Höhensumme
$sum_s=0; # Strecke
$sum_t=0; # Zeit
$maxcount=0;
$h_max=0;
$h_min=8848;
$s_max=0;
$v_max=0;
$n=0;
$punkte=1;
$anstieg=0;
$abfahrt=0;
while ($line=)
{
if ($line =~ /trkpt\ lat\=/)
{
@values = split(/\"/, $line);
$lat[$n]=$values[1];
$lon[$n]=$values[3];
$deltas = 1000 * sqrt( (($lat[$n]-$lat[$n-1])*$pi*6371/180) * (($lat[$n]-$lat[$n-1])*$pi*6371/180) + (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) * (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) );
if ($n==0) {$deltas=0;}
# printf STDOUT "delta s = %.0f \n",$deltas ;
# printf STDOUT "%5.2f %5.2f %5.2f %5.2f %5.2f \n" , $values[1], $values[2], $values[3], $values[4], $values[5];
$line=;
$line =~ s/e//g;
$line =~ s/l//g;
$line =~ s//g;
$line =~ s/>//g;
$line =~ s/\///g;
$line =~ s/\ //g;
$h[$n]=$line;
######### HÖHENGLÄTTUNG #########################
if ($n>0) {$h[$n]=($h[$n]+$h[$n-1]*12)/13;}
if ($h[$n] > $h_max) {$h_max=$h[$n];}
if ($h[$n] < $h_min) {$h_min=$h[$n];}
# printf STDOUT $line;
$line=;
$line =~ s/t//g;
$line =~ s/i//g;
$line =~ s/m//g;
$line =~ s/e//g;
$line =~ s/Z//g;
$line =~ s//g;
$line =~ s/>//g;
$line =~ s/\///g;
$line =~ s/\ //g;
$line2 = $line; # Kopie für Datum
$line =~ s/^.*T//g;
$line =~ s/[\n\r]$//g; # remove newline at end of string
if ( $n < 2 ) {$t_start = $line ;}
$t_ziel = $line ;
@values = split(/\:/, $line);
$seconds[$n]=$values[0]*3600+$values[1]*60+$values[2];
$time[$n]=$seconds[$n]-$seconds[0]; if ($time[$n]<0){$n=-1; $h_max=0; $h_min=8848;} # start all over
if ($deltas > 2000) {$n=-1; $h_max=0; $h_min=8848; } # start all over at big jumps
# printf STDOUT "%2.0f %2.0f %2.0f %6.0f \n" , $values[0], $values[1], $values[2], $time[$n];
$n++;
}
if ($line =~ /\<\/trk\>/) {last;}
if ($line =~ /\<\/rte\>/) {last;}
}
# Datum:
$line2 =~ s/T.*//g;
$line2 =~ s/[\n\r]$//g; # remove newline at end of string
@values = split(/-/, $line2);
$date="$values[2].$values[1].$values[0]";
$filedate="$values[0]$values[1]$values[2]";
printf STDOUT "Max. Height = %.0f m\n",$h_max ;
printf STDOUT "Min. Height = %.0f m\n",$h_min ;
$h_diff_total=$h_max-$h_min;
$maxcount=$n;
printf STDOUT "Data Points: %.0f \n",$maxcount ;
$h_finish=int($h[$n-1]);
printf STDOUT "Height at End = %.0f m\n",$h_finish ;
$h[0]=$h[1];
$s[0]=0;
$n=1;
while ($n < $maxcount)
{
# Abstand:
$deltas = 1000 * sqrt( (($lat[$n]-$lat[$n-1])*$pi*6371/180) * (($lat[$n]-$lat[$n-1])*$pi*6371/180) + (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) * (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) );
# Zeitdiff:
$deltat = $seconds[$n] - $seconds[$n-1];
# Distanz(n):
$s[$n] = $s[$n-1] + 1000 * sqrt( (($lat[$n]-$lat[$n-1])*$pi*6371/180) * (($lat[$n]-$lat[$n-1])*$pi*6371/180) + (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) * (6371*cos($pi/180*$lat[$n])*$pi*($lon[$n]-$lon[$n-1])/180) );
# Geschw.(n):
$v[$n] = 3.6 * ($s[$n] - $s[$n-1]) / ($seconds[$n] - $seconds[$n-1]);
# Glättung:
if ($n>1) {$v[$n] = 3.6 * ($s[$n] - $s[$n-2]) / ($seconds[$n] - $seconds[$n-2]);}
if ($n>2) {$v[$n] = 3.6 * ($s[$n] - $s[$n-3]) / ($seconds[$n] - $seconds[$n-3]);}
if ($n>3) {$v[$n] = 3.6 * ($s[$n] - $s[$n-4]) / ($seconds[$n] - $seconds[$n-4]);}
# summiere nur Daten mit mehr als 4 km/h
if ( $deltas / $deltat * 3.6 > 4 && $deltas / $deltat * 3.6 < 90)
{
# Zähler:
$punkte++;
# Gesamtstrecke:
$sum_s = $sum_s + $deltas;
# Höhensumme:
$sum_h = $sum_h + $h[$n];
# Nettozeit:
$sum_t = $sum_t + $deltat;
# v_max?
if ($v[$n]>$v_max) {$v_max=$v[$n];}
# if ($v_max>90) {$W=1300;}
# sum_rise?
if ($h[$n]>$h[$n-1]) {$sum_rise=$sum_rise+$h[$n]-$h[$n-1];}
# sum_fall?
if ($h[$n]<$h[$n-1]) {$sum_fall=$sum_fall+$h[$n-1]-$h[$n];}
if ($h[$n-2]<$h[$n-1] && $h[$n]<$h[$n-1]) {$maximum=$n; if ($h[$maximum]-$h[$minimum]>$bergmin) {$anstieg++;} }
if ($h[$n-2]>$h[$n-1] && $h[$n]>$h[$n-1]) {$minimum=$n; if ($h[$maximum]-$h[$minimum]>$bergmin) {$abfahrt++;} }
}
# printf STDOUT "v_max=%3.1f km/h\n",$v_max ;
# printf STDOUT "v=%d km/h\n",$v[$n] ;
# printf STDOUT "n=%d ",$n ;
# printf STDOUT "s=%5.3f ",$s[$n] ;
# printf STDOUT "h=%5.3f \n",$h[$n] ;
$n++;
}
if ($sum_t<1) {$sum_t=1;}
$h_med=$sum_h/$punkte ; # mittlere Höhe
$v_med=$sum_s/$sum_t ; # m/s
$power_med=$cw/2*$rho*($v_med*1.1)**3; # Leistung durch Luftwiderstand
$power_med=$power_med + $roll*$W*$g*($v_med*1.1); # Leistung durch Rollwiderstand
$v_med=$v_med*3.6 ; # km/h
$hours=int($sum_t/3600);
$minutes=int(($sum_t-$hours*3600)/60);
$secs=int($sum_t-$hours*3600-$minutes*60);
printf STDOUT "Distance = %.2f km\n",$sum_s/1000 ;
printf STDOUT "Net Time = %.1f h\n",$sum_t/3600 ;
printf STDOUT "Average Speed = %5.2f km/h\n",$v_med ;
printf STDOUT "Max. Speed = %.1f km/h\n",$v_max ;
printf STDOUT "Date: %s \n",$date ;
$h[1]=int($h[1]);
$sum_rise=int($sum_rise);
$h_max=int($h_max);
$s_max=int($sum_s);
$h[0]=$h[1];
$s[0]=$s[1];
# check for existing file:
if (-e "${filedate}_GPS.tour") { $filedate = "$filedate".'b';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'c';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'d';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'e';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'f';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'g';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'h';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'i';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'j';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'k';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'l';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'m';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'n';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'o';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'p';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'q';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'r';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'s';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'t';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'u';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'v';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'w';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'x';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'y';}
if (-e "${filedate}_GPS.tour") { chop($filedate); $filedate = "$filedate".'z';}
# open output file:
if (! open(OUTPUT,">${filedate}_GPS.tour") ) { print STDERR "Can't open output file ${filedate}_GPS.tour\n"; $bad++; next; }
print "Generating ${filedate}_GPS.tour\n";
printf OUTPUT ("HAC4Linux-Tour-File created by HAC4Linux (c) by Rick-Rainer Ludwig
#
# no, created by gpx2tour.pl (c) by Jochen Puchalla
#
######### File Format Discription #####################################
# This file contains information in ascii format. All data belongs to #
# a section startet by the sections name in rectangular brackets [ #
# and ]. The sections are collections of items which represent the #
# data stored in this file. An item is saved as the name, an equal #
# sign and the data directly behind (whithout any space!). #
# Comments are save with an # in front. Table lines start with an '!' #
# sign in front of the line and clumns are separated by tabs. #
#######################################################################
[FILE]
Version=0.1.0
[INFORMATION]
Number=1
");
printf OUTPUT ("Date=%s\n",$date);
printf OUTPUT ("Time=%s.00\n",$t_start);
printf OUTPUT ("Mode=46
RecTime=00:00:00.00
TimeDriven=");
printf OUTPUT ("%02.0f:%02.0f:%05.2f\n",$hours,$minutes,$secs);
printf OUTPUT ("Distance=%.0f\n",$sum_s);
printf OUTPUT ("Title=vom GPS
Start=Start
Finish=Ziel
[NOTES]
[FRIENDS]
[PERSON]
LastName=Puchalla
FirstName=Jochen
DateOfBirth=21.01.1975
SportsClub=
Equipment=Garmin GPS
MaxPulse=200
RestPulse=60
Weight=82
[STATISTICS]
");
printf OUTPUT ("Rosen=%.0f\n",$sum_rise);
printf OUTPUT ("Fallen=%.0f\n",$sum_fall);
printf OUTPUT ("Altitude=%.0f;%.0f;%.0f\n",$h_max,$h_med,$h_min);
printf OUTPUT ("Climb=25.00;1.00;0.00
Sink=-100.00;-1.00;0.00
");
printf OUTPUT ("CountClimb=%u\n",$anstieg);
printf OUTPUT ("CountSink=%u\n",$abfahrt);
printf OUTPUT ("Rise=10.00;1.00;0.00
Fall=-10.00;-1.00;0.00
Pulse=180;140;0
Speed=%2.2f;",$v_max);
printf OUTPUT ("%.2f",$v_med);
printf OUTPUT (";0.00
Temperature=00;00;00
Power=");
printf OUTPUT ("%.2f;%.2f",$power_med*2.5,$power_med);
printf OUTPUT (";0.00
Cadence=95;60;0
SkiSpeed=30.00;10.00;0.00
[SETTINGS]
DeviceShortName=
DateOfTransfer=00.00.00
DeltaTime=00:00:20.00
HomeAltitude=0
Weight=90
Distance1=111
HeightUp1=222
HeightDown1=333
TotalTime1=44:44:44.44
[POLAR-EXTENSIONS]
ActiveLimit=0
MaxVO2=0
StartDelay=0
[COACH-PARAMETER]
AverageHR=0
Flag=
IntervalAverageHR=0
IntervalTime=0
MaximumHR=0
ResultHR=0
ResultTime=0
TargetZone1=0;0;0;0;0;0;0;0;0
TargetZone2=0;0;0;0;0;0;0;0;0
TargetZone3=0;0;0;0;0;0;0;0;0
[TOUR-DATA]
#Pulse Cadence Temperature Altitude Marking Gradient Speed Distance ClimbSpeed AverageSpeed SkiSpeed Power Hour Minute Second
");
$n=$every; while ( $n < $maxcount )
{
$hours=int($time[$n]/3600);
$minutes=int(($time[$n]-$hours*3600)/60);
$secs=int($time[$n]-$hours*3600-$minutes*60);
$perc=($h[$n]-$h[$n-$every])/($s[$n]-$s[$n-$every])*100; # Durch Höhe ist auch Steigung geglättet
$vmed=($s[$n])/($time[$n])*3.6;
$power=$cw/2*$rho*($v[$n]/3.6)**3 + $roll*$W*$g*($v[$n]/3.6) ;#+ $W+$g*$mtrpermin/60; # ca. Leistung
$mtrpermin=($h[$n]-$h[$n-$every])/($time[$n]-$time[$n-$every])*60; # Durch Höhe ist auch Steiggeschw. geglättet
printf OUTPUT ("!0 0 11 %.0f 0 %.2f %.2f %.0f %.2f %.2f 0.00 %.2f %02.0f:%02.0f:%05.2f\n",$h[$n],$perc,$v[$n],$s[$n],$mtrpermin,$vmed,$power,$hours,$minutes,$secs);
$n=$n+$every; # jeder 2te Punkt ist immer noch höher auflösend als bei Ciclosport alle 20 s
}
printf OUTPUT ("
[MARKING-DATA]
");
close OUTPUT;
close INPUT;
}
exit(0);