#!/usr/bin/perl
# Given pylons and target areas, make wedge polygons with the wide
# part pointing to the target area. We are simulating cell tower
# antenna maps.
#
# Author: Dan Jacobson https://www.jidanni.org/
# Copyright: https://www.gnu.org/licenses/gpl.htm
# Created: 2024-03-17T21:43:36+0000
# Last-Updated: 2024-03-30T23:03:47+0000
#     Update #: 111
#
use strict;
use warnings q(all);
use Data::Dumper;
my $G = "geod +ellps=WGS84 -f %.6f";

my @pole = reverse qw/24.181664 120.865677/;
for ( 100, 700 ) {
    next;
    my @in = pylon_and_radius2cicle( \@pole, $_ );
    my $csv;
    for (@in) { $csv .= qq{@$_} . $/; }
    my $com = "ogr2ogr -f LIBKML -nlt POLYGON $_.kml $_.csv
        -dialect SQLite -sql \"SELECT MakeLine(MakePoint(CAST(field_1 AS float),
        CAST(field_2 AS float))) FROM '$_'\"";
    $com =~ tr/\n/ /;
    $com =~ s/\s+/ /g;
    open( my $fh, ">", "$_.csv" )
      or die;
    print $fh $csv;
    close $fh;
    for ("$_.kml") { unlink if -f }
    my $res = qx/$com/;
}

#exit;
my %targets;    #    # centers of areas with poor reception. I.e., where
                # the people sitting around the pizza pie are
                # located.

#  ( N => [qw/120.870499 24.195144/], S => [qw/120.866551 24.182822/] );
#  (
#    N => [ reverse qw/24.182686 120.867726/ ],
#    S => [ reverse qw/24.180960 120.864931/ ]
#  );
my %azimuths;
$azimuths{N} = 180 + ( $azimuths{S} = 240 );
%targets = %azimuths;                          #Hack supreme
my %pylons;
## %pylons=  ( 158 => [qw/120.8710656 24.1873743/], 159 => [qw/120.8724266 24.1822381/] );
for (qw/N S/) {

    #    $pylons{$_} = [ reverse split / /, $ENV{$_} ];
    $pylons{$_} = \@pole;
}
for my $p ( sort keys %pylons ) {
    for my $t ( sort keys %targets ) {
        next unless $p eq $t;

        #        print "\n$p -> $t:\n";
        my @in = pylon_and_azimuth2wedge( $pylons{$p},
            $azimuths{$p}
              || pylon_and_target2azimuth( $pylons{$p}, $targets{$t} ) )
          or die;
        my $csv;
        for (@in) { $csv .= qq{@$_} . $/; }
        my $com = "ogr2ogr -f LIBKML -nlt POLYGON $p$t.kml $p$t.csv
        -dialect SQLite -sql \"SELECT MakeLine(MakePoint(CAST(field_1 AS float),
        CAST(field_2 AS float))) FROM '$p$t'\"";
        $com =~ tr/\n/ /;
        $com =~ s/\s+/ /g;
        open( my $fh, ">", "$p$t.csv" )
          or die;
        print $fh $csv;
        close $fh;
        for ("$p$t.kml") { unlink if -f }
        my $res = qx/$com/;
    }
}

sub pylon_and_target2azimuth
{    #given a pylon lonlat, and a target lonlat, get the azimuth
    my @pylon  = @{ $_[0] };
    my @target = @{ $_[1] };
    my $args   = join $", ( reverse @pylon ), ( reverse @target );
    my $res    = qx/echo $args|$G -I -p/ or die;
    my @rez    = split /\s+/, $res;
    return $rez[0];
}

sub pylon_and_azimuth2wedge
{    #given a pylon lonlat, and an azimuth, make a pizza
     #slice polygon representing an antenna
    my @pylon     = @{ $_[0] };
    my $azimuth   = $_[1];
    my $width     = 120;                    #degrees
    my $radius    = $ENV{radius} || die;    #meters
    my $increment = 5;                      #degrees between points on the arc
    my @argl;
    for (
        my $angle = $azimuth - $width / 2 ;
        $angle <= $azimuth + $width / 2 ;
        $angle += $increment
    ) {
        my $args = join $", ( reverse @pylon ), $angle, $radius;
        push @argl, $args;
    }
    {                                       #close the polygon
        my $args = join $", ( reverse @pylon ), (0) x 2;
        push @argl, $args;
        unshift @argl, $args;
    }
    my $argz = join $/, @argl;
    my $res  = qx/echo "$argz"|$G -p/ or die;
    my @nodes;
    for my $line ( split /\n/, $res ) {
        push @nodes, [ ( split /\s+/, $line )[ 1, 0 ] ];
    }
    return @nodes;
}

sub pylon_and_radius2cicle
{    #given a pylon lonlat, and a radius in meters, make a ring.
    my @pylon     = @{ $_[0] };
    my $radius    = $_[1] || die;
    my $increment = 5;              #degrees between points on the arc
    my @argl;
    for ( my $angle = 0 ; $angle <= 360 ; $angle += $increment ) {
        my $args = join $", ( reverse @pylon ), $angle, $radius;
        push @argl, $args;
    }
    my $argz = join $/, @argl;
    my $res  = qx/echo "$argz"|$G -p/ or die;
    my @nodes;
    for my $line ( split /\n/, $res ) {
        push @nodes, [ ( split /\s+/, $line )[ 1, 0 ] ];
    }
    return @nodes;
}
