.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Geo::Gpx 3pm" .TH Geo::Gpx 3pm "2023-11-25" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Geo::Gpx \- Create and parse GPX files .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& my ($gpx, $waypoints, $tracks); \& \& # From a filename, an open file, or an XML string: \& \& $gpx = Geo::Gpx\->new( input => $fname ); \& $gpx = Geo::Gpx\->new( input => $fh ); \& $gpx = Geo::Gpx\->new( xml => $xml ); \& \& my $waypoints = $gpx\->waypoints(); \& my $tracks = $gpx\->tracks(); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\f(CW\*(C`Geo::Gpx\*(C'\fR supports the parsing and generation of \s-1GPX\s0 data. .SS "Constructor" .IX Subsection "Constructor" .ie n .IP "new( input => ($fname | $fh) or xml => $xml [, work_dir => $working_directory ] )" 4 .el .IP "new( input => ($fname | \f(CW$fh\fR) or xml => \f(CW$xml\fR [, work_dir => \f(CW$working_directory\fR ] )" 4 .IX Item "new( input => ($fname | $fh) or xml => $xml [, work_dir => $working_directory ] )" Create and return a new \f(CW\*(C`Geo::Gpx\*(C'\fR instance based on a *.gpx file (\fI\f(CI$fname\fI\fR), an open filehandle (\fI\f(CI$fh\fI\fR), or an \s-1XML\s0 string (\fI\f(CI$xml\fI\fR). \s-1GPX 1.0\s0 and 1.1 are supported. .Sp The optional \f(CW\*(C`work_dir\*(C'\fR (or \f(CW\*(C`wd\*(C'\fR for short) specifies where to save any working files, such as with the \fBsave()\fR method. It can be supplied as a relative path or as an absolute path. If \f(CW\*(C`work_dir\*(C'\fR is omitted, it is set based on the path of the \fI\f(CI$fname\fI\fR supplied or the current working directory if the constructor is called with an \s-1XML\s0 string or a filehandle (see \f(CW\*(C`set_wd()\*(C'\fR for more info). .IP "\fBclone()\fR" 4 .IX Item "clone()" Returns a deep copy of a \f(CW\*(C`Geo::Gpx\*(C'\fR instance. .Sp .Vb 1 \& $clone = $self\->clone; .Ve .SS "Methods" .IX Subsection "Methods" .ie n .IP "waypoints( $int or name => $name )" 4 .el .IP "waypoints( \f(CW$int\fR or name => \f(CW$name\fR )" 4 .IX Item "waypoints( $int or name => $name )" Without arguments, returns the array reference of waypoints. .Sp With an argument, returns a reference to the waypoint whose \f(CW\*(C`name\*(C'\fR field is an exact match with \fI\f(CI$name\fI\fR. If an integer is specified instead of the \f(CW\*(C`name\*(C'\fR key/value pair, returns the waypoint at position \fI\f(CI$int\fI\fR in the array reference (1\-indexed with negative integers also counting from the end of the array). .Sp Returns \f(CW\*(C`undef\*(C'\fR if no corresponding waypoints are found such that this method can be used to check if a specific point exists (i.e. no exception is raised if \fI\f(CI$name\fI\fR or \fI\f(CI$int\fI\fR do not exist) . .ie n .IP "waypoints_add( $point or \e%point [, $point or \e%point, X ] )" 4 .el .IP "waypoints_add( \f(CW$point\fR or \e%point [, \f(CW$point\fR or \e%point, X ] )" 4 .IX Item "waypoints_add( $point or %point [, $point or %point, X ] )" Add one or more waypoints. Each waypoint must be either a Geo::Gpx::Point or a hash reference with fields that can be parsed by Geo::Gpx::Point's \f(CW\*(C`new()\*(C'\fR constructor. See the later for the possible fields. .Sp .Vb 2 \& %point = ( lat => 54.786989, lon => \-2.344214, ele => 512, name => \*(AqMy house\*(Aq ); \& $gpx\->waypoints_add( \e%point ); \& \& or \& \& $pt = Geo::Gpx::Point\->new( %point ); \& $gpx\->waypoints_add( $pt ); .Ve .ie n .IP "waypoints_search( $field => $regex )" 4 .el .IP "waypoints_search( \f(CW$field\fR => \f(CW$regex\fR )" 4 .IX Item "waypoints_search( $field => $regex )" returns an array of waypoints whose \fI\f(CI$field\fI\fR (e.g. \f(CW\*(C`name\*(C'\fR, \f(CW\*(C`desc\*(C'\fR, X) matches \fI\f(CI$regex\fI\fR. By default, the regex is case-sensitive; specify \f(CW\*(C`qr/(?i:search_string_here)/\*(C'\fR to ignore case. .ie n .IP "waypoints_clip( $name | $regex | \s-1LIST\s0 )" 4 .el .IP "waypoints_clip( \f(CW$name\fR | \f(CW$regex\fR | \s-1LIST\s0 )" 4 .IX Item "waypoints_clip( $name | $regex | LIST )" .PD 0 .IP "way_clip( )" 4 .IX Item "way_clip( )" .PD Sends the coordinates of the waypoint(s) whose name is either \f(CW$name\fR or matches \f(CW$regex\fR to the clipboard (all points found are sent to the clipboard) and returns an array of points found. By default, the regex is case-sensitive; specify \f(CW\*(C`qr/(?i:...)/\*(C'\fR to ignore case. .Sp Alternatively, an array of \f(CW\*(C`Geo::GXP::Points\*(C'\fR can be provided. \f(CW\*(C`way_clip()\*(C'\fR is a short-hand for this method (convenient when used interactively in the debugger). .Sp This method is only supported on unix-based systems that have the \f(CW\*(C`xclip\*(C'\fR utility installed (see \s-1DEPENDENCIES\s0). .IP "\fBwaypoints_delete_all()\fR" 4 .IX Item "waypoints_delete_all()" delete all waypoints. Returns true. .ie n .IP "waypoint_delete( $name )" 4 .el .IP "waypoint_delete( \f(CW$name\fR )" 4 .IX Item "waypoint_delete( $name )" delete the waypoint whose \f(CW\*(C`name\*(C'\fR field is an exact match for \fI\f(CI$name\fI\fR (case sensitively). Returns true if successful, \f(CW\*(C`undef\*(C'\fR if the name cannot be found. .ie n .IP "waypoint_rename( $name, $new_name )" 4 .el .IP "waypoint_rename( \f(CW$name\fR, \f(CW$new_name\fR )" 4 .IX Item "waypoint_rename( $name, $new_name )" rename the waypoint whose \f(CW\*(C`name\*(C'\fR field is an exact match for \fI\f(CI$name\fI\fR (case sensitively) to \fI\f(CI$new_name\fI\fR. Returns the point's new name if successful, \f(CW\*(C`undef\*(C'\fR otherwise. .ie n .IP "waypoints_merge( $gpx, $regex )" 4 .el .IP "waypoints_merge( \f(CW$gpx\fR, \f(CW$regex\fR )" 4 .IX Item "waypoints_merge( $gpx, $regex )" Merge waypoints with those contained in the Geo::Gpx instance provide as argument. Waypoints are compared based on their respective \f(CW\*(C`name\*(C'\fR fields, which must exist in \fI\f(CI$gpx\fI\fR (if names are missing in the current instance, all points will be merged). .Sp A \fI\f(CI$regex\fI\fR may be provided to limit the merge to a subset of waypoints from \fI\f(CI$gpx\fI\fR. .Sp Returns the number of points successfully merged (i.e. the difference in \f(CW\*(C`$gps\->waypoints_count\*(C'\fR before and after the merge). .ie n .IP "waypoint_closest_to( $point of $tcx_trackpoint )" 4 .el .IP "waypoint_closest_to( \f(CW$point\fR of \f(CW$tcx_trackpoint\fR )" 4 .IX Item "waypoint_closest_to( $point of $tcx_trackpoint )" From any Geo::Gpx::Point or Geo::TCX::Trackpoint object, return the waypoint that is closest to it. If called in list context, returns a two-element array consisting of that waypoint, and the distance from the coordinate (in meters). .IP "\fBwaypoints_print()\fR" 4 .IX Item "waypoints_print()" print the list of waypoints to screen, along with their names and descriptions if defined. Returns true. .IP "\fBwaypoints_count()\fR" 4 .IX Item "waypoints_count()" returns the number of waypoints in the object. .IP "routes( integer or name => 'name' )" 4 .IX Item "routes( integer or name => 'name' )" Returns the array reference of routes when called without argument. Optionally accepts a single integer referring to the route number from routes aref (1\-indexed with negative integers also counting from the end of the array) or a key value pair with the name of the route to be returned. .ie n .IP "routes_add( $route or $points_aref [, name => $route_name )" 4 .el .IP "routes_add( \f(CW$route\fR or \f(CW$points_aref\fR [, name => \f(CW$route_name\fR )" 4 .IX Item "routes_add( $route or $points_aref [, name => $route_name )" Add a route to a \f(CW\*(C`Geo::Gpx\*(C'\fR object. The \fI\f(CI$route\fI\fR is expected to be an existing route (i.e. a hash ref). Returns true. A new route can also be created based an array reference(s) of Geo::Gpx::Point objects and added to the \f(CW\*(C`Geo::Gpx\*(C'\fR instance. .Sp \&\f(CW\*(C`name\*(C'\fR and all other meta fields supported by routes can be provided and will overwrite any existing fields in \fI\f(CI$route\fI\fR. .IP "\fBroutes_delete_all()\fR" 4 .IX Item "routes_delete_all()" delete all routes. Returns true. .IP "\fBroutes_count()\fR" 4 .IX Item "routes_count()" returns the number of routes in the object. .IP "tracks( integer or name => 'name' )" 4 .IX Item "tracks( integer or name => 'name' )" Returns the array reference of tracks when called without argument. Optionally accepts a single integer referring to the track number from the tracks aref (1\-indexed with negative integers also counting from the end of the array) or a key value pair with the name of the track to be returned. .ie n .IP "tracks_add( $track or $points_aref [, $points_aref, X ] [, name => $track_name ] )" 4 .el .IP "tracks_add( \f(CW$track\fR or \f(CW$points_aref\fR [, \f(CW$points_aref\fR, X ] [, name => \f(CW$track_name\fR ] )" 4 .IX Item "tracks_add( $track or $points_aref [, $points_aref, X ] [, name => $track_name ] )" Add a track to a \f(CW\*(C`Geo::Gpx\*(C'\fR object. The \fI\f(CI$track\fI\fR is expected to be an existing track (i.e. a hash ref). Returns true. .Sp If \fI\f(CI$track\fI\fR has no \f(CW\*(C`name\*(C'\fR field and none is provided, the timestamp of the first point of the track will be used (this is experimental and may change in the future). All other fields supported by tracks can be provided and will overwrite any existing fields in \fI\f(CI$track\fI\fR. .Sp A new track can also be created based an array reference(s) of Geo::Gpx::Point objects and added to the \f(CW\*(C`Geo::Gpx\*(C'\fR instance. If more than one array reference is supplied, the resulting track will contain as many segments as the number of aref's provided. .IP "\fBtracks_delete_all()\fR" 4 .IX Item "tracks_delete_all()" delete all tracks. Returns true. .ie n .IP "track_delete( $name )" 4 .el .IP "track_delete( \f(CW$name\fR )" 4 .IX Item "track_delete( $name )" delete the track whose \f(CW\*(C`name\*(C'\fR field is an exact match for \fI\f(CI$name\fI\fR (case sensitively). Returns true if successful, \f(CW\*(C`undef\*(C'\fR if the name cannot be found. .ie n .IP "track_rename( $name, $new_name )" 4 .el .IP "track_rename( \f(CW$name\fR, \f(CW$new_name\fR )" 4 .IX Item "track_rename( $name, $new_name )" rename the track whose \f(CW\*(C`name\*(C'\fR field is an exact match for \fI\f(CI$name\fI\fR (case sensitively) to \fI\f(CI$new_name\fI\fR. Returns the track's new name if successful, \f(CW\*(C`undef\*(C'\fR otherwise. .Sp Alternatively, an integer may be specified as the first argument, referring to the track number from tracks aref (1\-indexed). This is a convenience as it is quite common for tracks to be named with the timestamp fo the first point. .IP "\fBtracks_print()\fR" 4 .IX Item "tracks_print()" print the list of tracks to screen, by their \f(CW\*(C`name\*(C'\fR field. Returns true. .IP "\fBtracks_count()\fR" 4 .IX Item "tracks_count()" returns the number of tracks in the object. .IP "\fBiterate_waypoints()\fR" 4 .IX Item "iterate_waypoints()" .PD 0 .IP "\fBiterate_trackpoints()\fR" 4 .IX Item "iterate_trackpoints()" .IP "\fBiterate_routepoints()\fR" 4 .IX Item "iterate_routepoints()" .PD Get an iterator for all of the waypoints, trackpoints, or routepoints in a \f(CW\*(C`Geo::Gpx\*(C'\fR instance, as per the iterator chosen. .IP "\fBiterate_points()\fR" 4 .IX Item "iterate_points()" Get an iterator for all of the points in a \f(CW\*(C`Geo::Gpx\*(C'\fR instance, including waypoints, trackpoints, and routepoints. .Sp .Vb 4 \& my $iter = $gpx\->iterate_points(); \& while ( my $pt = $iter\->() ) { \& print "Point: ", join( \*(Aq, \*(Aq, $pt\->{lat}, $pt\->{lon} ), "\en"; \& } .Ve .ie n .IP "bounds( $iterator )" 4 .el .IP "bounds( \f(CW$iterator\fR )" 4 .IX Item "bounds( $iterator )" Compute the bounding box of all the points in a \f(CW\*(C`Geo::Gpx\*(C'\fR returning the result as a hash reference. .Sp .Vb 2 \& my $gpx = Geo::Gpx\->new( xml => $some_xml ); \& my $bounds = $gpx\->bounds(); .Ve .Sp returns a structure like this: .Sp .Vb 6 \& $bounds = { \& minlat => 57.120939, \& minlon => \-2.9839832, \& maxlat => 57.781729, \& maxlon => \-1.230902 \& }; .Ve .Sp \&\f(CW$iterator\fR defaults to \f(CW\*(C`$self\->iterate_points\*(C'\fR if not specified. .ie n .IP "xml( $version )" 4 .el .IP "xml( \f(CW$version\fR )" 4 .IX Item "xml( $version )" Generate and return an \s-1XML\s0 string representation of the instance. .Sp If the version is omitted it defaults to the value of the \f(CW\*(C`version\*(C'\fR attribute. Parsing a \s-1GPX\s0 document sets the version. If the \f(CW\*(C`version\*(C'\fR attribute is unset defaults to 1.0. .IP "\s-1TO_JSON\s0" 4 .IX Item "TO_JSON" For compatibility with \s-1JSON\s0 modules. Convert this object to a hash with keys that correspond to the above methods. Generated ala: .Sp .Vb 4 \& my %json = map { $_ => $self\->$_ } \& qw( name desc author keywords copyright \& time link waypoints tracks routes version ); \& $json{bounds} = $self\->bounds( $iter ); .Ve .Sp With one difference: the keys will only be set if they are defined. .ie n .IP "save( filename => $fname, key/values )" 4 .el .IP "save( filename => \f(CW$fname\fR, key/values )" 4 .IX Item "save( filename => $fname, key/values )" Saves the \f(CW\*(C`Geo::Gpx\*(C'\fR instance as a file. .Sp The filename field is optional unless the instance was created without a filename (i.e with an \s-1XML\s0 string or a filehandle) and \f(CW\*(C`set_filename()\*(C'\fR has not been called yet. If the filename is a relative path, the file will be saved in the instance's working directory (not the caller's, \f(CW\*(C`Cwd\*(C'\fR). .Sp \&\fIkey/values\fR are (all optional): .Sp \f(CW\*(C`force\*(C'\fR: overwrites existing files if true, otherwise it won't. \f(CW\*(C`extensions\*(C'\fR: save \f(CW\*(C`X\*(C'\fR tags if true (defaults to false). \f(CW\*(C`meta_time\*(C'\fR: save the \f(CW\*(C`\*(C'\fR tag in the file's meta information tags if true (defaults to false). Some applications like MapSource return an error if this tags is present. (All other time tags elsewhere are kept.) .ie n .IP "set_filename( $filename )" 4 .el .IP "set_filename( \f(CW$filename\fR )" 4 .IX Item "set_filename( $filename )" Sets/gets the filename. Returns the name of the file with the complete path. .ie n .IP "set_wd( $folder )" 4 .el .IP "set_wd( \f(CW$folder\fR )" 4 .IX Item "set_wd( $folder )" Sets/gets the working directory for any eventual saving of the *.gpx file and checks the validity of that path. It can be set as a relative path (i.e. relative to the actual Cwd) or as an absolute path, but is always returned as a full path. .Sp This working directory is always defined. The previous one is also stored in memory, such that \f(CW\*(C`set_wd(\*(Aq\-\*(Aq)\*(C'\fR switches back and forth between two directories. The module never actually \f(CW\*(C`chdir\*(C'\fR's, it just keeps track of where the user wishes to save files. .SS "Accessors" .IX Subsection "Accessors" .ie n .IP "name( $str )" 4 .el .IP "name( \f(CW$str\fR )" 4 .IX Item "name( $str )" .PD 0 .ie n .IP "desc( $str )" 4 .el .IP "desc( \f(CW$str\fR )" 4 .IX Item "desc( $str )" .ie n .IP "copyright( $str )" 4 .el .IP "copyright( \f(CW$str\fR )" 4 .IX Item "copyright( $str )" .ie n .IP "keywords( $aref )" 4 .el .IP "keywords( \f(CW$aref\fR )" 4 .IX Item "keywords( $aref )" .PD Accessors to get or set the \f(CW\*(C`name\*(C'\fR, \f(CW\*(C`desc\*(C'\fR, \f(CW\*(C`copyright\*(C'\fR, or \f(CW\*(C`keywords\*(C'\fR fields of the \f(CW\*(C`Geo::Gpx\*(C'\fR instance. .ie n .IP "author( $href )" 4 .el .IP "author( \f(CW$href\fR )" 4 .IX Item "author( $href )" The author information is stored in a hash that reflects the structure of a \s-1GPX 1.1\s0 document. To set it, supply a hash reference as (\f(CW\*(C`link\*(C'\fR and \f(CW\*(C`email\*(C'\fR are optional): { link => { text => 'Hexten', href => 'http://hexten.net/' }, email => { domain => 'hexten.net', id => 'andy' }, name => 'Andy Armstrong' }, .ie n .IP "link( $href )" 4 .el .IP "link( \f(CW$href\fR )" 4 .IX Item "link( $href )" The link is stored similarly to the author information, it can be set by supplying a hash reference as: { link => { text => 'Hexten', href => 'http://hexten.net/' } } .ie n .IP "time( $epoch )" 4 .el .IP "time( \f(CW$epoch\fR )" 4 .IX Item "time( $epoch )" Accessor for the