+=head1 SUBROUTINES
+
+=over 4
+
+=item process_generate_coverage JOB, PARAMS
+
+Queueable routine to fetch the sector coverage map from the tower mapping
+server and store it. Highly experimental. Requires L<Map::Splat> to be
+installed.
+
+PARAMS must include 'sectornum'.
+
+=cut
+
+sub process_generate_coverage {
+ my $job = shift;
+ my $param = shift;
+ $job->update_statustext('0,generating map') if $job;
+ my $sectornum = $param->{sectornum};
+ my $sector = FS::tower_sector->by_key($sectornum)
+ or die "sector $sectornum does not exist";
+ my $tower = $sector->tower;
+
+ load_class('Map::Splat');
+ # since this is still experimental, put it somewhere we can find later
+ my $workdir = "$FS::UID::cache_dir/cache.$FS::UID::datasrc/" .
+ "generate_coverage/sector$sectornum-". time;
+ make_path($workdir);
+ my $splat = Map::Splat->new(
+ lon => $tower->longitude,
+ lat => $tower->latitude,
+ height => ($sector->height || $tower->height || 0),
+ freq => $sector->freq_mhz,
+ azimuth => $sector->direction,
+ h_width => $sector->width,
+ tilt => $sector->downtilt,
+ v_width => $sector->v_width,
+ max_loss => $sector->margin,
+ min_loss => $sector->margin - 80,
+ dir => $workdir,
+ );
+ $splat->calculate;
+
+ my $box = $splat->box;
+ foreach (qw(west east south north)) {
+ $sector->set($_, $box->{$_});
+ }
+ $sector->set('image', $splat->mask);
+ # mask returns a PNG where everything below max_loss is solid colored,
+ # and everything above it is transparent. More useful for our purposes.
+ my $error = $sector->replace;
+ die $error if $error;
+}
+