#!/usr/bin/perl
# Make a KML file of my nearby air routes.
# Copyright       : http://www.fsf.org/copyleft/gpl.html
# Author          : Dan Jacobson -- https://www.jidanni.org/comm/air/m750/programs/
# Created On      : Thu Mar  7 07:14:40 2013
# Last Modified On: Wed Sep 18 19:37:34 2019
# Update Count    : 271
use strict;
use warnings FATAL => 'all';
use XML::LibXML;
eval { require Carp::Always; Carp::Always->import(); };
## http://eaip.caa.gov.tw/eaip/history/2019-08-29/html/eAIP/RC-ENR-3.3-en-TW.html#ID_938306
my $MetersPerFoot = 0.3048;
my @dan           = ( 120.865795, 24.181546 );    # My four corner junction
my ( %route, %seen_names );
while (<>) {
    next if /^#/;
    my @l = split;
    $l[1] =~ s/^/0/;                              #DDDMMSS[.SS]
    my $r = $ARGV;
    $r =~ s!.*/!!;
    $r =~ s/\..*//;
    push @{ $route{$r}{name} }, shift @l;
    my $sign;
    my @cd;
    for (@l) {
        s/.$//;
        if    ( $& eq q!S! || $& eq q!W! ) { $sign = -1 }
        elsif ( $& eq q!N! || $& eq q!E! ) { $sign = 1 }
        else                               { die "$& ugly" }
        my @t = unpack "A3A2A*";
        push @cd, $sign * ( ( shift @t ) + ( shift @t ) / 60 + ( shift @t ) / 60 / 60 );
    }
    push @{ $route{$r}{coord} }, [ reverse @cd ];
}
for ( my $FL = 290 ; $FL <= 410 ; $FL += 20 ) {
    for ( keys %route ) {
        push @{ $route{$_}{FL} }, $FL;
    }
    ## Even though some go lower, and have southbound (even numbered) FLs too.
}
my $doc = XML::LibXML::Document->new( '1.0', "UTF-8" );
my $kml = $doc->createElementNS( "http://www.opengis.net/kml/2.2", "kml" );
$kml->setAttribute( "xmlns:gx", "http://www.google.com/kml/ext/2.2" );
my $comment =
  $doc->createComment("MADE BY $ENV{PWD}/$0, WILL GET OVERWRITTEN.");
$kml->appendChild($comment);
my $Document = $doc->createElement('Document');
$kml->appendChild($Document);
$doc->setDocumentElement($kml);
for ($Document) {
    my $name = $doc->createElement('name');
    $name->appendText("近航線 Nearby air routes");
    $_->appendChild($name);
    my $description = $doc->createElement('description');
    $description->appendText("https://www.jidanni.org/comm/air/m750");
    $_->appendChild($description);
    my $open = $doc->createElement('open');
    $_->appendChild($open);
    $open->appendText(1);
    my $Style = $doc->createElement('Style');
    $Style->setAttribute( 'id', 0 );
    my $LineStyle = $doc->createElement('LineStyle');
    $Style->appendChild($LineStyle);
    my $glv = $doc->createElement('gx:labelVisibility');
    $glv->appendText(1);
    $LineStyle->appendChild($glv);
    $_->appendChild($Style);
}
for ( $doc->createElement('Folder') ) {
    my $name = $doc->createElement('name');
    $_->appendChild($name);
    $name->appendText("景 Views");
    my $open = $doc->createElement('open');
    $_->appendChild($open);
    $open->appendText(1);
    $Document->appendChild($_);
    for my $azimuth ( 30, 230 ) {
        my $Placemark = $doc->createElement('Placemark');
        $_->appendChild($Placemark);
        $name = $doc->createElement('name');
        $name->appendText("$azimuth degrees");
        $Placemark->appendChild($name);
        for ( $doc->createElement('Camera') ) {
            $Placemark->appendChild($_);
            my $longitude = $doc->createElement("longitude");
            $_->appendChild($longitude);
            $longitude->appendText( $dan[0] );
            my $latitude = $doc->createElement('latitude');
            $_->appendChild($latitude);
            $latitude->appendText( $dan[1] );
            my $altitude = $doc->createElement('altitude');
            $_->appendChild($altitude);
            $altitude->appendText(2);
            my $heading = $doc->createElement('heading');
            $_->appendChild($heading);
            $heading->appendText($azimuth);
            my $tilt = $doc->createElement('tilt');
            $_->appendChild($tilt);
            $tilt->appendText(90);
        }
        my $Point = $doc->createElement('Point');
        $Placemark->appendChild($Point);
        my $coordinates = $doc->createElement('coordinates');
        $Point->appendChild($coordinates);
        $coordinates->appendText( join ",", @dan );
    }
}
for my $r ( sort keys %route ) {
    for ( $doc->createElement('Folder') ) {
        my $name = $doc->createElement('name');
        $_->appendChild($name);
        $name->appendText($r);
        $Document->appendChild($_);
        my $Folder = $doc->createElement('Folder');
        $_->appendChild($Folder);
        $name = $doc->createElement('name');
        $name->appendText('線 Lines');
        $Folder->appendChild($name);
        for my $FL ( @{ $route{$r}{FL} } ) {
            my $Placemark = $doc->createElement('Placemark');
            my $name      = $doc->createElement('name');
            $name->appendText("$r:FL$FL");
            $Placemark->appendChild($name);
            my $LineString = $doc->createElement('LineString');
            $Placemark->appendChild($LineString);
            my $styleUrl = $doc->createElement('styleUrl');
            $styleUrl->appendText("#0");
            $Placemark->appendChild($styleUrl);
            my $altitudeMode = $doc->createElement('altitudeMode');
            $altitudeMode->appendText('absolute');
            $LineString->appendChild($altitudeMode);
            my $coordinates = $doc->createElement('coordinates');
            my @c;
            for ( @{ $route{$r}{coord} } ) {
                push @c, sprintf "%.5f,%.5f,%.0f", @$_, $FL * 100 * $MetersPerFoot;
            }
            $coordinates->appendText("@c");
            $LineString->appendChild($coordinates);
            $Folder->appendChild($Placemark);
        }
        $Folder = $doc->createElement('Folder');
        $_->appendChild($Folder);
        $name = $doc->createElement('name');
        $name->appendText('點 Points');
        $Folder->appendChild($name);
        for ( 0 .. $#{ $route{$r}{name} } ) {
            my $Placemark = $doc->createElement('Placemark');
            my $name      = $doc->createElement('name');
            my $n         = @{ $route{$r}{name} }[$_];
            $name->appendText($n);
            $Placemark->appendChild($name);
            if ( exists $seen_names{$n} ) {
                my $visibility = $doc->createElement('visibility');
                $Placemark->appendChild($visibility);
                $visibility->appendText(0);
            }
            $seen_names{$n}++;
            my $Point = $doc->createElement('Point');
            $Placemark->appendChild($Point);
            my $extrude = $doc->createElement('extrude');
            $extrude->appendText(1);
            $Point->appendChild($extrude);
            my $altitudeMode = $doc->createElement('altitudeMode');
            $altitudeMode->appendText('absolute');
            $Point->appendChild($altitudeMode);
            my $coordinates = $doc->createElement('coordinates');
            $Point->appendChild($coordinates);
            $coordinates->appendText(
                sprintf "%.5f,%.5f,%.0f",
                @{ @{ $route{$r}{coord} }[$_] },
                @{ $route{$r}{FL} }[-1] * 100 * $MetersPerFoot
            );
            $Folder->appendChild($Placemark);
        }
    }
}
print $doc->toString(1);

# Local Variables:
# compile-command: "./3d a/M750.dms a/B1.dms a/W4.dms | tee /tmp/k.kml # ../m750_3d.kml"
# End:
