From: Dirk Koopman Date: Thu, 26 Feb 2009 11:11:53 +0000 (+0000) Subject: add Geo::TAF changes from Robin Johnson + CTY1902 X-Git-Tag: 1.56~59 X-Git-Url: http://www.dxcluster.org/gitweb/gitweb.cgi?p=spider.git;a=commitdiff_plain;h=74d17365969eb25dfe6545e93ed6d9ce4268b349 add Geo::TAF changes from Robin Johnson + CTY1902 --- diff --git a/Geo/TAF/Makefile.PL b/Geo/TAF/Makefile.PL index 48e01cbd..8658fed3 100644 --- a/Geo/TAF/Makefile.PL +++ b/Geo/TAF/Makefile.PL @@ -7,6 +7,12 @@ WriteMakefile( 'VERSION_FROM' => 'TAF.pm', # finds $VERSION 'PREREQ_PM' => {}, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 +# Stuff for >= 5.005 (ABSTRACT_FROM => 'TAF.pm', # retrieve abstract from module - AUTHOR => 'Dirk Koopman ') : ()), + AUTHOR => 'Dirk Koopman , Robin H. Johnson, L') +# Stuff for < 5.005 + : + () +# FIN + ), ); diff --git a/Geo/TAF/README b/Geo/TAF/README index a12b490d..c4a1ffe9 100644 --- a/Geo/TAF/README +++ b/Geo/TAF/README @@ -28,6 +28,7 @@ DEPENDENCIES COPYRIGHT AND LICENCE Copyright (C) 2003 Dirk Koopman G1TLH +Portions Copyright (C) 2009 Robin H. Johnson This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/Geo/TAF/TAF.pm b/Geo/TAF/TAF.pm index 155f2944..aa10a78d 100644 --- a/Geo/TAF/TAF.pm +++ b/Geo/TAF/TAF.pm @@ -13,36 +13,41 @@ use 5.005; use strict; use vars qw($VERSION); -$VERSION = '1.04-1'; +$VERSION = '1.05'; my %err = ( - '1' => "No valid ICAO designator", - '2' => "Length is less than 10 characters", - '3' => "No valid issue time", - '4' => "Expecting METAR or TAF at the beginning", - ); + '1' => "No valid ICAO designator", + '2' => "Length is less than 10 characters", + '3' => "No valid issue time", + '4' => "Expecting METAR or TAF at the beginning", + ); my %clt = ( - SKC => 1, - CLR => 1, - NSC => 1, - BLU => 1, - WHT => 1, - GRN => 1, - YLO => 1, - AMB => 1, - RED => 1, - BKN => 1, - NIL => 1, - ); + SKC => 1, + CLR => 1, + NSC => 1, + NSD => 1, + 'BLU+' => 1, + BLU => 1, + WHT => 1, + GRN => 1, + YLO => 1, + YLO1 => 1, + YLO2 => 1, + AMB => 1, + RED => 1, + BKN => 1, + NIL => 1, + '///' => 1, + ); my %ignore = ( - AUTO => 1, - COR => 1, - ); + 'AUTO' => 1, # Automatic weather system in usage + 'COR' => 1, # Correction issued (US) + 'CCA' => 1, # Correction issued (EU) + ); - # Preloaded methods go here. sub new @@ -58,7 +63,7 @@ sub metar my $self = shift; my $l = shift; return 2 unless length $l > 10; - $l = 'METAR ' . $l unless $l =~ /^\s*(?:METAR|TAF)\s/i; + $l = 'METAR ' . $l unless $l =~ /^\s*(?:METAR|TAF|SPECI)\s/i; return $self->decode($l); } @@ -67,7 +72,16 @@ sub taf my $self = shift; my $l = shift; return 2 unless length $l > 10; - $l = 'TAF ' . $l unless $l =~ /^\s*(?:METAR|TAF)\s/i; + $l = 'TAF ' . $l unless $l =~ /^\s*(?:METAR|TAF|SPECI)\s/i; + return $self->decode($l); +} + +sub speci +{ + my $self = shift; + my $l = shift; + return 2 unless length $l > 10; + $l = 'SPECI ' . $l unless $l =~ /^\s*(?:METAR|TAF|SPECI)\s/i; return $self->decode($l); } @@ -82,6 +96,7 @@ sub as_strings my $self = shift; my @out; for (@{$self->{chunks}}) { + next if $_->type =~ m/^Geo::TAF::[A-Z]+::IGNORE$/; push @out, $_->as_string; } return @out; @@ -97,7 +112,7 @@ sub as_chunk_strings { my $self = shift; my @out; - + for (@{$self->{chunks}}) { push @out, $_->as_chunk; } @@ -117,7 +132,7 @@ sub raw sub is_weather { - return $_[0] =~ /^\s*(?:(?:METAR|TAF)\s+)?[A-Z]{4}\s+\d{6}Z?\s+/; + return $_[0] =~ /^\s*(?:(?:METAR|TAF|SPECI)\s+)?[A-Z]{4}\s+\d{6}Z?\s+/; } sub errorp @@ -135,33 +150,25 @@ sub decode my $l = uc shift; $l =~ s/=$//; - - # Fix dodgy TAFs. - # TAFs like this are non-standard, but I have seen these examples in - # real life, and that is, after all, what this code needs to cope with. [DW] - $l =~ s/\b(BECMG)(\d{4})\b/$1 $2/g; # Some people can't use a space bar - $l =~ s/\bTEMP0\b/TEMPO/g; # Some people use zero instead of a letter O - $l =~ s/\bBEC\b/BECMG/g; # And some people can't spell BECMG - + my @tok = split /\s+/, $l; $self->{line} = join ' ', @tok; - - # do we explicitly have a METAR or a TAF + + # Count how many problems we have + $self->{decode_failures} = 0; + + # do we explicitly have a METAR, SPECI or TAF my $t = shift @tok; - if ($t eq 'TAF') { - $self->{taf} = 1; - } elsif ($t eq 'METAR') { - $self->{taf} = 0; + if ($t =~ /^(TAF|METAR|SPECI)$/) { + $self->{report_type} = $t; + $self->{taf} = $t eq 'TAF'; } else { return 4; } # next token is the ICAO dseignator $t = shift @tok; - # ignore AMD (amendment) token if present. - $t = shift @tok if $t eq 'AMD'; - if ($t =~ /^[A-Z]{4}$/) { $self->{icao} = $t; } else { @@ -170,9 +177,6 @@ sub decode # next token is an issue time $t = shift @tok; - # ignore AMD (amendment) token if present. - $t = shift @tok if $t eq 'AMD'; - if (my ($day, $time) = $t =~ /^(\d\d)(\d{4})Z?$/) { $self->{day} = $day; $self->{time} = _time($time); @@ -193,107 +197,175 @@ sub decode # we are now into the 'list' of things that can repeat over and over my @chunk = ( - $self->_chunk('HEAD', $self->{taf} ? 'TAF' : 'METAR', - $self->{icao}, $self->{day}, $self->{time}) + $self->_chunk('HEAD', $self->{report_type}, + $self->{icao}, $self->{day}, $self->{time}), + $self->_chunk('BLOCK'), # new block always now ); - - push @chunk, $self->_chunk('VALID', $self->{valid_day}, $self->{valid_from}, - $self->{valid_to}) if $self->{valid_day}; + + if($self->{valid_day}) { + push @chunk, $self->_chunk('VALID'); + push @chunk, $self->_chunk('PERIOD', $self->{valid_from}, $self->{valid_to}, $self->{valid_day}, ); + push @chunk, $self->_chunk('BLOCK'); # new block always now + } + + my ($c0, $c1, $expect, @remark_buffer, $ignore_no_length_change); + my ($day, $time, $percent, $sort, $dir); + my ($wdir, $spd, $gust, $unit); + my ($viz, $vunit); + my ($m, $p); while (@tok) { $t = shift @tok; - + # Count number of items in chunk, and use to determine if we could not + # decode. + $c0 = $#chunk; + # If this is NOT set, and the count doesn't change, we failed a decode + $ignore_no_length_change = 0; + + # This is just so the rest patches easier + if(!defined($t)) { + # temporary - if ($t eq 'TEMPO' || $t eq 'BECMG') { - - # next token may be a time if it is a taf - my ($from, $to); - if (@tok && (($from, $to) = $tok[0] =~ /^(\d\d)(\d\d)$/)) { - if ($self->{taf} && $from >= 0 && $from <= 24 && $to >= 0 && $to <= 24) { - shift @tok; - $from = _time($from * 100); - $to = _time($to * 100); - } else { - undef $from; - undef $to; - } + } elsif ($t eq 'TEMPO' || $t eq 'TEMP0' || $t eq 'BECMG') { + # TEMPO occurs with both a oh and a zero, in some bad automated hardware + $t = 'TEMPO' if $t eq 'TEMP0'; + push @chunk, $self->_chunk('BLOCK'); # new block always now + push @chunk, $self->_chunk($t); + $expect = 'PERIOD'; + + # time range + } elsif ($expect eq 'PERIOD' || $t =~ /^(\d\d)(\d\d)\/(\d\d)(\d\d)$/) { + undef $expect; + # next token may be a period if it is a taf + # Two possible formats: + # XXYY = hour XX to hour YY (but only valid after TEMPO/BECMG) + # AABB/CCDD = day aa hour bb TO day cc hour dd (after TEMPO/BECMG, but ALSO valid after HEAD) + my ($from_time, $to_time, $from_day, $to_day); + my ($got_time, $got_day); + if (($from_time, $to_time) = $t =~ /^(\d\d)(\d\d)$/) { + $got_time = 1; + } elsif (($from_day, $from_time, $to_day, $to_time) = $t =~ /^(\d\d)(\d\d)\/(\d\d)(\d\d)$/) { + $got_time = $got_day = 1; + } + if ($got_time && $self->{taf} && $from_time >= 0 && $from_time <= 24 && $to_time >= 0 && $to_time <= 24) { + $from_time = _time($from_time * 100); + $to_time = _time($to_time * 100); + } else { + undef $from_time; + undef $to_time; + undef $got_time; } - push @chunk, $self->_chunk($t, $from, $to); + if($got_time && $got_day && $from_day >= 1 && $from_day <= 31 && $to_day >= 1 && $to_day <= 31) { + # do not shift tok, we did it already + } else { + undef $from_day; + undef $to_day; + undef $got_day; + } + push @chunk, $self->_chunk('PERIOD', $from_time, $to_time, $from_day, $to_day) if $got_time; # ignore } elsif ($ignore{$t}) { - ; - - # no sig weather + push @chunk, $self->_chunk('IGNORE', $t); + + # no sig weather } elsif ($t eq 'NOSIG' || $t eq 'NSW') { push @chunk, $self->_chunk('WEATHER', 'NOSIG'); + # // means the automated system cannot determine the precipiation at all + } elsif ($t eq '//') { + push @chunk, $self->_chunk('WEATHER', $t); + # specific broken on its own } elsif ($t eq 'BKN') { push @chunk, $self->_chunk('WEATHER', $t); - - # other 3 letter codes + + # wind shear (is followed by a runway designation) + } elsif ($t eq 'WS') { + push @chunk, $self->_chunk('WEATHER', $t); + + # other 3 letter codes } elsif ($clt{$t}) { push @chunk, $self->_chunk('CLOUD', $t); - + # EU CAVOK viz > 10000m, no cloud, no significant weather } elsif ($t eq 'CAVOK') { $self->{viz_dist} ||= ">10000"; $self->{viz_units} ||= 'm'; push @chunk, $self->_chunk('CLOUD', 'CAVOK'); - # AMD group (end for now) - } elsif ($t eq 'AMD') { - last; - - # RMK group (end for now) - } elsif ($t eq 'RMK') { - last; - - # from - } elsif (my ($time) = $t =~ /^FM(\d\d\d?\d?)Z?$/ ) { - $time .= '0' while length($time) < 4; - push @chunk, $self->_chunk('FROM', _time($time)); - - # Until - } elsif (($time) = $t =~ /^TI?LL?(\d\d\d?\d?)Z?$/ ) { - $time .= '0' while length($time) < 4; - push @chunk, $self->_chunk('TIL', _time($time)); - - # probability - } elsif (my ($percent) = $t =~ /^PROB(\d\d)$/ ) { - - # next token may be a time if it is a taf - my ($from, $to); - if (@tok && (($from, $to) = $tok[0] =~ /^(\d\d)(\d\d)$/)) { - if ($self->{taf} && $from >= 0 && $from <= 24 && $to >= 0 && $to <= 24) { - shift @tok; - $from = _time($from * 100); - $to = _time($to * 100); - } else { - undef $from; - undef $to; - } + # RMK group (end for now) + } elsif ($t eq 'RMK' or $t eq 'RKM') { + #push @chunk, $self->_chunk('RMK', join(' ',@tok)); + $self->{in_remark} = $c0; + push @chunk, $self->_chunk('BLOCK'); # new block always now + #last; + + # from + } elsif (($day,$time) = $t =~ /^FM(\d\d)?(\d\d\d\d)Z?$/ ) { + push @chunk, $self->_chunk('BLOCK'); # new block always now + push @chunk, $self->_chunk('FROM', _time($time), $day); + + # Until + } elsif (($day,$time) = $t =~ /^TL(\d\d)?(\d\d\d\d)Z?$/ ) { + push @chunk, $self->_chunk('BLOCK'); # new block always now + push @chunk, $self->_chunk('TIL', _time($time), $day); + + # At + # Seen at http://stoivane.iki.fi/metar/ + } elsif (($day,$time) = $t =~ /^AT(\d\d)?(\d\d\d\d)Z?$/ ) { + push @chunk, $self->_chunk('BLOCK'); # new block always now + push @chunk, $self->_chunk('AT', _time($time), $day); + + # probability + } elsif (($percent) = $t =~ /^PROB(\d\d)$/ ) { + push @chunk, $self->_chunk('BLOCK'); # new block always now + $expect = 'PERIOD'; + push @chunk, $self->_chunk('PROB', $percent); + + # runway + } elsif (($sort, $dir) = $t =~ /^(RWY?|LDG|TKOF|R)(\d\d\d?[RLC]?)$/ ) { + # Special case, + # there is a some broken METAR hardware out there that codes: + # 'RWY01 /0100VP2000N' + # TODO: include the full regex here + if($tok[0] =~ /^\/[MP]?\d{4}/) { + $t .= shift @tok; + unshift @tok, $t } - push @chunk, $self->_chunk('PROB', $percent, $from, $to); + push @chunk, $self->_chunk('RWY', $sort, $dir); - # runway - } elsif (my ($sort, $dir) = $t =~ /^(RWY?|LDG)(\d\d[RLC]?)$/ ) { + # runway, but as seen in wind shear + # eg: LDG RWY25L + } elsif (($sort) = $t =~ /^(LDG|TKOF)$/ ) { + my $t2; + $t2 = shift @tok; + ($dir) = $t2 =~ /^RWY(\d\d[RLC]?)$/; push @chunk, $self->_chunk('RWY', $sort, $dir); # a wind group - } elsif (my ($wdir, $spd, $gust, $unit) = $t =~ /^(\d\d\d|VRB)(\d\d)(?:G(\d\d))?(KT|MPH|MPS|KMH)$/) { - + } elsif (($wdir, $spd, $gust, $unit) = $t =~ /^([\dO]{3}|VRB|\/{3})([\dO]{2}|\/{2})(?:G([\dO]{2,3}))?(KTS?|MPH|MPS|KMH)$/) { my ($fromdir, $todir); - - if (@tok && (($fromdir, $todir) = $tok[0] =~ /^(\d\d\d)V(\d\d\d)$/)) { + + # More hardware suck, oh vs. zero + $wdir =~ s/O/0/g if $wdir; + $spd =~ s/O/0/g if $spd; + $gust =~ s/O/0/g if $gust; + + # it could be variable so look at the next token + if (@tok && (($fromdir, $todir) = $tok[0] =~ /^([\dO]{3})V([\dO]{3})$/)) { shift @tok; + $fromdir =~ s/O/0/g; + $todir =~ s/O/0/g; } - - # it could be variable so look at the next token - $spd = 0 + $spd; + # Part of the hardware is bad + $wdir = 'NA' if $wdir eq '///'; + $spd = 'NA' if $spd eq '//'; + + $spd = 0 + $spd unless $spd eq 'NA'; $gust = 0 + $gust if defined $gust; + $unit = 'kt' if $unit eq 'KTS'; $unit = ucfirst lc $unit; $unit = 'm/sec' if $unit eq 'Mps'; $self->{wind_dir} ||= $wdir; @@ -301,13 +373,25 @@ sub decode $self->{wind_gusting} ||= $gust; $self->{wind_units} ||= $unit; push @chunk, $self->_chunk('WIND', $wdir, $spd, $gust, $unit, $fromdir, $todir); - + + # wind not reported + # MHRO does not seem to follow this rule. + } elsif ($t =~ /^\/{5}$/) { + if($self->{icao} eq 'MHRO') { + ; # TODO: We will do something here once we figure what MHRO uses this field for + push @chunk, $self->_chunk('IGNORE', $t); + } else { + push @chunk, $self->_chunk('WIND', 'NR', undef, undef, undef, undef, undef); + } + # pressure - } elsif (my ($u, $p, $punit) = $t =~ /^([QA])(?:NH)?(\d\d\d\d)(INS?)?$/) { + } elsif (my ($u, $p, $punit) = $t =~ /^([QA])(?:NH)?(\d{4}|\/{4}|)(INS?)?$/) { - $p = 0 + $p; + $p = 'NA' if $p eq '////'; + $p = 'NA' if $p eq '' or !defined($p); + $p = 0.0 + $p unless $p eq 'NA'; if ($u eq 'A' || $punit && $punit =~ /^I/) { - $p = sprintf "%.2f", $p / 100; + $p = sprintf("%.2f", $p / 100.0) unless $p eq 'NA'; $u = 'in'; } else { $u = 'hPa'; @@ -317,82 +401,224 @@ sub decode push @chunk, $self->_chunk('PRESS', $p, $u); # viz group in metres - } elsif (my ($viz, $mist) = $t =~ m!^(\d\d\d\d[NSEW]{0,2})([A-Z][A-Z])?$!) { - $viz = $viz eq '9999' ? ">10000" : 0 + $viz; + # May be \d{4}NDV per http://www.caa.co.uk/docs/33/CAP746.PDF + # //// = unknown + # strictly before the remark section. After RMK plain numbers mean other things. + } elsif (!defined $self->{in_remark} and ($viz, $dir) = $t =~ m/^(\d\d\d\d|\/{4})([NSEW]{1,2}|NDV)?$/) { + if($viz eq '////') { + $viz = 'NA'; + } else { + $viz = $viz eq '9999' ? ">10000" : 0 + $viz; + } $self->{viz_dist} ||= $viz; $self->{viz_units} ||= 'm'; - push @chunk, $self->_chunk('VIZ', $viz, 'm'); - push @chunk, $self->_chunk('WEATHER', $mist) if $mist; - - # viz group in KM - } elsif (($viz) = $t =~ m!^(\d+)KM$!) { - $viz = $viz eq '9999' ? ">10000" : 0 + $viz; + $dir = undef if $dir && $dir eq 'NDV'; + push @chunk, $self->_chunk('VIZ', $viz, 'm', $dir); + #push @chunk, $self->_chunk('WEATHER', $mist) if $mist; + + # viz group in integral KM, feet, M + } elsif (($viz, $vunit) = $t =~ m/^(\d+|\/{1,3})(KM|FT|M)$/) { + if($viz =~ /^\/+$/) { + $viz = 'NA'; + } else { + $viz = $viz eq '9999' ? ">10000" : 0 + $viz; + } + $vunit = lc $vunit; $self->{viz_dist} ||= $viz; - $self->{viz_units} ||= 'Km'; - push @chunk, $self->_chunk('VIZ', $viz, 'Km'); + $self->{viz_units} ||= $vunit; + push @chunk, $self->_chunk('VIZ', $viz, $vunit); - # viz group in miles and fraction of a mile with space between - } elsif (my ($m) = $t =~ m!^(\d)$!) { - my ($viz, $denom); - if (@tok && (($viz, $denom) = $tok[0] =~ m!^(\d)/(\d)SM$!)) { + # viz group in miles and faction of a mile with space between + } elsif (my ($m) = $t =~ m/^(\d)$/) { + if (@tok && (($viz) = $tok[0] =~ m/^(\d\/\d)SM$/)) { shift @tok; - $denom ||= 1; - $viz = $m + $viz / $denom; + $viz = "$m $viz"; $self->{viz_dist} ||= $viz; - $self->{viz_units} ||= 'Miles'; - push @chunk, $self->_chunk('VIZ', $viz, 'Miles'); + $self->{viz_units} ||= 'miles'; + push @chunk, $self->_chunk('VIZ', $viz, 'miles'); } - + # viz group in miles (either in miles or under a mile) - } elsif (my ($lt, $mviz, $denom) = $t =~ m!^([MP])?(\d+)(?:/(\d))?SM$!) { - $denom ||= 1; - $mviz /= $denom; - $mviz = '<' . $mviz if $lt and $lt eq 'M'; - $mviz = '>' . $mviz if $lt and $lt eq 'P'; - $self->{viz_dist} ||= $mviz; - $self->{viz_units} ||= 'Miles'; - push @chunk, $self->_chunk('VIZ', $mviz, 'Miles'); - + } elsif (my ($lt, $viz) = $t =~ m/^(M|P)?(\d+(:?\/\d)?|\/{1,3})SM$/) { + if($viz =~ /^\/+$/) { + $viz = 'NA'; + } + $viz = '<' . $viz if $lt eq 'M'; + $viz = '>' . $viz if $lt eq 'P'; + $self->{viz_dist} ||= $viz; + $self->{viz_units} ||= 'Stat. Miles'; + push @chunk, $self->_chunk('VIZ', $viz, 'miles'); + + # Runway deposits state per ICAO + # 8 digits + # (DR,DR),ER,CR,(eR,eR),(BR,BR) + # "ER,CR,eR,eR" == CLRD when previous deposits are removed + # Also an alternate form, xxyzCLRD. + } elsif (my ($rwy, $type, $extent, $depth, $braking) = $t =~ m/^(\d\d)(\d|\/|C)(\d|\/|L)(\d\d|\/\/|RD|CL)(\d\d|\/\/|RD)$/) { + # Runway desginator + if($rwy == 99) { + $rwy = 'LAST'; + } elsif($rwy == 88) { + $rwy = 'ALL'; + } elsif($rwy >= 50) { + $rwy = ($rwy-50).'R'; + } else { + $rwy = $rwy.'L'; + } + + # Type + # Not processed here + + # Extent + # Not processed here + + # Depth + if($depth eq 'RD' or $depth eq 'CL') { + # Previous contaminination cleared + $type = 'CLRD'; + $extent = undef; + $depth = undef; + $braking = undef if $braking eq 'RD'; + } elsif($depth eq '//') { + ; # pass-thru + } elsif($depth == 0) { + $depth = '<1mm'; + } elsif($depth <= 90) { + $depth .= 'mm'; + } elsif($depth == 91) { + # BAD! + } elsif($depth >= 92 && $depth <= 97) { + # 92 = 10cm ... 97 = 35cm + $depth = sprintf('%dcm', (($depth - 90) * 5)); + } elsif($depth == 99) { + $depth = '>40cm'; + } elsif($depth == 99) { + $extent = 'CVRD'; + $depth = 'NR'; + } + + # Friction / Breaking action + if(defined($braking) && $braking < 91) { + $braking = sprintf('%.2f', $braking/100.0); + } # Other codes are handling in the print + + push @chunk, $self->_chunk('DEP', $rwy, $type, $extent, $depth, $braking); + # runway visual range - } elsif (my ($rw, $rlt, $range, $vlt, $var, $runit, $tend) = $t =~ m!^R(\d\d[LRC]?)/([MP])?(\d\d\d\d)(?:V([MP])(\d\d\d\d))?(?:(FT)/?)?([UND])?$!) { - $runit = 'm' unless $runit; - $runit = lc $unit; + } elsif (my ($rw, $rlt, $range, $vlt, $var, $runit, $tend) = $t =~ m/^R(\d\d\d?[LRC]?)\/([MP])?(\d\d\d\d?)(?:V([MP])?(\d\d\d\d?))?((?:FT)\/?)?([UND])?$/) { + $runit = 'm' unless defined($runit) && length($runit) > 0; + $runit = lc $runit; $range = "<$range" if $rlt && $rlt eq 'M'; $range = ">$range" if $rlt && $rlt eq 'P'; $var = "<$var" if $vlt && $vlt eq 'M'; $var = ">$var" if $vlt && $vlt eq 'P'; push @chunk, $self->_chunk('RVR', $rw, $range, $var, $runit, $tend); - + # weather - } elsif (my ($deg, $w) = $t =~ /^(\+|\-|VC)?([A-Z][A-Z]{1,4})$/) { + } elsif (not defined $self->{in_remark} && my ($deg, $w) = $t =~ /^(\+|\-)?([A-Z][A-Z]{1,6})$/) { push @chunk, $self->_chunk('WEATHER', $deg, $w =~ /([A-Z][A-Z])/g); - - # cloud and stuff - } elsif (my ($amt, $height, $cb) = $t =~ m!^(FEW|SCT|BKN|OVC|SKC|CLR|VV|///)(\d\d\d|///)(CB|TCU)?$!) { - push @chunk, $self->_chunk('CLOUD', $amt, $height eq '///' ? 0 : $height * 100, $cb) unless $amt eq '///' && $height eq '///'; + # cloud and stuff + # /// is the TCU column means that the automated system is unable to detect it + } elsif (my ($amt, $height, $cb) = $t =~ m/^(FEW|SCT|BKN|OVC|SKC|CLR|VV|\/{3})(\d\d\d|\/{3})(CB|TCU|CBMAM|ACC|CLD|\/\/\/)?$/) { + push @chunk, $self->_chunk('CLOUD', $amt, $height eq '///' ? 0 : $height * 100, $cb); # temp / dew point - } elsif (my ($ms, $t, $n, $d) = $t =~ m!^T?(M)?(\d\d)/(M)?(\d\dZ?)?$!) { - $t = 0 + $t; + } elsif (my ($ms, $temp, $n, $d) = $t =~ m/^(M)?(\d\d)\/(M)?(\d\d)?$/) { + $temp = 0 + $temp; $d = 0 + $d; - $t = -$t if defined $ms; + $temp = -$temp if defined $ms; $d = -$d if defined $d && defined $n; - $self->{temp} ||= $t; + $self->{temp} ||= $temp; $self->{dewpoint} ||= $d; - push @chunk, $self->_chunk('TEMP', $t, $d); - } + push @chunk, $self->_chunk('TEMP', $temp, $d); - } + # Remark section containing exact cloud type + okta number + # cloud type codes in Geo::TAF::EN::CLOUD + # example: CI1AC1TCU4 = Cirrus 1/8, Altocumulus 1/8, Towering Cumulus 4/8 + # example: SN2SC1SC3SC2 + } elsif (my $ct = $t =~ m/^((?:CI|CS|CC|AS|AC|ACC|ST|NS|SC|SF|SN|CF|CU|TCU|CB)\d)+$/) { + foreach my $ct (split m/((?:CI|CS|CC|AS|AC|ACC|ST|NS|SC|SF|SN|CF|CU|TCU|CB)\d)/, $t) { + chomp $ct; + next if(length($ct) == 0); + $t = $ct; + $ct =~ s/\d+$//; + $t =~ s/^$ct//; + push @chunk, $self->_chunk('CLOUD', $t, $ct) + } + + # pressure equivilent @ sea level + } elsif (($p) = $t =~ /^SLP(\d\d\d)$/) { + $p = 0+$p; + $p = sprintf '%.1f', 1000+$p/10.0; + push @chunk, $self->_chunk('SLP', $p, 'hPa'); + + # station type + } elsif (defined $self->{in_remark} && ($type) = $t =~ /^AO(1|2)$/) { + $type = ($type == '1' ? '-' : '+').'PRECIP'; + push @chunk, $self->_chunk('STATION_TYPE', $type); + + # US NWS: + # Hourly Precipitation Amount (P) + # 3- and 6-Hour Precipitation Amount (3, 6) + # 24-Hour Precipitation Amount (7) + # + # The specification says 4 digits after the type code, but some stations only have 3: + # CXKA 011100Z AUTO 35002KT M28/M31 RMK AO1 3010 SLP219 T12761306 50023 + # ^^^ 0.1 inches in the 3 hour period + # + # KW22 011135Z AUTO 23016G23KT 10SM BKN029 OVC036 02/M02 A2988 RMK A02 P000 + # ^^^ 0.0 inches in the last hour + } elsif (defined $self->{in_remark} && my ($precip_period, $precip) = $t =~ /^(3|6|7|P)(\d{3,4})$/) { + $precip_period = 24 if $precip_period eq '7'; + $precip_period = 1 if $precip_period eq 'P'; + push @chunk, $self->_chunk('PRECIP', $precip, $precip_period); + + # other remarks go to a text buffer for now + #} elsif (defined $self->{in_remark} && length($t) > 0) { + } elsif (defined $self->{in_remark}) { + print "Adding to remark buffer: $t\n"; + push @remark_buffer, $t; + $ignore_no_length_change = 1; + + #X#} elsif (1) { + #X# print "Debug marker: $t\n"; + #X# $ignore_no_length_change = 1; + + } elsif(0) { + + + # End of processing + } + + $c1 = $#chunk; + if($c0 == $c1 && $ignore_no_length_change == 0) { + push @chunk, $self->_chunk('RMK','Failed to decode: '.$t); + $self->{decode_failures}++; + } + } + + if (@remark_buffer) { + push @chunk, $self->_chunk('BLOCK') unless ($c0 == $c1); + push @chunk, $self->_chunk('RMK', join(' ', @remark_buffer)); + } $self->{chunks} = \@chunk; return undef; } -sub _chunk +sub _pkg { my $self = shift; my $pkg = shift; no strict 'refs'; $pkg = $self->{chunk_package} . '::' . $pkg; + return $pkg; +} +sub _chunk +{ + my $self = shift; + my $pkg = shift; + no strict 'refs'; + $pkg = $self->_pkg($pkg); return $pkg->new(@_); } @@ -409,7 +635,7 @@ sub AUTOLOAD return if $name eq 'DESTROY'; *$AUTOLOAD = sub {return $_[0]->{$name}}; - goto &$AUTOLOAD; + goto &$AUTOLOAD; } # @@ -419,6 +645,7 @@ sub AUTOLOAD # package Geo::TAF::EN; +sub type { return __PACKAGE__; } sub new { @@ -454,15 +681,15 @@ sub day return "${d}th"; } - package Geo::TAF::EN::HEAD; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } sub as_string { my $self = shift; - return "$self->[0] for $self->[1] issued at $self->[3] on " . $self->day($self->[2]); + return sprintf "%s for %s issued at %s on %s", $self->[0], $self->[1], $self->[3], $self->day($self->[2]); } package Geo::TAF::EN::VALID; @@ -472,48 +699,73 @@ use vars qw(@ISA); sub as_string { my $self = shift; - return "valid from $self->[1] to $self->[2] on " . $self->day($self->[0]); + return "valid"; + # will be followed by a PERIOD block } package Geo::TAF::EN::WIND; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +my %wst = ( + NA => 'unknown', + NR => 'not reported', + VRB => 'variable', +); -# direction, $speed, $gusts, $unit, $fromdir, $todir +# $direction, $speed, $gusts, $unit, $fromdir, $todir sub as_string { my $self = shift; - my $out = "wind"; - $out .= $self->[0] eq 'VRB' ? " variable" : " $self->[0]"; - $out .= " varying between $self->[4] and $self->[5]" if defined $self->[4]; - $out .= ($self->[0] eq 'VRB' ? '' : " degrees") . " at $self->[1]"; - $out .= " gusting $self->[2]" if defined $self->[2]; - $out .= $self->[3]; + my $out; + $out = sprintf("wind %s", ($wst{$self->[0]} ? $wst{$self->[0]}: $self->[0])); + $out .= sprintf(" varying between %s && %s", $self->[4], $self->[5]) if defined $self->[4]; + $out .= sprintf("%s at %s", ($self->[0] eq 'VRB' ? '' : " degrees"), $wst{$self->[1]} ? $wst{$self->[1]} : $self->[1]) if defined $self->[1]; + $out .= sprintf(" gusting %s", $self->[2]) if defined $self->[2] && $self->[1] ne 'NA'; + $out .= $self->[1] eq 'NA' ? ' speed' : $self->[3] if defined $self->[3]; return $out; } package Geo::TAF::EN::PRESS; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +# $pressure, $unit +sub as_string +{ + my $self = shift; + return sprintf "QNH pressure not available" if $self->[0] eq 'NA'; + return sprintf "QNH pressure %s%s", $self->[0], $self->[1]; +} + +package Geo::TAF::EN::SLP; +use vars qw(@ISA); +@ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } # $pressure, $unit sub as_string { my $self = shift; - return "QNH $self->[0]$self->[1]"; + return sprintf "SLP pressure not available" if $self->[0] eq 'NA'; + return sprintf "SLP pressure %s%s", $self->[0], $self->[1]; } # temperature, dewpoint package Geo::TAF::EN::TEMP; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } sub as_string { my $self = shift; - my $out = "temperature $self->[0]C"; - $out .= " dewpoint $self->[1]C" if defined $self->[1]; + my $out; + $out = sprintf("temperature %sC", $self->[0]); + $out .= sprintf(" dewpoint %sC", $self->[1]) if defined $self->[1]; return $out; } @@ -521,87 +773,135 @@ sub as_string package Geo::TAF::EN::CLOUD; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } my %st = ( - VV => 'vertical visibility', - SKC => "no cloud", - CLR => "no cloud no significant weather", - SCT => "3-4 oktas", - BKN => "5-7 oktas", - FEW => "0-2 oktas", - OVC => "8 oktas overcast", - CAVOK => "no cloud below 5000ft >10Km visibility no significant weather (CAVOK)", - CB => 'thunder clouds', - TCU => 'towering cumulus', - NSC => 'no significant cloud', - BLU => '3 oktas at 2500ft 8Km visibility', - WHT => '3 oktas at 1500ft 5Km visibility', - GRN => '3 oktas at 700ft 3700m visibility', - YLO => '3 oktas at 300ft 1600m visibility', - AMB => '3 oktas at 200ft 800m visibility', - RED => '3 oktas at <200ft <800m visibility', - NIL => 'no weather', - '///' => 'some', - ); - + VV => 'vertical visibility', + SKC => "no cloud", + CLR => "no cloud no significant weather", + SCT => "3-4 oktas/scattered", + BKN => "5-7 oktas/broken", + FEW => "0-2 oktas/few", + OVC => "8 oktas/overcast", + '///' => 'some', +); + +my %cloud_code = ( + # Cloud codes found in remarks, followed by an okta + # same order as the SCT/BWN/FEW/OVC codes. + CI => 'Cirrus', + CS => 'Cirrostratus', + CC => 'Cirrocumulus', + AS => 'Altostratus', + AC => 'Altocumulus', + ACC => 'Altocumulus Castellanus', + ST => 'Stratus', + NS => 'Nimbostratus', + SC => 'Stratoculumus', + SF => 'Stratus Fractus', + CF => 'Cumulus Fractus', + CU => 'Cumulus', + TCU => 'Towering Cumulus', + CB => 'Cumulonimbus', # aka thunder clouds + + # not official, but seen often in Canada: METAR CYVR 262319Z 09011KT 1 1/2SM -SN FEW003 BKN006 OVC010 00/ RMK SN2SC1SC3SC2 + SN => 'Snow clouds', +); + +my %col = ( + 'CAVOK' => "no cloud below 5000ft >10km visibility no significant weather (CAVOK)", + 'NSC' => 'no significant cloud', + 'NCD' => "no cloud detected", + 'BLU+' => '3 oktas at >2500ft >8km visibility', + 'BLU' => '3 oktas at 2500ft 8km visibility', + 'WHT' => '3 oktas at 1500ft 5km visibility', + 'GRN' => '3 oktas at 700ft 3700m visibility', + 'YLO1' => '3 oktas at 500ft 2500m visibility', + 'YLO2' => '3 oktas at 300ft 1600m visibility', + 'YLO' => '3 oktas at 300ft 1600m visibility', # YLO2 and YLO are meant to be identical + 'AMB' => '3 oktas at 200ft 800m visibility', + 'RED' => '3 oktas at <200ft <800m visibility', + 'NIL' => 'no weather', +); + +my %st_storm = ( + CB => 'cumulonimbus', + TCU => 'towering cumulus', + CBMAM => 'cumulonimbus mammatus', + ACC => 'altocumulus castellatus', + CLD => 'standing lenticular', + # if you get this, the automated sensors are unable to decide + '///' => 'unknown cumulus', +); + +# $amt, $height, $cb sub as_string { my $self = shift; - return $st{$self->[0]} if @$self == 1; - return $st{$self->[0]} . " $self->[1]ft" if $self->[0] eq 'VV'; - return $st{$self->[0]} . " cloud at $self->[1]ft" . ((defined $self->[2]) ? " with $st{$self->[2]}" : ""); + return $col{$self->[0]} if @$self == 1 && $col{$self->[0]}; + if(@$self == 2 && (int($self->[0]) eq "$self->[0]") and defined $cloud_code{$self->[1]}) { + return sprintf "%s %d/8 cover", $cloud_code{$self->[1]}, $self->[0]; + } + return sprintf("%s %sft", $st{$self->[0]}, $self->[1]) if $self->[0] eq 'VV'; + my $out = sprintf("%s cloud", $st{$self->[0]}); + $out .= sprintf(' at %sft', $self->[1]) if $self->[1]; + $out = 'unknown cloud cover' if $self->[1] == 0 && $self->[0] eq '///'; + $out .= sprintf(" with %s", $st_storm{$self->[2]}) if $self->[2]; + return $out; } package Geo::TAF::EN::WEATHER; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } my %wt = ( - '+' => 'heavy', - '-' => 'light', - 'VC' => 'in the vicinity', - - MI => 'shallow', - PI => 'partial', - BC => 'patches of', - DR => 'low drifting', - BL => 'blowing', - SH => 'showers', - TS => 'thunderstorms containing', - FZ => 'freezing', - RE => 'recent', - - DZ => 'drizzle', - RA => 'rain', - SN => 'snow', - SG => 'snow grains', - IC => 'ice crystals', - PE => 'ice pellets', - GR => 'hail', - GS => 'small hail/snow pellets', - UP => 'unknown precip', - - BR => 'mist', - FG => 'fog', - FU => 'smoke', - VA => 'volcanic ash', - DU => 'dust', - SA => 'sand', - HZ => 'haze', - PY => 'spray', - - PO => 'dust/sand whirls', - SQ => 'squalls', - FC => 'tornado', - SS => 'sand storm', - DS => 'dust storm', - '+FC' => 'water spouts', - WS => 'wind shear', - 'BKN' => 'broken', - - 'NOSIG' => 'no significant weather', - - ); + '+' => 'heavy', + '-' => 'light', + 'VC' => 'in the vicinity', + + 'MI' => 'shallow', + 'PI' => 'partial', + 'BC' => 'patches of', + 'DR' => 'low drifting', + 'BL' => 'blowing', + 'SH' => 'showers', + 'TS' => 'thunderstorms containing', + 'FZ' => 'freezing', + 'RE' => 'recent', + + 'DZ' => 'drizzle', + 'RA' => 'rain', + 'SN' => 'snow', + 'SG' => 'snow grains', + 'IC' => 'ice crystals', + 'PE' => 'ice pellets', + 'GR' => 'hail', + 'GS' => 'small hail/snow pellets', + 'UP' => 'unknown precip', + '//' => 'unknown weather', + + 'BR' => 'mist', + 'FG' => 'fog', + 'FU' => 'smoke', + 'VA' => 'volcanic ash', + 'DU' => 'dust', + 'SA' => 'sand', + 'HZ' => 'haze', + 'PY' => 'spray', + + 'PO' => 'dust/sand whirls', + 'SQ' => 'squalls', + 'FC' => 'tornado', + 'SS' => 'sand storm', + 'DS' => 'dust storm', + '+FC' => 'water spouts', + 'WS' => 'wind shear', + 'BKN' => 'broken', + + 'NOSIG' => 'no significant weather', + 'PRFG' => 'fog banks', # officially PR is a modifier of FG + ); sub as_string { @@ -611,7 +911,7 @@ sub as_string my ($vic, $shower); my @in; push @in, @$self; - + while (@in) { my $t = shift @in; @@ -628,9 +928,9 @@ sub as_string shift; next; } - + push @out, $wt{$t}; - + if (@out && $shower) { $shower = 0; push @out, $wt{'SH'}; @@ -641,18 +941,60 @@ sub as_string return join ' ', @out; } +package Geo::TAF::EN::STATION_TYPE; +use vars qw(@ISA); +@ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +# $code +sub as_string +{ + my $self = shift; + my $code = shift; + my $out = 'Automated station'; + if($code eq '+PRECIP') { + $out .= ' cannot detect precipitation'; + } elsif($code eq '-PRECIP') { + $out .= ' has precipitation discriminator'; + } +} + +package Geo::TAF::EN::PRECIP; +use vars qw(@ISA); +@ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +# $precip, $period +sub as_string +{ + my $self = shift; + my $precip = $self->[0]; + my $period = $self->[1]; + if($period == 1) { + return sprintf 'precipitation %.2f inches in last hour', $precip; + } elsif($period == 24) { + return sprintf '24 hour total precipitation %.2f inches', $precip; + } else { + return sprintf '%d-hour precipitation %.2f', $period, $precip; + } +} + package Geo::TAF::EN::RVR; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } +# $rw, $range, $var, $runit, $tend; sub as_string { my $self = shift; - my $out = "visual range on runway $self->[0] is $self->[1]$self->[3]"; - $out .= " varying to $self->[2]$self->[3]" if defined $self->[2]; + my $out; + $out = sprintf("visual range on runway %s is %s%s", $self->[0], $self->[1], $self->[3]); + $out .= sprintf(" varying to %s%s", $self->[2], $self->[3]) if defined $self->[2]; if (defined $self->[4]) { $out .= " decreasing" if $self->[4] eq 'D'; $out .= " increasing" if $self->[4] eq 'U'; + $out .= " unchanged" if $self->[4] eq 'N'; } return $out; } @@ -660,50 +1002,89 @@ sub as_string package Geo::TAF::EN::RWY; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } +my %rwy = ( + LDG => 'landing', + SKC => 'take-off', + ); sub as_string { my $self = shift; - my $out = $self->[0] eq 'LDG' ? "landing " : ''; - $out .= "runway $self->[1]"; + my $out; + if($rwy{$self->[0]}) { + $out .= $rwy{$self->[0]} . ' '; + } + $out .= sprintf("runway %s", $self->[1]); return $out; } package Geo::TAF::EN::PROB; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } +# $percent, $from, $to; sub as_string { my $self = shift; - - my $out = "probability $self->[0]%"; - $out .= " $self->[1] to $self->[2]" if defined $self->[1]; - return $out; + + return sprintf("probability %s%%", $self->[0]); + # will be followed by a PERIOD block } package Geo::TAF::EN::TEMPO; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } sub as_string { my $self = shift; - my $out = "temporarily"; - $out .= " $self->[0] to $self->[1]" if defined $self->[0]; - - return $out; + return "temporarily"; + # will be followed by a PERIOD block } package Geo::TAF::EN::BECMG; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } sub as_string { my $self = shift; - my $out = "becoming"; - $out .= " $self->[0] to $self->[1]" if defined $self->[0]; + return "becoming"; + # will be followed by a PERIOD block +} + +package Geo::TAF::EN::PERIOD; +use vars qw(@ISA); +@ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +sub as_string +{ + my $self = shift; + # obj, from_time, to_time, from_day, to_day + my ($out, $format); + $out = 'period from '; + # format 1 = time only, no date + # format 2 = time, one day (or two days that are the same value) + # format 3 = time and two different day + $format = 1 if defined $self->[0] && defined $self->[1]; + if(defined $self->[2]) { + $format = 3; + $format-- if not defined $self->[3] or $self->[2] == $self->[3]; + } + if($format == 2) { + $out .= sprintf("%s to %s on %s", $self->[0], $self->[1], $self->day($self->[2])); + } elsif($format == 3) { + $out .= sprintf("%s %s to %s %s", $self->day($self->[2]), $self->[0], $self->day($self->[3]), $self->[1]); + } elsif($format == 1) { + $out .= sprintf("%s to %s", $self->[0], $self->[1]); + } else { + $out .= 'BAD PERIOD'; + } return $out; } @@ -711,34 +1092,176 @@ sub as_string package Geo::TAF::EN::VIZ; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } sub as_string { - my $self = shift; + my $self = shift; + + my $out = 'visibility '; + return $out.'not available' if $self->[0] eq 'NA'; + return $out.sprintf("%s%s%s", ($self->[2] ? $self->[2].' ' : ''), $self->[0], $self->[1]); +} - return "visibility $self->[0]$self->[1]"; +package Geo::TAF::EN::DEP; +use vars qw(@ISA); +@ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +my %cover_type = ( + 0 => 'clear & dry', + 1 => 'damp', + 2 => 'wet/water patches', + 3 => 'frost-covered', + 4 => 'dry snow', + 5 => 'wet snow', + 6 => 'slush', + 7 => 'ice', + 8 => 'compacted snow', + 9 => 'frozen ruts', + '/' => 'unknown', + 'CLRD' => 'cleared', + ); + +my %extent = ( + 1 => '<10%', + 2 => '11-25%', + 5 => '26-50%', + 9 => '51-100%', + '/' => 'not reported', + 'CVRD' => 'non-operational', + ); + +my %depth = ( + 'NR' => 'not reported', + '//' => 'not significent', + ); + +my %breaking = ( + 95 => 'good', + 94 => 'medium/good', + 93 => 'medium', + 92 => 'medium/poor', + 91 => 'poor', + 99 => 'unreliable', + '//' => 'not reported', + ); + +# $rwy, $cover_type, $extent, $depth, $braking +sub as_string +{ + my $self = shift; + + my $out; + $out = sprintf 'Runway %s conditions: %s', $self->[0], $cover_type{$self->[1]}; + if(defined($self->[2])) { + $out .= sprintf(', extent %s',$extent{$self->[2]}); + } + if(defined($self->[3])) { + $_ = $depth{$self->[3]}; + $_ = $self->[3] unless $_; + $out .= sprintf(', depth %s', $_); + } + if(defined($self->[4])) { + $_ = $depth{$self->[4]}; + $out .= sprintf(', braking action %s', $_) if $_; + $out .= sprintf(', friction coefficient %s', $self->[4]) unless $_; + } + $out .= ';'; + + return $out; } package Geo::TAF::EN::FROM; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } sub as_string { - my $self = shift; + my $self = shift; - return "from $self->[0]"; + if($self->[1]) { + return sprintf("from %s on the %s", $self->[0],$self->day($self->[1])); + } else { + return sprintf("from %s", $self->[0]); + } } package Geo::TAF::EN::TIL; use vars qw(@ISA); @ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +sub as_string +{ + my $self = shift; + + if($self->[1]) { + return sprintf("until %s on the %s", $self->[0],$self->day($self->[1])); + } else { + return sprintf("until %s", $self->[0]); + } +} + +package Geo::TAF::EN::AT; +use vars qw(@ISA); +@ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } sub as_string { - my $self = shift; + my $self = shift; - return "until $self->[0]"; + if($self->[1]) { + return sprintf("at %s on the %s", $self->[0],$self->day($self->[1])); + } else { + return sprintf("at %s", $self->[0]); + } +} + +package Geo::TAF::EN::RMK; +use vars qw(@ISA); +@ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +sub as_string +{ + my $self = shift; + + return sprintf("remark %s", $self->[0]); +} + +package Geo::TAF::EN::IGNORE; +use vars qw(@ISA); +@ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +sub as_string +{ + my $self = shift; + return ''; +} + +package Geo::TAF::EN::BLOCK; +=pod +=begin classdoc + +The 'BLOCK' marker is used to explicitly indicate a new block. If producing +human-readable output, this signifies that new line should be started. + +@return nothing + +=end classdoc +=cut +use vars qw(@ISA); +@ISA = qw(Geo::TAF::EN); +sub type { return __PACKAGE__; } + +sub as_string +{ + my $self = shift; + return ''; } # Autoload methods go after =cut, and are processed by the autosplit program. @@ -818,7 +1341,7 @@ a new constructor. If you sub-class the built-in English translation routines then you can pick this up by called the constructor thus:- - + my $t = Geo::TAF->new(chunk_package => 'Geo::TAF::ES'); or whatever takes your fancy. @@ -913,7 +1436,7 @@ Returns a stringified version of any error returned by L =item taf() -Returns whether this object is a taf or not. +Returns whether this object is a TAF or not. =item icao() @@ -1012,10 +1535,12 @@ L =head1 AUTHOR Dirk Koopman, L +With additions/corrections by Robin H. Johnson, L =head1 COPYRIGHT AND LICENSE Copyright (c) 2003 by Dirk Koopman, G1TLH +Portions Copyright (C) 2009 Robin H. Johnson This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. diff --git a/data/cty.dat b/data/cty.dat index 8fbc1c44..1dad21c1 100644 --- a/data/cty.dat +++ b/data/cty.dat @@ -106,7 +106,7 @@ Sierra Leone: 35: 46: AF: 8.50: 13.20: 0.0: 9L: West Malaysia: 28: 54: AS: 3.20: -101.60: -8.0: 9M2: 9M1,9M2,9M4,9W2,9W4; East Malaysia: 28: 54: OC: 5.80: -118.10: -8.0: 9M6: - 9M6,9M8,9W6,9W8,=9M1CSQ,=9M1CSS,=9M4SEA,=9M4SMO; + 9M6,9M8,9W6,9W8,=9M4SEA,=9M4SMO; Nepal: 22: 42: AS: 27.70: -85.30: -5.75: 9N: 9N; Rep. of Congo: 36: 52: AF: -4.30: -15.30: -1.0: 9Q: @@ -138,7 +138,7 @@ Pakistan: 21: 41: AS: 30.00: -70.00: -5.0: AP: Scarborough Reef: 27: 50: AS: 15.10: -117.50: -8.0: BS7: BS7; Taiwan: 24: 44: AS: 23.80: -121.00: -8.0: BV: - BM,BN,BO,BP,BQ,BU,BV,BW,BX; + BM,BN,BO,BP,BQ,BU,BV,BW,BX,=VERSION; Pratas Island: 24: 44: AS: 20.40: -116.40: -8.0: BV9P: BM9P,BN9P,BO9P,BP9P,BQ9P,BU9P,BV9P,BW9P,BX9P; China: 24: 44: AS: 40.00: -116.40: -8.0: BY: @@ -187,11 +187,12 @@ Antarctica: 13: 74: SA: -65.00: 64.00: -4.0: CE9: ANT,AX0,FT0Y(30)[70],FT2Y(30)[70],FT4Y(30)[70],FT5Y(30)[70],FT8Y(30)[70], LU1Z[73],R1AN,VH0(39)[69],VI0(39)[69],VJ0(39)[69],VK0(39)[69],VL0(39)[69], VM0(39)[69],VN0(39)[69],VZ0(39)[69],ZL5(30)[71],ZM5(30)[71],ZS7(38)[67], - =8J1RF(39)[67],=8J1RL(39)[67],=CE9/K2ARB(30)[71],=DP0GVN(38)[67], - =DP1POL(38)[67],=KC4/K2ARB(30)[71],=KC4AAA(39),=KC4AAC[73], - =KC4USB(12)[72],=KC4USV(30)[71],=LU4ZS[73],=OP0LE(38)[67],=OP0OL(38)[67], - =R1ANR(38)[67],=VP8DJB[73],=VP8DKF(30)[71],=VP8DLJ[73],=VP8PJ[73], - =VP8ROT[73]; + =8J1RF(39)[67],=8J1RL(39)[67],=CE9/K2ARB(30)[71],=CE9XX[73], + =DP0GVN(38)[67],=DP1POL(38)[67],=KC4/K2ARB(30)[71],=KC4AAA(39), + =KC4AAC[73],=KC4USB(12)[72],=KC4USV(30)[71],=LU/FT5YJ[73],=LU4ZS[73], + =OP0LE(38)[67],=OP0OL(38)[67],=OR3AX(30)[70],=OR4AX(30)[70], + =R1ANR(38)[67],=VP8DJB[73],=VP8DKF(30)[71],=VP8DLJ[73],=VP8DLM[73], + =VP8PJ[73],=VP8ROT[73]; Cuba: 08: 11: NA: 21.50: 80.00: 5.0: CM: CL,CM,CO,T4; Morocco: 33: 37: AF: 32.00: 5.00: 0.0: CN: @@ -325,20 +326,20 @@ Scotland: 14: 27: EU: 55.80: 4.30: 0.0: GM: =GB0GDS,=GB0GEI,=GB0GHD,=GB0GKR,=GB0GNE,=GB0HHW,=GB0KGS,=GB0KTC,=GB0LCS, =GB0LTM,=GB0MFG,=GB0MLM,=GB0MOL,=GB0NHL,=GB0OS,=GB0OYT,=GB0PPE,=GB0QWM, =GB0RBS,=GB0SHP,=GB0SI,=GB0SK,=GB0SKY,=GB0SS,=GB0SSF,=GB0TI,=GB100MAS, - =GB125BRC,=GB150NRL,=GB1EPC,=GB1FS,=GB1FVT,=GB1OL,=GB2AGG,=GB2AST,=GB2AYR, - =GB2CHG,=GB2DHS,=GB2DTM,=GB2FBM,=GB2FIO,=GB2FSM,=GB2GEO,=GB2GNL,=GB2GTM, - =GB2HI,=GB2HRH,=GB2HST,=GB2HSW,=GB2IAS,=GB2IGB,=GB2IGS,=GB2IMM,=GB2IOC, - =GB2IOG,=GB2IOT,=GB2JUNO,=GB2KDS,=GB2KHL,=GB2LAY,=GB2LBN,=GB2LCL,=GB2LCP, - =GB2LGB,=GB2LHI,=GB2LMG,=GB2LNM,=GB2LO,=GB2LP,=GB2LS,=GB2LSS,=GB2LT, - =GB2LTH,=GB2LTN,=GB2MAS,=GB2MDG,=GB2MOD,=GB2MOF,=GB2MSL,=GB2MUL,=GB2NAG, - =GB2NBC,=GB2NCL,=GB2NEF,=GB2NL,=GB2NTS,=GB2OWM,=GB2OYC,=GB2PBF,=GB2PS, - =GB2RB,=GB2RRL,=GB2SKG,=GB2SLH,=GB2SPD,=GB2SSF,=GB2STB,=GB2TDS,=GB2TI, - =GB2WBB,=GB3GM,=GB400CA,=GB4AAS,=GB4CGW,=GB4DAS,=GB4GM,=GB4LNM,=GB4NFE, - =GB4PMS,=GB4RAF,=GB4SLH,=GB4TSR,=GB4ZBS,=GB50ATC,=GB50JS,=GB50SWL,=GB5AST, - =GB5BBS,=GB5CO,=GB5FHC,=GB5JS,=GB5OL,=GB5RO,=GB5SI,=GB5TI,=GB60BBC, - =GB60CRB,=GB60NTS,=GB6MI,=GB6SA,=GB6SM,=GB6TAA,=GB6WW,=GB700BSB,=GB75GD, - =GB75SCP,=GB75STT,=GB8AYR,=GB8CA,=GB8CF,=GB8CI,=GB8CM,=GB8CN,=GB8CO, - =GB8CSL,=GB8CY,=GB8FF,=GB8OO,=GB8RU,=GB93AM; + =GB125BRC,=GB150NRL,=GB1EPC,=GB1FS,=GB1FVT,=GB1OL,=GB250RB,=GB2AGG, + =GB2AST,=GB2AYR,=GB2CHG,=GB2DHS,=GB2DTM,=GB2FBM,=GB2FIO,=GB2FSM,=GB2GEO, + =GB2GNL,=GB2GTM,=GB2HI,=GB2HLB,=GB2HRH,=GB2HST,=GB2HSW,=GB2IAS,=GB2IGB, + =GB2IGS,=GB2IMM,=GB2IOC,=GB2IOG,=GB2IOT,=GB2JUNO,=GB2KDS,=GB2KHL,=GB2LAY, + =GB2LBN,=GB2LCL,=GB2LCP,=GB2LGB,=GB2LHI,=GB2LMG,=GB2LNM,=GB2LO,=GB2LP, + =GB2LS,=GB2LSS,=GB2LT,=GB2LTH,=GB2LTN,=GB2MAS,=GB2MDG,=GB2MOD,=GB2MOF, + =GB2MSL,=GB2MUL,=GB2NAG,=GB2NBC,=GB2NCL,=GB2NEF,=GB2NL,=GB2NTS,=GB2OWM, + =GB2OYC,=GB2PBF,=GB2PS,=GB2RB,=GB2RRL,=GB2SKG,=GB2SLH,=GB2SPD,=GB2SSF, + =GB2STB,=GB2TDS,=GB2TI,=GB2WBB,=GB3GM,=GB400CA,=GB4AAS,=GB4CGW,=GB4DAS, + =GB4GM,=GB4LNM,=GB4NFE,=GB4PMS,=GB4RAF,=GB4SLH,=GB4TSR,=GB4ZBS,=GB50ATC, + =GB50JS,=GB50SWL,=GB5AST,=GB5BBS,=GB5CO,=GB5FHC,=GB5JS,=GB5OL,=GB5RO, + =GB5SI,=GB5TI,=GB60BBC,=GB60CRB,=GB60NTS,=GB6MI,=GB6SA,=GB6SM,=GB6TAA, + =GB6WW,=GB700BSB,=GB75GD,=GB75SCP,=GB75STT,=GB8AYR,=GB8CA,=GB8CF,=GB8CI, + =GB8CM,=GB8CN,=GB8CO,=GB8CSL,=GB8CY,=GB8FF,=GB8OO,=GB8RU,=GB93AM; Shetland: 14: 27: EU: 60.40: 1.50: 0.0: *GM/s: GZ,MZ,=2M0BDR,=2M0BDT,=2M0ZET,=GB2ELH,=GM0AVR,=GM0CXQ,=GM0CYJ,=GM0DJI, =GM0EKM,=GM0ILB,=GM0ULK,=GM1KKI,=GM1ZNR,=GM3KLA,=GM3WHT,=GM3ZET,=GM3ZNM, @@ -359,8 +360,8 @@ Wales: 14: 27: EU: 51.50: 3.20: 0.0: GW: =GB2MLM,=GB2MOP,=GB2RFS,=GB2RSC,=GB2RTB,=GB2SAC,=GB2SDD,=GB2SIP,=GB2TD, =GB2TTA,=GB2VK,=GB2WDS,=GB2WFF,=GB2WHO,=GB2WSF,=GB4BPL,=GB4CI,=GB4DPS, =GB4HMD,=GB4HMM,=GB4LRG,=GB4LSG,=GB4MD,=GB4MDI,=GB4MUU,=GB4NDG,=GB4SA, - =GB4SDD,=GB4SMM,=GB4SNF,=GB4TMS,=GB4XXX,=GB5BS/J,=GB5FI,=GB5SIP,=GB60VLY, - =GB6AR,=GB6GW,=GB6OQA,=GB750CC,=GB8OQE; + =GB4SDD,=GB4SMM,=GB4SNF,=GB4TMS,=GB4XXX,=GB5BS/J,=GB5FI,=GB5ONG,=GB5SIP, + =GB60VLY,=GB6AR,=GB6GW,=GB6OQA,=GB750CC,=GB8OQE; Solomon Islands: 28: 51: OC: -9.40: -160.00: -11.0: H4: H4; Temotu: 32: 51: OC: -10.70: -165.80: -11.0: H40: @@ -382,7 +383,7 @@ Dominican Republic: 08: 11: NA: 18.50: 70.00: 4.0: HI: Colombia: 09: 12: SA: 4.60: 74.10: 5.0: HK: 5J,5K,HJ,HK; San Andres/Providencia: 07: 11: NA: 12.50: 81.70: 5.0: HK0/a: - 5J0,5K0,HJ0,HK0,=5K0T(8); + 5J0,5K0,HJ0,HK0; Malpelo I.: 09: 12: SA: 4.00: 81.10: 5.0: HK0/m: =HK0TU; South Korea: 25: 44: AS: 37.50: -127.00: -9.0: HL: @@ -404,8 +405,8 @@ Italy: 15: 28: EU: 41.90: -12.50: -1.0: I: Italy (Africa): 33: 37: AF: 35.40: -12.50: -1.0: *IG9: IG9,IH9; Sardinia: 15: 28: EU: 39.20: -9.10: -1.0: IS: - IM0,IS,IW0U,IW0V,IW0W,IW0X,IW0Y,IW0Z,=IQ0AG,=IQ0AH,=IQ0AI,=IQ0AK,=IQ0AL, - =IQ0AM,=IQ0EH,=IQ0HO,=IQ0QP,=IQ0SS; + IM0,IS,IW0U,IW0V,IW0W,IW0X,IW0Y,IW0Z,=II0SB,=IQ0AG,=IQ0AH,=IQ0AI,=IQ0AK, + =IQ0AL,=IQ0AM,=IQ0EH,=IQ0HO,=IQ0QP,=IQ0SS; Sicily: 15: 28: EU: 37.50: -14.00: -1.0: *IT9: IB9,ID9,IE9,IF9,II9,IJ9,IO9,IQ9,IR9,IT,IU9,IW9,IZ9; Djibouti: 37: 48: AF: 11.60: -43.20: -3.0: J2: @@ -424,7 +425,7 @@ Japan: 25: 45: AS: 35.70: -139.80: -9.0: JA: 7J,7K,7L,7M,7N,8J,8K,8L,8M,8N,JA,JB,JC,JE,JF,JG,JH,JI,JJ,JK,JL,JM,JN,JO, JP,JQ,JR,JS; Minami Torishima: 27: 90: OC: 24.30: -154.00: -10.0: JD/m: - =JD1BME,=JD1BMM,=JD1YAA,=JD1YBJ; + =JD1BME,=JD1BMM,=JD1BND,=JD1YAA,=JD1YBJ; Ogasawara: 27: 45: AS: 27.50: -141.00: -9.0: JD/o: JD1; Mongolia: 23: 32: AS: 47.90: -106.90: -8.0: JT: @@ -461,35 +462,35 @@ United States: 05: 08: NA: 43.00: 87.90: 5.0: K: =K9VV(5),=K9WZB(3)[6],=K9YC(3)[6],=KA2EYH(4),=KA4OTB(4),=KA8Q(5), =KB4AMA(4),=KB7Q(4)[6],=KC4HW(4),=KC4SAW(4),=KC6R(4)[7],=KC7UP(4)[6], =KD4HXT(3)[6],=KD4SN(4),=KD5M(5)[8],=KE3D(4)[7],=KE4KWE(4),=KE4KY(4), - =KE4MBP(4),=KE7NO(4)[6],=KF7NN(5)[8],=KG4CUY(4),=KG4NOZ(4),=KG7HF(5)[8], - =KH6DX(3)[6],=KH7WW(3)[6],=KL1SE(4)[8],=KL7OO(3)[6],=KL7WP(3)[6],=KN4Q(4), - =KN5H(3)[6],=KN6RO(5)[8],=KO7X(4)[7],=KP2F(4)[8],=KP3M(5)[8],=KR4F(4), - =KR4TI(4),=KS4X(4),=KS5A(3)[6],=KS7T(4)[6],=KT2Z(4)[7],=KU1CW(4)[7], - =KU8E(5),=KV6O(4)[7],=KV9R(5),=KY4F(4),=KZ4V(4),=KZ5OH(5)[8],=N1CC(4)[7], - =N1QXV(4)[7],=N1WQ(4)[7],=N2BJ(4),=N2BZP(3)[6],=N2IC(4)[7],=N2NS(4), - =N2WN(4),=N3BB(4)[7],=N3HE(4),=N3KCJ(3)[6],=N3PV(3)[6],=N3ZI(3)[6], - =N3ZZ(3)[6],=N4ARO(4),=N4AU(4),=N4BCB(4),=N4CB(3)[6],=N4CBK(4), - =N4CYV(4)[7],=N4DW(4),=N4ECJ(4),=N4GK(4),=N4GN(4),=N4HID(4),=N4IJ(4)[7], - =N4IR(4),=N4JF(4),=N4KC(4),=N4KG(4),=N4KZ(4),=N4LS(3)[6],=N4LW(4), - =N4NM(4),=N4NO(4),=N4OGW(4)[7],=N4PF(4),=N4PT(3)[6],=N4QS(4),=N4RR(4), - =N4SL(3)[6],=N4TN(4),=N4TZ(4),=N4UC(4),=N4VN(4),=N4VV(4),=N4XM(4), - =N4ZI(4),=N4ZZ(4),=N5RA(3)[6],=N5VI(5)[8],=N6AR(5)[8],=N6CY(5)[8], - =N6DT(4)[7],=N6RFM(5)[8],=N6ZO(5)[8],=N7DF(4)[7],=N7IV(4)[7],=N7KA(4)[7], - =N7NG(4)[6],=N7VR(4)[6],=N8GZ(3)[6],=N8II(5),=N8NA(5),=N8PR(5),=N8RA(5), - =N8RR(5),=N8WXQ(5),=N9ADG(3)[6],=N9JRZ(5),=NA4C(4),=NA4K(4),=NA4M(4)[7], - =NB7V(4)[6],=ND2T(3)[6],=NE4M(4),=NE8J(5),=NH0Y(3)[6],=NH6CN(4)[8], - =NI9K(5),=NJ2P(3)[6],=NJ4I(4),=NL7FK(4)[8],=NN7A(4)[7],=NO9E(5), - =NP2CB(5)[8],=NP3D(5)[8],=NQ4U(4),=NS0I(5)[8],=NS2X(4),=NT4TT(3)[6], - =NU4B(4),=NU4N(4),=NV4B(4),=NW7O(4)[6],=NW8U(5),=NX9T(5),=NY4N(4), - =W0AH(5)[8],=W0BR(5)[8],=W0ID(5)[8],=W0JLC(5)[8],=W0QQG(5)[8], - =W0UCE(5)[8],=W0YK(3)[6],=W0YR(5)[8],=W1ESE(3)[6],=W1NN(4),=W1RET(4), - =W1RH(3)[6],=W1SKU(4),=W1YY(3)[6],=W2OO(4),=W2PK(3)[6],=W2VJN(3)[6], - =W2WB(3)[6],=W3CP(3)[6],=W3FAF(4)[7],=W3HDH(4),=W3HKK(4),=W3IQ(4), - =W4BCG(4),=W4CID(4),=W4CKD(4),=W4DAN(4),=W4DEC(4),=W4DIM(4),=W4DVG(4), - =W4EEH(4),=W4FIN(4),=W4GHD(4),=W4GKM(4),=W4HRC(4),=W4JSI(4),=W4KW(4), - =W4LC(4),=W4LSC(3)[6],=W4NBS(4),=W4NI(4),=W4NJK(3)[6],=W4NL(4),=W4NTI(4), - =W4NZ(4),=W4PA(4),=W4PV(4),=W4RJ(4),=W4RK(4)[7],=W4RYW(4),=W4SK(4), - =W4UAT(3)[6],=W4UDX(4),=W4UHF(4),=W4UR(4),=W4WL(4),=W4YOK(4)[7], + =KE4MBP(4),=KE7NO(4)[6],=KF7NN(5)[8],=KG4CUY(4),=KG4NOZ(4),=KG4W, + =KG7HF(5)[8],=KH6DX(3)[6],=KH7WW(3)[6],=KL1SE(4)[8],=KL7OO(3)[6], + =KL7WP(3)[6],=KN4Q(4),=KN5H(3)[6],=KN6RO(5)[8],=KO7X(4)[7],=KP2F(4)[8], + =KP3M(5)[8],=KR4F(4),=KR4TI(4),=KS4X(4),=KS5A(3)[6],=KS7T(4)[6], + =KT2Z(4)[7],=KU1CW(4)[7],=KU8E(5),=KV6O(4)[7],=KV9R(5),=KY4F(4),=KZ4V(4), + =KZ5OH(5)[8],=N1CC(4)[7],=N1QXV(4)[7],=N1WQ(4)[7],=N2BJ(4),=N2BZP(3)[6], + =N2IC(4)[7],=N2NS(4),=N2WN(4),=N3BB(4)[7],=N3HE(4),=N3KCJ(3)[6], + =N3PV(3)[6],=N3ZI(3)[6],=N3ZZ(3)[6],=N4ARO(4),=N4AU(4),=N4BCB(4), + =N4CB(3)[6],=N4CBK(4),=N4CYV(4)[7],=N4DW(4),=N4ECJ(4),=N4GK(4),=N4GN(4), + =N4HID(4),=N4IJ(4)[7],=N4IR(4),=N4JF(4),=N4KC(4),=N4KG(4),=N4KZ(4), + =N4LS(3)[6],=N4LW(4),=N4NM(4),=N4NO(4),=N4OGW(4)[7],=N4PF(4),=N4PT(3)[6], + =N4QS(4),=N4RR(4),=N4SL(3)[6],=N4TN(4),=N4TZ(4),=N4UC(4),=N4VN(4), + =N4VV(4),=N4XM(4),=N4ZI(4),=N4ZZ(4),=N5RA(3)[6],=N5VI(5)[8],=N6AR(5)[8], + =N6CY(5)[8],=N6DT(4)[7],=N6RFM(5)[8],=N6ZO(5)[8],=N7DF(4)[7],=N7IV(4)[7], + =N7KA(4)[7],=N7NG(4)[6],=N7VR(4)[6],=N8GZ(3)[6],=N8II(5),=N8NA(5), + =N8PR(5),=N8RA(5),=N8RR(5),=N8WXQ(5),=N9ADG(3)[6],=N9JRZ(5),=NA4C(4), + =NA4K(4),=NA4M(4)[7],=NB7V(4)[6],=ND2T(3)[6],=NE4M(4),=NE8J(5), + =NH0Y(3)[6],=NH6CN(4)[8],=NI9K(5),=NJ2P(3)[6],=NJ4I(4),=NL7FK(4)[8], + =NN7A(4)[7],=NO9E(5),=NP2CB(5)[8],=NP3D(5)[8],=NQ4U(4),=NS0I(5)[8], + =NS2X(4),=NT4TT(3)[6],=NU4B(4),=NU4N(4),=NV4B(4),=NW7O(4)[6],=NW8U(5), + =NX9T(5),=NY4N(4),=W0AH(5)[8],=W0BR(5)[8],=W0ID(5)[8],=W0JLC(5)[8], + =W0QQG(5)[8],=W0UCE(5)[8],=W0YK(3)[6],=W0YR(5)[8],=W1ESE(3)[6],=W1NN(4), + =W1RET(4),=W1RH(3)[6],=W1SKU(4),=W1YY(3)[6],=W2OO(4),=W2PK(3)[6], + =W2VJN(3)[6],=W2WB(3)[6],=W3CP(3)[6],=W3FAF(4)[7],=W3HDH(4),=W3HKK(4), + =W3IQ(4),=W4BCG(4),=W4CID(4),=W4CKD(4),=W4DAN(4),=W4DEC(4),=W4DIM(4), + =W4DVG(4),=W4EEH(4),=W4FIN(4),=W4GHD(4),=W4GKM(4),=W4HRC(4),=W4JSI(4), + =W4KW(4),=W4LC(4),=W4LSC(3)[6],=W4NBS(4),=W4NI(4),=W4NJK(3)[6],=W4NL(4), + =W4NTI(4),=W4NZ(4),=W4PA(4),=W4PV(4),=W4RJ(4),=W4RK(4)[7],=W4RYW(4), + =W4SK(4),=W4UAT(3)[6],=W4UDX(4),=W4UHF(4),=W4UR(4),=W4WL(4),=W4YOK(4)[7], =W5JBV(5)[8],=W5JR(3)[6],=W5REA(5)[8],=W6AAN(5)[8],=W6IHG(5)[8], =W6IZT(5)[8],=W6LFB(4)[7],=W6NRJ(5)[8],=W6NWS(5)[8],=W6PU(4)[7], =W6TER(4)[7],=W6UB(4)[8],=W6XR(5)[8],=W7DO(5)[8],=W7ED(4)[6],=W7FG(4)[7], @@ -509,7 +510,7 @@ United States: 05: 08: NA: 43.00: 87.90: 5.0: K: Guantanamo Bay: 08: 11: NA: 19.90: 75.20: 5.0: KG4: KG4; Mariana Is.: 27: 64: OC: 15.20: -145.80: -10.0: KH0: - AH0,KH0,NH0,WH0,=KG6SL,=VERSION; + AH0,KH0,NH0,WH0,=KG6SL; Baker & Howland Is.: 31: 61: OC: 0.50: 176.00: 12.0: KH1: AH1,KH1,NH1,WH1; Guam: 27: 64: OC: 13.50: -144.80: -10.0: KH2: @@ -541,7 +542,7 @@ Virgin Is.: 08: 11: NA: 18.30: 64.90: 4.0: KP2: Puerto Rico: 08: 11: NA: 18.50: 66.20: 4.0: KP4: KP3,KP4,NP3,NP4,WP3,WP4; Desecheo I.: 08: 11: NA: 18.30: 67.50: 4.0: KP5: - KP5,NP5,WP5; + KP5,NP5,WP5,=K5D; Norway: 14: 18: EU: 60.00: -10.70: -1.0: LA: LA,LB,LC,LD,LE,LF,LG,LH,LI,LJ,LK,LL,LM,LN; Argentina: 13: 14: SA: -34.60: 58.40: 3.0: LU: @@ -550,38 +551,40 @@ Argentina: 13: 14: SA: -34.60: 58.40: 3.0: LU: =L30EY/D,=L30EY/V,=L40E/D,=L44D/D,=L80AA/D,=L84VI/D,=L8D/X,=LO0D/D, =LO7E/D,=LU/DH4PB/R,=LU/DH4PB/S,=LU1AEE/D,=LU1AF/D,=LU1CDP/D,=LU1DHO/D, =LU1DK/D,=LU1DMA/E,=LU1DZ/E,=LU1DZ/P,=LU1DZ/Q,=LU1DZ/R,=LU1DZ/S,=LU1DZ/X, - =LU1EJ/W,=LU1EQ/D,=LU1EUU/W,=LU1EYW/D,=LU1OFN/I,=LU1VOF/D,=LU1VZ/V, - =LU1XAW/X,=LU1XWC/E,=LU1XY/X,=LU1YU/D,=LU1YY/Y,=LU2CRM/XA,=LU2DT/D, - =LU2DT/LH,=LU2DVI/H,=LU2EE/D,=LU2EE/E,=LU2EJB/X,=LU2VC/D,=LU2VDV/D, - =LU2WV/O,=LU2XX/X,=LU3CQ/D,=LU3DC/D,=LU3DJI/D,=LU3DJI/W,=LU3DOC/D, - =LU3DR/D,=LU3DR/V,=LU3DXG/D,=LU3DZO/D,=LU3EOU/D,=LU3ES/D,=LU3ES/V, - =LU3ES/W,=LU3HKA/D,=LU3HKA/H,=LU4AAO/D,=LU4DA/D,=LU4DBP/D,=LU4DBT/D, - =LU4DQ/D,=LU4DRC/Y,=LU4DRH/D,=LU4DRH/E,=LU4EHP/V,=LU4EJ/D,=LU4ELE/D, - =LU4ESP/D,=LU4ETN/D,=LU4ETN/W,=LU4EV/Q,=LU4UZW/D,=LU4WG/W,=LU5BE/D, - =LU5BOJ/O,=LU5DEM/D,=LU5DEM/V,=LU5DEM/W,=LU5DIT/D,=LU5DIT/V,=LU5DIT/W, - =LU5DRV/D,=LU5DRV/V,=LU5DT/D,=LU5DV/D,=LU5DWS/D,=LU5EAO/D,=LU5EFX/Y, - =LU5EJL/D,=LU5EWO/D,=LU5FZ/D,=LU5VAT/D,=LU5XC/X,=LU6DBL/D,=LU6DBL/W, - =LU6DKT/D,=LU6DRD/D,=LU6DRD/E,=LU6DRN/D,=LU6DRR/D,=LU6EC/W,=LU6EJJ/D, - =LU6EPE/D,=LU6EPR/D,=LU6EPR/E,=LU6EU/D,=LU6EYK/X,=LU6JJ/D,=LU6UAL/D, - =LU6UO/D,=LU6UO/P,=LU6UO/Q,=LU6UO/R,=LU6UO/S,=LU6UO/X,=LU6XAH/X,=LU7AC/D, - =LU7BTO/D,=LU7DBL/D,=LU7DID/V,=LU7DID/Y,=LU7DIR/D,=LU7DJJ/W,=LU7DP/D, - =LU7DR/D,=LU7DSY/D,=LU7DSY/V,=LU7DSY/W,=LU7DW/D,=LU7DZL/D,=LU7DZL/E, - =LU7EGH/V,=LU7EGY/D,=LU7EHL/D,=LU7EO/D,=LU7EPC/D,=LU7EPC/W,=LU7HW/D, - =LU7VCH/D,=LU7WFM/W,=LU7WW/W,=LU8ADX/D,=LU8DCH/D,=LU8DCH/Q,=LU8DIP/D, - =LU8DR/D,=LU8DRA/W,=LU8DRH/D,=LU8DSJ/D,=LU8DWR/D,=LU8DWR/V,=LU8EBJ/D, - =LU8EBJ/E,=LU8EBK/D,=LU8EBK/E,=LU8ECF/D,=LU8ECF/E,=LU8EEM/D,=LU8EFF/D, - =LU8EGS/D,=LU8EHQ/D,=LU8EHQ/E,=LU8EHQ/W,=LU8EKB/W,=LU8EKC/D,=LU8EOT/X, + =LU1EEZ/D,=LU1EJ/W,=LU1EQ/D,=LU1EUU/W,=LU1EYW/D,=LU1OFN/I,=LU1VOF/D, + =LU1VZ/V,=LU1WCR/W,=LU1WF/W,=LU1WP/W,=LU1XAW/X,=LU1XWC/E,=LU1XY/X, + =LU1YU/D,=LU1YY/Y,=LU2AGQ/D,=LU2CRM/XA,=LU2DT/D,=LU2DT/LH,=LU2DVI/H, + =LU2EE/D,=LU2EE/E,=LU2EJB/X,=LU2VC/D,=LU2VCD/V,=LU2VDV/D,=LU2WV/O, + =LU2XBI/XA,=LU2XX/X,=LU3CQ/D,=LU3DC/D,=LU3DJI/D,=LU3DJI/W,=LU3DOC/D, + =LU3DR/D,=LU3DR/V,=LU3DXG/D,=LU3DXG/W,=LU3DZO/D,=LU3EOU/D,=LU3ES/D, + =LU3ES/V,=LU3ES/W,=LU3HKA/D,=LU3HKA/H,=LU4AAO/D,=LU4DA/D,=LU4DBP/D, + =LU4DBT/D,=LU4DQ/D,=LU4DRC/Y,=LU4DRH/D,=LU4DRH/E,=LU4EHP/V,=LU4EJ/D, + =LU4ELE/D,=LU4ESP/D,=LU4ETN/D,=LU4ETN/W,=LU4EV/Q,=LU4UZW/D,=LU4WG/W, + =LU5BE/D,=LU5BE/XA,=LU5BOJ/O,=LU5DEM/D,=LU5DEM/V,=LU5DEM/W,=LU5DIT/D, + =LU5DIT/V,=LU5DIT/W,=LU5DRV/D,=LU5DRV/V,=LU5DT/D,=LU5DV/D,=LU5DWS/D, + =LU5EAO/D,=LU5EFX/Y,=LU5EJL/D,=LU5EWO/D,=LU5FZ/D,=LU5VAT/D,=LU5XC/X, + =LU6DBL/D,=LU6DBL/W,=LU6DDC/D,=LU6DG/D,=LU6DKT/D,=LU6DRD/D,=LU6DRD/E, + =LU6DRN/D,=LU6DRR/D,=LU6DTB/D,=LU6EC/W,=LU6EJJ/D,=LU6EPE/D,=LU6EPR/D, + =LU6EPR/E,=LU6EU/D,=LU6EYK/X,=LU6JJ/D,=LU6UAL/D,=LU6UO/D,=LU6UO/P, + =LU6UO/Q,=LU6UO/R,=LU6UO/S,=LU6UO/X,=LU6WG/W,=LU6XAH/X,=LU7AC/D,=LU7BTO/D, + =LU7DBL/D,=LU7DID/V,=LU7DID/Y,=LU7DIR/D,=LU7DJJ/W,=LU7DP/D,=LU7DR/D, + =LU7DSY/D,=LU7DSY/V,=LU7DSY/W,=LU7DW/D,=LU7DZL/D,=LU7DZL/E,=LU7EGH/V, + =LU7EGY/D,=LU7EHL/D,=LU7EO/D,=LU7EPC/D,=LU7EPC/W,=LU7HW/D,=LU7VCH/D, + =LU7WFM/W,=LU7WW/W,=LU8ADX/D,=LU8DCH/D,=LU8DCH/Q,=LU8DIP/D,=LU8DR/D, + =LU8DRA/W,=LU8DRH/D,=LU8DSJ/D,=LU8DWR/D,=LU8DWR/V,=LU8EBJ/D,=LU8EBJ/E, + =LU8EBK/D,=LU8EBK/E,=LU8ECF/D,=LU8ECF/E,=LU8EEM/D,=LU8EFF/D,=LU8EGS/D, + =LU8EHQ/D,=LU8EHQ/E,=LU8EHQ/W,=LU8EHV/D,=LU8EKB/W,=LU8EKC/D,=LU8EOT/X, =LU8EOT/Y,=LU8ERH/D,=LU8EXJ/D,=LU8EXN/D,=LU8FOZ/V,=LU8VCC/D,=LU8WFT/Q, - =LU8XC/X,=LU8XW/X,=LU8XW/XD,=LU9ARB/D,=LU9AUC/D,=LU9DBK/X,=LU9DKX/X, - =LU9DPD/XA,=LU9EI/F,=LU9EJS/E,=LU9ESD/D,=LU9ESD/F,=LU9ESD/V,=LU9ESD/W, - =LU9ESD/Y,=LU9EV/LH,=LU9JMG/J,=LW1DAL/D,=LW1EXU/D,=LW1EXU/Y,=LW2DX/E, - =LW2DX/P,=LW2DX/Q,=LW2DX/R,=LW2DX/S,=LW2DX/Y,=LW2EFS/D,=LW2ENB/D, - =LW3DKC/D,=LW3DKC/E,=LW3DKO/D,=LW3DKO/E,=LW3HAQ/D,=LW4DRH/D,=LW4DRH/E, - =LW4DRV/D,=LW4ECV/D,=LW4EM/E,=LW4EM/LH,=LW5DR/LH,=LW5DWX/D,=LW5EE/D, - =LW5EE/V,=LW5EOL/D,=LW6DTM/D,=LW7DAF/D,=LW7DAF/W,=LW7DLY/D,=LW7DNS/E, - =LW7EJV/D,=LW7WFM/W,=LW8DMK/D,=LW8DMK/W,=LW8EAG/D,=LW8ECQ/D,=LW8EU/D, - =LW8EXF/D,=LW9DCF/Y,=LW9DX/D,=LW9EAG/D,=LW9EAG/V,=LW9EAG/W,=LW9EVA/D, - =LW9EVA/E; + =LU8XC/X,=LU8XW/X,=LU8XW/XD,=LU9ARB/D,=LU9AUC/D,=LU9DBK/X,=LU9DF/D, + =LU9DKX/X,=LU9DO/D,=LU9DPD/XA,=LU9EI/F,=LU9EJS/E,=LU9ESD/D,=LU9ESD/F, + =LU9ESD/V,=LU9ESD/W,=LU9ESD/Y,=LU9EV/D,=LU9EV/LH,=LU9JMG/J,=LW1DAL/D, + =LW1DE/D,=LW1EXU/D,=LW1EXU/Y,=LW2DX/E,=LW2DX/P,=LW2DX/Q,=LW2DX/R,=LW2DX/S, + =LW2DX/Y,=LW2EFS/D,=LW2ENB/D,=LW3DKC/D,=LW3DKC/E,=LW3DKO/D,=LW3DKO/E, + =LW3HAQ/D,=LW4DRH/D,=LW4DRH/E,=LW4DRV/D,=LW4ECV/D,=LW4EM/E,=LW4EM/LH, + =LW5DR/LH,=LW5DWX/D,=LW5EE/D,=LW5EE/V,=LW5EOL/D,=LW6DTM/D,=LW7DAF/D, + =LW7DAF/W,=LW7DLY/D,=LW7DNS/E,=LW7EDH/D,=LW7EJV/D,=LW7WFM/W,=LW8DMK/D, + =LW8DMK/W,=LW8EAG/D,=LW8ECQ/D,=LW8EU/D,=LW8EXF/D,=LW9DCF/Y,=LW9DX/D, + =LW9EAG/D,=LW9EAG/V,=LW9EAG/W,=LW9EVA/D,=LW9EVA/E; Luxembourg: 14: 27: EU: 49.60: -6.20: -1.0: LX: LX; Lithuania: 15: 29: EU: 54.50: -25.50: -2.0: LY: @@ -593,7 +596,8 @@ Peru: 10: 12: SA: -10.00: 76.00: 5.0: OA: Lebanon: 20: 39: AS: 33.80: -35.80: -2.0: OD: OD; Austria: 15: 28: EU: 47.30: -13.30: -1.0: OE: - OE,=4U1VIC,=4U1WED; + OE,=4U1VIC,=4U1WED,=OE3AGA/AAW,=OE3AIS/AAW,=OE3HM/AAW,=OE3KKA/AAW, + =OE3RPB/AAW,=OE3SGA/AAW,=OE3WWB/AAW; Finland: 15: 18: EU: 60.20: -25.00: -2.0: OH: OF,OG,OH,OI,OJ; Aland Is.: 15: 18: EU: 60.20: -20.00: -2.0: OH0: @@ -782,7 +786,8 @@ Uzbekistan: 17: 30: AS: 41.20: -69.30: -5.0: UK: Kazakhstan: 17: 30: AS: 43.30: -76.90: -5.0: UN: UN,UO,UP,UQ; Ukraine: 16: 29: EU: 50.40: -30.50: -2.0: UR: - EM,EN,EO,U5,UR,US,UT,UU,UV,UW,UX,UY,UZ; + EM,EN,EO,U5,UR,US,UT,UU,UV,UW,UX,UY,UZ,=UR2XO/WAP,=UR5KCC/WAP,=UR5KGG/WAP, + =UR8LV/WAP,=UT1KY/WAP,=UT7UA/WAP; Antigua & Barbuda: 08: 11: NA: 17.10: 61.80: 4.0: V2: V2; Belize: 07: 11: NA: 17.30: 88.80: 6.0: V3: @@ -805,8 +810,8 @@ Canada: 05: 09: NA: 45.00: 80.00: 4.0: VE: XM,XN1(5)[9],XN2(2)[9],XO0(2)[4],XO1(1)[2],XO2(5)[9],=CY2ZT/2(5), =K3FMQ/VE2(2),=KD3RF/VE2(2),=KD3TB/VE2(2),=VA2BY(2),=VA2CT(2),=VA2DO(2), =VA2DXE(2),=VA2KCE(2),=VA2RHJ(2),=VA2UA(2),=VA2VFT(2),=VA2ZM(2), - =VA3NA/2(2),=VB2C(2),=VB2R(2),=VB2V(2),=VC2C(2),=VE2/K3FMQ(2),=VE2ACP(2), - =VE2AE(2),=VE2AG(2),=VE2AOF(2),=VE2AQS(2),=VE2AS(2),=VE2BQB(2),=VE2CSI(2), + =VA3NA/2(2),=VB2C(2),=VB2R(2),=VB2V(2),=VC2C(2),=VE2/K3FMQ(2),=VE2AE(2), + =VE2AG(2),=VE2AOF(2),=VE2AQS(2),=VE2AS(2),=VE2BQB(2),=VE2CSI(2), =VE2CVI(2),=VE2DMG(2),=VE2DS(2),=VE2DWU(2),=VE2DXY(2),=VE2DYW(2), =VE2DYX(2),=VE2EAK(2),=VE2EDL(2),=VE2EDX(2),=VE2ELL(2),=VE2ENB(2), =VE2END(2),=VE2ENR(2),=VE2ERU(2),=VE2FCV(2),=VE2GSA(2),=VE2GSO(2), @@ -814,7 +819,7 @@ Canada: 05: 09: NA: 45.00: 80.00: 4.0: VE: =VE2PR(2),=VE2QRZ(2),=VE2RB(2),=VE2TVU(2),=VE2UA(2),=VE2VH(2),=VE2WDX(2), =VE2WT(2),=VE2XAA/2(2),=VE2XY(2),=VE2YM(2),=VE2Z(2),=VE2ZC(5),=VE2ZM(5), =VE2ZV(5),=VE3EY/2(2),=VE3NE/2(2),=VE3RHJ/2(2),=VE8AJ(2),=VE8PW(2), - =VE8RCS(2),=VER20081209,=VY0AA(4)[3],=VY0PW(4)[3],=VY2MGY/3(4)[4]; + =VE8RCS(2),=VER20090219,=VY0AA(4)[3],=VY0PW(4)[3],=VY2MGY/3(4)[4]; Australia: 30: 59: OC: -22.00: -135.00: -10.0: VK: AX,VH,VI,VJ,VK,VL,VM,VN,VZ; Heard I.: 39: 68: AF: -53.00: -73.40: -5.0: VK0H: @@ -828,13 +833,13 @@ Lord Howe I.: 30: 60: OC: -31.60: -159.10: -10.5: VK9L: AX9L,VH9L,VI9L,VJ9L,VK9AL,VK9CL,VK9FL,VK9GL,VK9KL,VK9L,VL9L,VM9L,VN9L, VZ9L; Mellish Reef: 30: 56: OC: -17.60: -155.80: -10.0: VK9M: - AX9M,VH9M,VI9M,VJ9M,VK9FM,VK9KM,VK9M,VL9M,VM9M,VN9M,VZ9M; + AX9M,VH9M,VI9M,VJ9M,VK9FM,VK9KM,VK9M,VL9M,VM9M,VN9M,VZ9M,=VK9GMW; Norfolk I.: 32: 60: OC: -29.00: -168.00: -11.5: VK9N: AX9,VH9,VI9,VJ9,VK9,VK9CN,VL9,VM9,VN9,VZ9; Willis I.: 30: 55: OC: -16.20: -150.00: -10.0: VK9W: AX9W,VH9W,VI9W,VJ9W,VK9FW,VK9KW,VK9W,VL9W,VM9W,VN9W,VZ9W,=VK9DWX; Christmas I.: 29: 54: OC: -10.50: -105.70: -7.0: VK9X: - AX9X,VH9X,VI9X,VJ9X,VK9FX,VK9KX,VK9X,VL9X,VM9X,VN9X,VZ9X; + AX9X,VH9X,VI9X,VJ9X,VK9FX,VK9KX,VK9X,VL9X,VM9X,VN9X,VZ9X,=JA1XGI/VK9; Anguilla: 08: 11: NA: 18.30: 63.00: 4.0: VP2E: VP2E; Montserrat: 08: 11: NA: 16.80: 62.20: 4.0: VP2M: @@ -852,8 +857,8 @@ Falkland Is.: 13: 16: SA: -51.70: 57.90: 4.0: VP8: South Georgia: 13: 73: SA: -54.30: 36.80: 2.0: VP8/g: =VP8DIF,=VP8SGK; South Shetland: 13: 73: SA: -62.00: 58.30: 4.0: VP8/h: - CE9,=DT8A,=ED3RKL,=HF0APAS,=HF0POL,=HL8KSJ,=LU1ZC,=LZ0A,=R1ANF,=VP8/LZ1UQ, - =VP8DJK; + CE9,=DT8A,=ED3RKL,=HC0/FT5YJ,=HF0APAS,=HF0POL,=HL8KSJ,=LU1ZC,=LZ0A, + =OA0/FT5YJ,=R1ANF,=VP8/LZ1UQ,=VP8DJK; South Orkney: 13: 73: SA: -60.00: 45.50: 3.0: VP8/o: =AY1ZA,=LU1ZA; South Sandwich: 13: 73: SA: -57.00: 26.70: 2.0: VP8/s: diff --git a/data/prefix_data.pl b/data/prefix_data.pl index 03399006..e10c1d70 100644 --- a/data/prefix_data.pl +++ b/data/prefix_data.pl @@ -285,11 +285,8 @@ '=4U7ITU' => '274', '=4U8ITU' => '274', '=4U9ITU' => '274', - '=5K0T' => '77', '=8J1RF' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=8J1RL' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', - '=9M1CSQ' => '303,529', - '=9M1CSS' => '303,529', '=9M4SEA' => '303,529', '=9M4SMO' => '303,529', '=AA6DY' => '220', @@ -323,6 +320,7 @@ '=AY5E/D' => '119,398,399', '=AY7DSY/D' => '119,398,399', '=CE9/K2ARB' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', + '=CE9XX' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=CY2ZT/2' => '191', '=DJ4SN/LU/X' => '119,398,399', '=DP0GVN' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', @@ -439,6 +437,7 @@ '=GB2000SET' => '66', '=GB200A' => '66', '=GB200HNT' => '66', + '=GB250RB' => '64,353', '=GB2AGG' => '64,353', '=GB2ANG' => '66', '=GB2AST' => '64,353', @@ -466,6 +465,7 @@ '=GB2GU' => '65', '=GB2HDG' => '66', '=GB2HI' => '64,353', + '=GB2HLB' => '64,353', '=GB2HRH' => '64,353', '=GB2HST' => '64,353', '=GB2HSW' => '64,353', @@ -609,6 +609,7 @@ '=GB5JS' => '64,353', '=GB5MOB' => '61', '=GB5OL' => '64,353', + '=GB5ONG' => '66', '=GB5RO' => '64,353', '=GB5SI' => '64,353', '=GB5SIP' => '66', @@ -680,10 +681,12 @@ '=GM8LNH' => '353', '=GM8MMA' => '353', '=GM8YEC' => '353', + '=HC0/FT5YJ' => '208', '=HF0APAS' => '208', '=HF0POL' => '208', '=HK0TU' => '76', '=HL8KSJ' => '208', + '=II0SB' => '85', '=IQ0AG' => '85', '=IQ0AH' => '85', '=IQ0AI' => '85', @@ -694,8 +697,10 @@ '=IQ0HO' => '85', '=IQ0QP' => '85', '=IQ0SS' => '85', + '=JA1XGI/VK9' => '194', '=JD1BME' => '93', '=JD1BMM' => '93', + '=JD1BND' => '93', '=JD1YAA' => '93', '=JD1YBJ' => '93', '=JW2FL' => '366', @@ -759,6 +764,7 @@ '=K4XG' => '220', '=K4XU' => '220', '=K4ZGB' => '220', + '=K5D' => '116', '=K5EK' => '220', '=K5KG' => '220', '=K5MA' => '220', @@ -833,6 +839,7 @@ '=KF7NN' => '220', '=KG4CUY' => '220', '=KG4NOZ' => '220', + '=KG4W' => '220', '=KG6ASO' => '102', '=KG6DX' => '102', '=KG6SL' => '111', @@ -879,6 +886,7 @@ '=LO7E/D' => '119,398,399', '=LU/DH4PB/R' => '119,398,399', '=LU/DH4PB/S' => '119,398,399', + '=LU/FT5YJ' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=LU1AEE/D' => '119,398,399', '=LU1AF/D' => '119,398,399', '=LU1CDP/D' => '119,398,399', @@ -891,6 +899,7 @@ '=LU1DZ/R' => '119,398,399', '=LU1DZ/S' => '119,398,399', '=LU1DZ/X' => '119,398,399', + '=LU1EEZ/D' => '119,398,399', '=LU1EJ/W' => '119,398,399', '=LU1EQ/D' => '119,398,399', '=LU1EUU/W' => '119,398,399', @@ -898,6 +907,9 @@ '=LU1OFN/I' => '119,398,399', '=LU1VOF/D' => '119,398,399', '=LU1VZ/V' => '119,398,399', + '=LU1WCR/W' => '119,398,399', + '=LU1WF/W' => '119,398,399', + '=LU1WP/W' => '119,398,399', '=LU1XAW/X' => '119,398,399', '=LU1XWC/E' => '119,398,399', '=LU1XY/X' => '119,398,399', @@ -905,6 +917,7 @@ '=LU1YY/Y' => '119,398,399', '=LU1ZA' => '206', '=LU1ZC' => '208', + '=LU2AGQ/D' => '119,398,399', '=LU2CRM/XA' => '119,398,399', '=LU2DT/D' => '119,398,399', '=LU2DT/LH' => '119,398,399', @@ -913,8 +926,10 @@ '=LU2EE/E' => '119,398,399', '=LU2EJB/X' => '119,398,399', '=LU2VC/D' => '119,398,399', + '=LU2VCD/V' => '119,398,399', '=LU2VDV/D' => '119,398,399', '=LU2WV/O' => '119,398,399', + '=LU2XBI/XA' => '119,398,399', '=LU2XX/X' => '119,398,399', '=LU3CQ/D' => '119,398,399', '=LU3DC/D' => '119,398,399', @@ -924,6 +939,7 @@ '=LU3DR/D' => '119,398,399', '=LU3DR/V' => '119,398,399', '=LU3DXG/D' => '119,398,399', + '=LU3DXG/W' => '119,398,399', '=LU3DZO/D' => '119,398,399', '=LU3EOU/D' => '119,398,399', '=LU3ES/D' => '119,398,399', @@ -950,6 +966,7 @@ '=LU4WG/W' => '119,398,399', '=LU4ZS' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=LU5BE/D' => '119,398,399', + '=LU5BE/XA' => '119,398,399', '=LU5BOJ/O' => '119,398,399', '=LU5DEM/D' => '119,398,399', '=LU5DEM/V' => '119,398,399', @@ -971,11 +988,14 @@ '=LU5XC/X' => '119,398,399', '=LU6DBL/D' => '119,398,399', '=LU6DBL/W' => '119,398,399', + '=LU6DDC/D' => '119,398,399', + '=LU6DG/D' => '119,398,399', '=LU6DKT/D' => '119,398,399', '=LU6DRD/D' => '119,398,399', '=LU6DRD/E' => '119,398,399', '=LU6DRN/D' => '119,398,399', '=LU6DRR/D' => '119,398,399', + '=LU6DTB/D' => '119,398,399', '=LU6EC/W' => '119,398,399', '=LU6EJJ/D' => '119,398,399', '=LU6EPE/D' => '119,398,399', @@ -991,6 +1011,7 @@ '=LU6UO/R' => '119,398,399', '=LU6UO/S' => '119,398,399', '=LU6UO/X' => '119,398,399', + '=LU6WG/W' => '119,398,399', '=LU6XAH/X' => '119,398,399', '=LU7AC/D' => '119,398,399', '=LU7BTO/D' => '119,398,399', @@ -1039,6 +1060,7 @@ '=LU8EHQ/D' => '119,398,399', '=LU8EHQ/E' => '119,398,399', '=LU8EHQ/W' => '119,398,399', + '=LU8EHV/D' => '119,398,399', '=LU8EKB/W' => '119,398,399', '=LU8EKC/D' => '119,398,399', '=LU8EOT/X' => '119,398,399', @@ -1055,7 +1077,9 @@ '=LU9ARB/D' => '119,398,399', '=LU9AUC/D' => '119,398,399', '=LU9DBK/X' => '119,398,399', + '=LU9DF/D' => '119,398,399', '=LU9DKX/X' => '119,398,399', + '=LU9DO/D' => '119,398,399', '=LU9DPD/XA' => '119,398,399', '=LU9EI/F' => '119,398,399', '=LU9EJS/E' => '119,398,399', @@ -1064,9 +1088,11 @@ '=LU9ESD/V' => '119,398,399', '=LU9ESD/W' => '119,398,399', '=LU9ESD/Y' => '119,398,399', + '=LU9EV/D' => '119,398,399', '=LU9EV/LH' => '119,398,399', '=LU9JMG/J' => '119,398,399', '=LW1DAL/D' => '119,398,399', + '=LW1DE/D' => '119,398,399', '=LW1EXU/D' => '119,398,399', '=LW1EXU/Y' => '119,398,399', '=LW2DX/E' => '119,398,399', @@ -1098,6 +1124,7 @@ '=LW7DAF/W' => '119,398,399', '=LW7DLY/D' => '119,398,399', '=LW7DNS/E' => '119,398,399', + '=LW7EDH/D' => '119,398,399', '=LW7EJV/D' => '119,398,399', '=LW7WFM/W' => '119,398,399', '=LW8DMK/D' => '119,398,399', @@ -1224,8 +1251,18 @@ '=NW8U' => '220', '=NX9T' => '220', '=NY4N' => '220', + '=OA0/FT5YJ' => '208', + '=OE3AGA/AAW' => '124', + '=OE3AIS/AAW' => '124', + '=OE3HM/AAW' => '124', + '=OE3KKA/AAW' => '124', + '=OE3RPB/AAW' => '124', + '=OE3SGA/AAW' => '124', + '=OE3WWB/AAW' => '124', '=OP0LE' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=OP0OL' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', + '=OR3AX' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', + '=OR4AX' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=R1ANF' => '208', '=R1ANR' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=R35NP' => '176,427,432', @@ -1300,6 +1337,12 @@ '=TX5CW' => '45,330', '=TX7LX' => '44', '=TX9' => '330', + '=UR2XO/WAP' => '177', + '=UR5KCC/WAP' => '177', + '=UR5KGG/WAP' => '177', + '=UR8LV/WAP' => '177', + '=UT1KY/WAP' => '177', + '=UT7UA/WAP' => '177', '=VA2BY' => '191', '=VA2CT' => '191', '=VA2DO' => '191', @@ -1315,7 +1358,6 @@ '=VB2V' => '191', '=VC2C' => '191', '=VE2/K3FMQ' => '191', - '=VE2ACP' => '191', '=VE2AE' => '191', '=VE2AG' => '191', '=VE2AOF' => '191', @@ -1369,12 +1411,13 @@ '=VE8AJ' => '191', '=VE8PW' => '191', '=VE8RCS' => '191', - '=VER20081209' => '191', - '=VERSION' => '111', + '=VER20090219' => '191', + '=VERSION' => '9', '=VK0HI' => '199', '=VK0IR' => '199', '=VK9AA' => '195', '=VK9DWX' => '198', + '=VK9GMW' => '196', '=VP6DX' => '331', '=VP8/LZ1UQ' => '208', '=VP8DIF' => '205', @@ -1382,6 +1425,7 @@ '=VP8DJK' => '208', '=VP8DKF' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=VP8DLJ' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', + '=VP8DLM' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=VP8PJ' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=VP8ROT' => '99,370,371,372,373,374,375,376,377,378,379,380,381,382,383,384,385,386', '=VP8SGK' => '205', diff --git a/perl/Version.pm b/perl/Version.pm index 7dd45ac2..944658fa 100644 --- a/perl/Version.pm +++ b/perl/Version.pm @@ -11,6 +11,6 @@ use vars qw($version $subversion $build); $version = '1.55'; $subversion = '0'; -$build = '36'; +$build = '37'; 1;