latest version of RBN. Add qra to prefixes.
[spider.git] / perl / create_prefix.pl
1 #!/usr/bin/env perl
2 # a program to create a prefix file from a wpxloc.raw file
3 #
4 # Copyright (c) - Dirk Koopman G1TLH
5 #
6 #
7 #
8
9 use 5.10.1;
10
11 # search local then perl directories
12 BEGIN {
13         # root of directory tree for this system
14         $root = "/spider"; 
15         $root = $ENV{'DXSPIDER_ROOT'} if $ENV{'DXSPIDER_ROOT'};
16
17         mkdir "$root/local_data", 02777 unless -d "$root/local_data";
18
19         unshift @INC, "$root/perl";     # this IS the right way round!
20         unshift @INC, "$root/local";
21 }
22
23 use DXVars;
24 use SysVar;
25
26 use Data::Dumper;
27 use DXUtil;
28 use DXBearing;
29
30 use strict;
31
32 my %loc = ();                                           # the location unique hash
33 my $nextloc = 1;                                        # the next location number
34 my %locn = ();                                          # the inverse of the above
35 my %pre = ();                                           # the prefix hash
36 my %pren = ();                                          # the inverse
37
38 my $prefix;
39 my $system;
40
41 if (@ARGV && $ARGV[0] =~ /^-?-?syst?e?m?$/) {
42         $prefix = $main::data;
43         ++$system;
44         shift;
45         say "create_prefix.pl: creating SYSTEM prefix files";   
46 } else {
47         $prefix = $main::local_data;
48         say "create_prefix.pl: creating LOCAL prefix files";    
49 }
50
51 my $ifn;
52
53 $ifn = $system ? "$main::data/wpxloc.raw" : "$prefix/wpxloc.raw";
54 unless (open (IN, $ifn)) {
55         $ifn = "$main::data/wpxloc.raw";
56         open(IN, $ifn) or die "can't open $ifn ($!)";
57 }
58
59 # first pass, find all the 'master' location records
60 while (<IN>) {
61         next if /^\!/;                          # ignore comment lines
62         chomp;
63         my @f  = split;                         # get each 'word'
64         next if @f == 0;                        # ignore blank lines
65
66         if (($f[14] && $f[14] eq '@') || ($f[15] && $f[15] eq '@')) {
67                 my $locstr = join ' ', @f[1..13];
68                 my $loc = $loc{$locstr};
69                 $loc = addloc($locstr) if !$loc;
70         }
71 }
72
73 #foreach $loc (sort {$a <=> $b;} keys %locn) {
74 #  print "loc: $loc data: $locn{$loc}\n";
75 #}
76
77 # go back to the beginning and this time add prefixes (adding new location entries, if required)
78 seek(IN, 0, 0);
79
80 my $line;
81 while (<IN>) {
82         $line++;
83         chomp;
84         next if /^\s*\!/;                               # ignore comment lines
85         next if /^\s*$/;
86         
87         my @f  = split;                         # get each 'word'
88         next if @f == 0;                        # ignore blank lines
89   
90         # location record
91         my $locstr = join ' ', @f[1..13];
92         my $loc = $loc{$locstr};
93         $loc = addloc($locstr) if !$loc;
94   
95         my @prefixes = split /,/, $f[0];
96         foreach my $p (@prefixes) {
97                 my $ref;
98         
99                 if ($p =~ /#/) {
100                         my $i;
101                         for ($i = 0; $i < 9; ++$i) {
102                                 my $t = $p;
103                                 $t =~ s/#/$i/;
104                                 addpre($t, $loc);
105                         }
106                 } else {
107                         addpre($p, $loc);
108                 }       
109         }
110 }
111
112 close(IN);
113
114 #print Data::Dumper->Dump([\%pre, \%locn], [qw(pre locn)]);
115
116 # now open the cty.dat file if it is there
117 my $r;
118 $ifn = $system ? "$main::data/cty.dat" : "$prefix/cty.dat";
119 unless ($r = open (IN, $ifn)) {
120         $ifn = "$main::data/cty.dat";
121         $r = open(IN, $ifn);
122 }
123
124 my @f;
125 my @a;
126 $line = 0;
127 if ($r) {
128         my $state = 0;
129         while (<IN>) {
130                 $line++;
131                 s/\r$//;
132                 next if /^\s*\#/;
133                 next if /^\s*$/;
134                 chomp;
135                 if ($state == 0) {
136                         s/:$//;
137                         @f = split /:\s+/;
138                         @a = ();
139                         $state = 1;
140                 } elsif ($state == 1) {
141                         s/^\s+//;
142                         if (/;$/) {
143                                 $state = 0;
144                                 s/[,;]$//;
145                                 push @a, split /\s*,/;
146                                 $f[7] =~ s/^\*\s*//;   # remove any preceeding '*' before a callsign
147                                 ct($_, uc $f[7], @a) if @a;
148                         } else {
149                                 s/,$//;
150                                 push @a, split /\s*,/;
151                         }
152                 }
153         }
154 }
155 close IN;
156
157
158 open(OUT, ">$prefix/prefix_data.pl") or die "Can't open $prefix/prefix_data.pl ($!)";
159
160 print OUT "\%pre = (\n";
161 foreach my $k (sort keys %pre) {
162         my $ans = printpre($k);
163         print OUT "  '$k' => '$ans',\n";
164 }
165 print OUT ");\n\n";
166
167 print OUT "\n\%prefix_loc = (\n";
168 foreach my $l (sort {$a <=> $b} keys %locn) {
169         print OUT "   $l => bless( {";
170         my ($name, $dxcc, $itu, $cq, $utcoff, $latd, $latm, $lats, $latl, $longd, $longm, $longs, $longl) = split /\s+/, $locn{$l};
171   
172         $longd += ($longm/60);
173         $longd = 0-$longd if (uc $longl) eq 'W'; 
174         $latd += ($latm/60);
175         $latd = 0-$latd if (uc $latl) eq 'S';
176         my $qra = DXBearing::lltoqra($latd, $longd);
177         print OUT " name => '$name',";
178         print OUT " dxcc => $dxcc,";
179         print OUT " itu => $itu,";
180         print OUT " cq => $cq,";
181         print OUT " utcoff => $utcoff,";
182         print OUT " lat => $latd,";
183         print OUT " long => $longd";
184         print OUT " qra => $qra";
185         print OUT " }, 'Prefix'),\n";
186 }
187 print OUT ");\n\n";
188
189 close(OUT);
190
191 sub addpre
192 {
193         my ($p, $ent) = @_;
194         my $ref = $pre{$p};
195         $ref = $pre{$p} = [] if !$ref;
196         push @{$ref}, $ent;;
197 }
198
199 sub printpre
200 {
201         my $p = shift;
202         my $ref = $pre{$p};
203         my $out;
204         my $r;
205   
206         foreach $r (@{$ref}) {
207                 $out .= "$r,";
208         }
209         chop $out;
210         return $out;
211 }
212
213 sub ct
214 {
215         my $l = shift;
216         my $p = shift; 
217         my @a = @_;
218         my $ref = $pre{$p};
219         if ($ref) {
220                 my $a;
221                 foreach $a (@a) {
222                         # for now remove (nn) [nn]
223                         my ($itu) = $a =~ /(\(\d+\))/; $a =~ s/(\(\d+\))//g;
224                         my ($cq) = $a =~ /(\[\d+\])/; $a =~ s/(\[\d+\])//g;
225                         my ($lat, $long) = $a =~ m{(<[-+\d.]+/[-+\d.]+>)}; $a =~ s{(<[-+\d.]+/[-+\d.]+>)}{}g;
226                         my ($cont) = $a =~ /(\{[A-Z]{2}\})/; $a =~ s/(\{[A-Z]{2}\})//g;
227
228                         unless ($a) {
229                                 print "line $line: blank prefix on $l in cty.dat\n";
230                                 next;
231                         }
232                         next if $a eq $p;       # ignore if we have it already
233                         my $nref = $pre{$a};
234                         $pre{$a} = $ref if !$nref; # copy the original ref if new 
235                 }
236         } else {
237                 print "line $line: unknown prefix '$p' on $l in cty.dat\n";
238         }
239 }
240
241 sub addloc
242 {
243         my $locstr = shift;
244         $locstr =~ s/\'/\\'/g;
245         my $loc = $loc{$locstr} = $nextloc++;
246         $locn{$loc} = $locstr;
247         return $loc;
248 }
249