geogpx has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I use geo::gpx to read GPS data. That works okay when i loop at the dumper output. Then i got stuck by the knowledge. How do i loop through "$tracks" and access eg. 'ele' to generate the average elevation per track like :

Output i'd like to have

Average elevation Track 1 = 72 Track 2 = 61

My Code

use Geo::Gpx; open $fh, "W20120129101405.gpx" ; my $gpx = Geo::Gpx->new( input => $fh ); my $tracks = $gpx->tracks(); print Dumper ($tracks);

Data Dump

-- OUTPUT --
$VAR1 = = [ { 'name' => 'Track 1', 'segments' => [ { 'points' => [ { 'lat' => '54.5182217145253', 'ele' => '73.0', 'lon' => '-2.62191579018834' }, { 'lat' => '54.1507759448355', 'lon' => '-3.05774931478646' 'ele' => '71.0', }, { 'lat' => '54.6016296784874', 'lon' => '-3.40418920968631' 'ele' => '72.0', } ] }, { 'points' => [ { 'lat' => '54.6862790450185', 'lon' => '-3.68760108982739' 'ele' => '63.0', } ] } ] }, { 'name' => 'Track 2', 'segments' => [ { 'points' => [ { 'lat' => '54.9927807628549', 'lon' => '-4.04712811256436' 'ele' => '60.0', }, { 'lat' => '55.1148395198045', 'lon' => '-4.33623533555793' 'ele' => '61.0', }, { 'lat' => '54.6214174046189', 'lon' => '-4.26293674042878' 'ele' => '62.0', }, { 'lat' => '55.0540816059084', 'lon' => '-4.42261020671926' 'ele' => '59.0', }, { 'lat' => '55.4451622411372', 'lon' => '-4.32873765338' 'ele' => '63.0', } ] } ] } ];

Replies are listed 'Best First'.
Re: how to access GPX data
by tobyink (Canon) on May 27, 2012 at 13:36 UTC
    use List::Util qw[sum]; foreach my $track (@$tracks) { my @points = map { @{$_->{points}} } @{ $track->{segments} }; my $count_of_points = @points; my $total_elevation = sum 0, map { $_->{ele} } @points; my $average = $total_elevation / $count_of_points; printf "%s = %d\n", $track->{name}, $average; }

    Though I get 69 for the average elevation of Track 1. You seem to be ignoring the fourth measurement (63.0). My code above does not ignore that.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      Thnx! that works great :) and yes, you're right about the average of track 1
Re: how to access GPX data
by kcott (Archbishop) on May 27, 2012 at 14:03 UTC

    Your "Output i'd like to have" for "Track 1" doesn't include the value from the second segment. You didn't indicate any exclusions so I've included this in my code below. I've used floating point numbers for the averages instead of integers.

    my $VAR1 = [ ... ]; # Dumper output you posted (s/VAR1 = = [/VAR1 = [/ +) print qq{Average elevation\n}; for my $track (@$VAR1) { print q{ }, $track->{name}, q{ = }; my $track_ele_total = 0; my $track_ele_count = 0; for my $segment (@{$track->{segments}}) { for my $point (@{$segment->{points}}) { ++$track_ele_count; $track_ele_total += $point->{ele}; } } printf qq{%06f\n} => $track_ele_total / $track_ele_count; }

    Which outputs:

    Average elevation Track 1 = 69.750000 Track 2 = 61.000000

    -- Ken

      Ken, Thnx, this gives some more info on how to access the other fields induvidualy. No doubt that will come in handy later