Skip Menu |

This queue is for tickets about the Geo-Gpx CPAN distribution.

Report information
The Basics
Id: 34458
Status: resolved
Priority: 0/
Queue: Geo-Gpx

People
Owner: Nobody in particular
Requestors: spurkis [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.21
Fixed in: (no value)



Subject: bounds() does not work as documented, and TO_JSON support
Thanks for a handy module! One small gripe: $gpx->bounds() does not work as documented - it requires an $iterator param. The attached patch fixes that by defaulting $iter to $self->iterate_points. I'd also like to see TO_JSON support in the module so it can be serialized with JSON:: modules, so I've implemented that too. The implementation could be more efficient by using Clone, but I couldn't be bothered to add another dependency. Both are tested. Hope this helps, -Steve
Subject: Geo-Gpx-0.21-json-bounds.patch
diff -ruN Geo-Gpx-0.21.orig/lib/Geo/Gpx.pm Geo-Gpx-0.21/lib/Geo/Gpx.pm --- Geo-Gpx-0.21.orig/lib/Geo/Gpx.pm 2008-03-26 19:05:42.000000000 +0000 +++ Geo-Gpx-0.21/lib/Geo/Gpx.pm 2008-03-26 21:28:10.000000000 +0000 @@ -411,6 +411,7 @@ sub bounds { my ( $self, $iter ) = @_; + $iter ||= $self->iterate_points; my $bounds = {}; @@ -612,6 +613,20 @@ return join( '', @ret ); } +# for JSON:: modules... +sub TO_JSON { + my $self = shift; + my %json; #= map {$_ => $self->$_} ... + foreach my $key (@META, @ATTR) { + my $val = $self->$key; + $json{$key} = $val if defined( $val ); + } + if (my $bounds = $self->bounds) { + $json{bounds} = $self->bounds; + } + return \%json; +} + #### Legacy methods from 0.10 sub gpx { @@ -689,7 +704,7 @@ been extended to support general parsing and generation of GPX data. GPX 1.0 and 1.1 are supported. -=head1 INTERFACE +=head1 INTERFACE =over @@ -705,24 +720,24 @@ New applications can use C<Geo::Gpx> to parse a GPX file: my $gpx = Geo::Gpx->new( xml => $gpx_document ); - + or from an open filehandle: my $gpx = Geo::Gpx->new( input => $fh ); - + or can create an empty container to which waypoints, routes and tracks can then be added: my $gpx = Geo::Gpx->new(); $gpx->waypoints( \@wpt ); -=item C<bounds()> +=item C<bounds( [ $iterator ] )> Compute the bounding box of all the points in a C<Geo::Gpx> returning the result as a hash reference. For example: my $gpx = Geo::Gpx->new( xml => $some_xml ); my $bounds = $gpx->bounds(); - + returns a structure like this: $bounds = { @@ -732,12 +747,14 @@ maxlon => -1.230902 }; +C<$iterator> defaults to C<$self-E<gt>iterate_points>. + =item C<name( [ $newname ] )> Accessor for the <name> element of a GPX. To get the name: my $name = $gpx->name(); - + and to set it: $gpx->name('My big adventure'); @@ -747,7 +764,7 @@ Accessor for the <desc> element of a GPX. To get the the description: my $desc = $gpx->desc(); - + and to set it: $gpx->desc('Got lost, wandered around for ages, got cold, got hungry.'); @@ -775,7 +792,7 @@ $gpx->author({ name => 'Me!' }); - + The bizarre encoding of email addresses as id and domain is a feature of GPX. =item C<time( [ $newtime ] )> @@ -822,7 +839,7 @@ 'text' => 'Hexten', 'href' => 'http://hexten.net/' }; - + For example: $gpx->link({ href => 'http://google.com/', text => 'Google' }); @@ -859,7 +876,7 @@ ageofdgpsdata => 45, dgpsid => 247 }; - + All fields apart from C<lat> and C<lon> are optional. See the GPX specification for an explanation of the fields. The waypoints array is an anonymous array of such points: @@ -1049,7 +1066,7 @@ my $gpx10 = $gpx->xml('1.0'); my $gpx11 = $gpx->xml('1.1'); - + If the version is omitted it defaults to the value of the C<version> attibute. Parsing a GPX document sets the version. If the C<version> attribute is unset defaults to 1.0. @@ -1061,6 +1078,18 @@ C<Geo::Cache> points to the constructor; this should probably be avoided for new applications. +=item C<TO_JSON> + +For compatability with L<JSON> modules. Converts this object to a hash with +keys that correspond to the above methods. Generated ala: + + my %json = map {$_ => $self->$_} + qw(name desc author keywords copyright + time link waypoints tracks routes version ); + $json{bounds} = $self->bounds( $iter ); + +With one difference: the keys will only be set if they are defined. + =item C<gpx> Synonym for C<xml()>. Provided for compatibility with version 0.10. @@ -1107,7 +1136,7 @@ =head1 SEE ALSO -L<Geo::Cache> +L<Geo::Cache>, L<JSON> =head1 BUGS AND LIMITATIONS @@ -1152,3 +1181,5 @@ FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +=cut diff -ruN Geo-Gpx-0.21.orig/t/05.misc.t Geo-Gpx-0.21/t/05.misc.t --- Geo-Gpx-0.21.orig/t/05.misc.t 2008-03-26 19:05:42.000000000 +0000 +++ Geo-Gpx-0.21/t/05.misc.t 2008-03-26 21:28:10.000000000 +0000 @@ -1,16 +1,17 @@ use strict; use warnings; -use Test::More tests => 5; +use Test::More tests => 9; use Geo::Gpx; +my $time = time(); my @wpt = ( { # All standard GPX fields lat => 54.786989, lon => -2.344214, ele => 512, - time => time(), + time => $time, magvar => 0, geoidheight => 0, name => 'My house & home', @@ -59,3 +60,46 @@ like $@, qr/mandatory in waypoint/, "mandatory lat, lon OK"; } } + +{ + my $gpx = Geo::Gpx->new; + $gpx->add_waypoint( @wpt ); + my $iter = $gpx->iterate_points; + my $bounds = { + 'maxlat' => 54.786989, + 'maxlon' => -2.344214, + 'minlat' => -38.870059, + 'minlon' => -151.21003, + }; + is_deeply $gpx->bounds, $bounds, "gpx->bounds doesn't require an iterator"; +} + +{ + my $gpx = Geo::Gpx->new; + $gpx->add_waypoint( @wpt ); + my $iter = $gpx->iterate_points; + my $expect = { + waypoints => \@wpt, + bounds => { + 'maxlat' => 54.786989, + 'maxlon' => -2.344214, + 'minlat' => -38.870059, + 'minlon' => -151.21003, + }, + time => $time, + }; + is_deeply $gpx->TO_JSON, $expect, "TO_JSON"; + $gpx->name( 'spurkis' ); + $expect->{name} = 'spurkis'; + is_deeply $gpx->TO_JSON, $expect, "TO_JSON now has a name"; + + SKIP: { + eval "use JSON"; + skip 'JSON not installed', 1 if $@; + + my $coder = JSON->new->allow_blessed->convert_blessed; + my $json = $coder->encode( $gpx ); + my $json2 = $coder->encode( $expect ); + is_deeply $json, $json2, "works with JSON module"; + }; +}
Thanks Steve. Applied (with minor modifications) as r16.