Etrex mimo, że nie ma barometru dość sensownie podaje wysokość npm. Jakoś do tej pory umknęło to mojej uwadze.
Poniżej skrypt wyznaczający długość trasy, łączną sumę wysokości
podjazdów (przewyższenie, aka
cumulative elevation gain)
oraz
rysujący profil w postaci pliku PNG. To ostatnie niekoniecznie jest
sensowne, bo GD::Graph::lines
traktuje dane z osi OX jako napisy
a nie liczby i w związku
z tym odstępy między poszczególnymi punktami na tej osi są równe.
Zamiast GD::Graph::lines
trzeba użyć czegoś innego,
np. Chart::Graph::Gnuplot.
#!/usr/bin/perl # # Tworzy plik PNG przedstawiający profil śladu (wysokość mnpm) # z danych podanych (jako argument skryptu) w pliku GPX # tprzechlewski[_at_]gmail.com sierpień/2008 # use XML::LibXML; use Geo::Distance; use Getopt::Long; GetOptions( 'log' => \$print_log, 'pic' => \$print_pic, ); $usage = "Usage: $0 [-p | -l] plik.gpx ;; -p generate PNG file ; -l show log.\n"; my $geo = new Geo::Distance; my $file = shift || die "$usage"; my $parser = XML::LibXML->new; open my $fh, $file || die "problems..."; $doc = $parser->parse_fh($fh); my @tracks = $doc->getElementsByTagName('trk'); my $ptnum=0; for $tx (@tracks) { @segments = $tx->getChildrenByTagName('trkseg'); if ( $name = $tx->getChildrenByTagName('name')->[0] ) { # pierwszy element to nazwa śladu if ($print_log) { print "<!-- track:: ", $name->textContent(), " -->\n"; } } for $sx (@segments) { @points = $sx->getChildrenByTagName('trkpt'); for $px (@points) { @data = $px->getChildrenByTagName('*'); @attrs = $px->attributes(); if ($print_log) { print "-> " ; } for $dx (@data) { if ($print_log) { print $dx->nodeName, " = ", $dx->textContent(), " ; " ; } if ($dx->nodeName eq 'ele') { $ele = $dx->textContent(); push @Elevations, $ele; } } for $ax (@attrs) { if ($print_log) { print " ", $ax->nodeName, " = ", $ax->getValue() ; } if ($ax->nodeName eq 'lon') { $lon = $ax->textContent() } elsif ($ax->nodeName eq 'lat') { $lat = $ax->textContent() } } if ($print_log) { print " ;;\n"; } if ( $ptnum > 0 ) { $curr_dist = $geo->distance( "meter", $plon, $plat => $lon, $lat ); $dist += $curr_dist ; push @Distances, $curr_dist; if (($ele_diff = $ele - $pele ) > 0) { $totalEleGain += $ele_diff ; } } else { push @Distances, 0; } $plon = $lon; $plat = $lat ; $pele = $ele ; $ptnum++; } } } # http://en.wikipedia.org/wiki/Cumulative_elevation_gain (przewyższenie): printf "*** Dist: %.1f meters *** EleGain: $totalEleGain ***\n", $dist; ## Drukowanie profilu trasy unless ( $print_pic ) { exit 0 } use GD::Graph::lines; use POSIX; # floor my $img_file = "${file}.png" ; my @data = (\@Distances, \@Elevations, ); my $mygraph = GD::Graph::lines->new(400, 300); # skip some dates to avoid label overlapping on X-axis: my $x_factor = floor (($#Distances + 1) / 10 ) + 2; print "$#Distances observations. X-axis labels printed evey ${x_factor}th one!\n"; $mygraph->set_text_clr('black'); $mygraph->set( x_label => 'Dist', y_label => '#', title => "# Elev", # Draw datasets in 'solid', 'dashed' and 'dotted-dashed' lines line_types => [1, 1, ], # Set the thickness of line line_width => 2, # Set colors for datasets dclrs => ['blue', 'red', 'cyan'], #x_tick_number => 'auto', x_label_skip => $x_factor, transparent => 0, ## non-transparent bgclr => 'white', fgclr => 'black', borderclrs => 'black', boxclr => '#ede7e7', labelclr => 'black', #axislabelclr, legendclr => 'black', ) or warn $mygraph->error; $mygraph->set_legend_font(GD::gdMediumBoldFont); $mygraph->set_legend('ele', 'ele2', '???'); my $myimage = $mygraph->plot(\@data) or die $mygraph->error; ## for cgi script uncomment: ##print "Content-type: image/png\n\n"; open ( IMG, ">$img_file") or die " *** Problems opening: $img_file ***" ; print IMG $myimage->png; close (IMG); ##print "@Distances\n"; ## debug ##
Wykorzystuję od jakiegoś czasu XML::LibXML
.
W skryptach do obsługi flickr.com korzystałem z XML::Simple
ale do parsowania plików GPX ten pakiet
się nie nadaje -- nie zachowuje porządku elementów (bo je czyta do hasza).
W oczywisty sposób porządek punktów na śladzie nie może być dowolny.
A tutaj ktoś zrobił coś podobnego tyle, że używając Pythona.
Jak nie zapiszę, to zapomnę. Już kiedyś znalazłem serwis pozwalający on-line na tworzenie tras (routes) w formacie GPX za pomocą klikania w GoogleMaps. Nie zapisałem i oczywiście nie mogłem go znaleźć przez dłuższą chwilę. W końcu jest: http://www.gmap-pedometer.com/. Moja przykładowa trasa: Brodnica-BachotekUMK. IMHO czasami może się okazać przydatne...