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