3 #=======================================================================
5 # File ID: 5e0437a0-fafa-11dd-abd7-000475e441b9
8 # ©opyleft 2002– Øyvind A. Holm <sunny@sunbase.org>
9 # License: GNU General Public License, see end of file for legal stuff.
10 #=======================================================================
20 our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
23 @EXPORT = qw(&trackpoint &postgresql_copy_safe &num_expand);
31 # Receive a hash and return a trackpoint as a string {{{
34 defined($Dat{'what'}) || return(undef);
35 defined($Dat{'format'}) || return(undef);
36 defined($Dat{'error'}) || return(undef);
38 defined($Dat{'year'}) || ($Dat{'year'} = 0);
39 defined($Dat{'month'}) || ($Dat{'month'} = 0);
40 defined($Dat{'day'}) || ($Dat{'day'} = 0);
41 defined($Dat{'hour'}) || ($Dat{'hour'} = "");
42 defined($Dat{'min'}) || ($Dat{'min'} = "");
43 defined($Dat{'sec'}) || ($Dat{'sec'} = "");
44 $Dat{'print_time'} = (
48 !length($Dat{'hour'}) ||
49 !length($Dat{'min'}) ||
54 ("$Dat{'year'}$Dat{'month'}$Dat{'day'}$Dat{'hour'}$Dat{'min'}" =~
55 /[^\d]/) || ($Dat{'sec'} =~ /[^\d\.]/)
57 ($Dat{'print_time'} = 0);
59 $Dat{'lat'} =~ /[^\d\.\-\+]/ && return(undef);
60 $Dat{'lon'} =~ /[^\d\.\-\+]/ && return(undef);
61 length($Dat{'ele'}) && $Dat{'ele'} =~ /[^\d\.\-\+]/ && return(undef);
63 defined($Dat{'lat'}) || ($Dat{'lat'} = "");
64 defined($Dat{'lon'}) || ($Dat{'lon'} = "");
65 defined($Dat{'ele'}) || ($Dat{'ele'} = "");
66 defined($Dat{'desc'}) || ($Dat{'desc'} = "");
68 $Dat{'lat'} = num_expand
($Dat{'lat'});
69 $Dat{'lon'} = num_expand
($Dat{'lon'});
70 $Dat{'ele'} = num_expand
($Dat{'ele'});
74 if ($Dat{'what'} eq "tp") {
75 if ($Dat{'format'} eq "gpsml") {
76 $Retval .= gen_gpsml_entry
(%Dat);
77 } elsif($Dat{'format'} eq "gpx") {
78 $Retval .= gen_gpx_entry
(%Dat);
79 } elsif($Dat{'format'} eq "clean") {
80 $Retval .= "$Dat{'lon'}\t$Dat{'lat'}\t$Dat{'ele'}\n";
81 } elsif($Dat{'format'} eq "xgraph") {
82 if (length($Dat{'lat'}) && length($Dat{'lon'})) {
83 $Retval .= "$Dat{'lon'} $Dat{'lat'}\n";
85 } elsif ($Dat{'format'} eq "pgtab") {
86 $Retval .= gen_pgtab_entry
(%Dat);
87 } elsif ($Dat{'format'} eq "gpstrans") {
88 $Retval .= gen_gpstrans_entry
(%Dat);
103 $Dat{'lat'} = num_expand
($Dat{'lat'});
104 $Dat{'lon'} = num_expand
($Dat{'lon'});
105 $Dat{'ele'} = num_expand
($Dat{'ele'});
106 my $err_str = length($Dat{'error'}) ?
$Dat{'error'} : "";
107 my $lat_str = length($Dat{'lat'}) ?
" lat=\"$Dat{'lat'}\"" : "";
108 my $lon_str = length($Dat{'lon'}) ?
" lon=\"$Dat{'lon'}\"" : "";
109 my ($estr_begin, $estr_ext, $estr_end) =
111 if (length($err_str)) {
112 $estr_begin = "<!-- ";
113 $estr_ext = "<extensions>$Spc<error>$err_str</error>$Spc</extensions>$Spc";
116 if (length("$lat_str$lon_str$Dat{'ele'}")) {
119 "$Spc$Spc$Spc$Spc$Spc$Spc",
121 "<trkpt$lat_str$lon_str>",
124 ?
"<ele>$Dat{'ele'}</ele>$Spc"
128 "$Dat{'year'}-$Dat{'month'}-$Dat{'day'}T" .
129 "$Dat{'hour'}:$Dat{'min'}:$Dat{'sec'}Z" .
133 "</trkpt>$estr_end\n"
140 sub gen_gpsml_entry
{
143 my $err_str = length($Dat{'error'}) ?
$Dat{'error'} : "";
144 my $Elem = length($err_str) ?
"etp" : "tp";
145 my $Retval = join("",
147 ?
sprintf("<time>%04u-%02u-%02uT" .
148 "%02u:%02u:%02gZ</time> ",
149 $Dat{'year'}, $Dat{'month'}, $Dat{'day'},
150 $Dat{'hour'}, $Dat{'min'}, $Dat{'sec'}*1.0
153 (length($Dat{'lat'}))
154 ?
"<lat>" . $Dat{'lat'}*1.0 . "</lat> "
156 (length($Dat{'lon'}))
157 ?
"<lon>" . $Dat{'lon'}*1.0 . "</lon> "
159 (length($Dat{'ele'}))
160 ?
"<ele>" . $Dat{'ele'}*1.0 . "</ele> "
162 (length($Dat{'desc'}))
163 ?
sprintf("<desc>%s</desc> ",
168 ($Retval = sprintf("<%s%s> %s</%s>\n",
170 length($err_str) ?
" err=\"$err_str\"" : "",
176 } # gen_gpsml_entry()
178 sub gen_pgtab_entry
{
181 my $Retval = join("\t",
183 ?
"$Dat{'year'}-$Dat{'month'}-$Dat{'day'}T" .
184 "$Dat{'hour'}:$Dat{'min'}:$Dat{'sec'}Z"
186 (length($Dat{'lat'}) && length($Dat{'lon'}))
187 ?
"($Dat{'lat'},$Dat{'lon'})"
189 length($Dat{'ele'}) ?
$Dat{'ele'} : '\N', # ele
196 } # gen_pgtab_entry()
198 sub gen_gpstrans_entry
{
202 my ($gpt_lat, $gpt_lon) =
203 (ddd_to_dms
($Dat{'lat'}), ddd_to_dms
($Dat{'lon'}));
204 if ($Dat{'print_time'}) {
205 $Retval = "T\t$Dat{'month'}/$Dat{'day'}/$Dat{'year'} " .
206 "$Dat{'hour'}:$Dat{'min'}:$Dat{'sec'}\t" .
207 "$gpt_lat\t$gpt_lon\n";
209 $Retval = "T\t00/00/00 00:00:00\t$gpt_lat\t$gpt_lon\n";
213 } # gen_gpstrans_entry()
215 sub postgresql_copy_safe
{
218 $Str =~ s/\\/\\\\/gs;
224 } # postgresql_copy_safe()
227 # Convert scientific notation to decimal notation {{{
229 length($Retval) || return("");
230 if ($Retval =~ /^(.*)e([-+]?)(.*)$/) {
231 my ($num, $sign, $exp) = ($1, $2, $3);
232 my $sig = $sign eq '-' ?
"." . ($exp - 1 + length $num) : '';
233 $Retval = sprintf("%${sig}f", $Retval);
236 my $minus = ($Retval =~ s/^-//) ?
"-" : "";
237 if ($Retval =~ /\.\d/) {
240 $Retval =~ s/^0([1-9]+)\./$1./;
245 length($Retval) || ($Retval = 0);
246 $Retval = $Retval ?
"$minus$Retval" : 0;