#!/usr/bin/perl
## Author: Doug Phillips WE6Z
#  Tested with: Perl v5.10.0 built for i386-linux-thread-multi
#  This program is built to convert an ADIF fromatted logbook file
#    into a KML file for viewing in Google Earth.

#    Copyright (C) 2009  Doug Phillips WE6Z
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.

    
use warnings;

print "ADIF to KML by Doug Phillips WE6Z \n\n"; # Print a short message

$call='';$mode='';$date='';$time='';$dxcc='';$state='';  #set initial values of variables to null

# print "$#ARGV\n"; # for debugging.
#  Check to see how many items were passed in from the command line
if ($#ARGV >= 0)
{

# Hash table holding state abbreviations and GPS locations.
# State, longitude, latitude, altitude
%statelocation = ('AK','-154.49306200,63.58875300,0',
'AL','-86.90229800,32.31823100,0',
'AR','-91.83183300,35.20105000,0',
'AZ','-111.09373100,34.04892800,0',
'CA','-121.47582000,38.57092800,0',
'CO','-105.78206700,39.55005100,0',
'CT','-73.08774900,41.60322100,0',
'DE','-75.52767000,38.91083200,0',
'FL','-81.51575400,27.66482700,0',
'GA','-82.90712300,32.15743500,0',
'HI','-155.66585700,19.89868200,0',
'IA','-93.09770200,41.87800200,0',
'ID','-114.74204100,44.06820200,0',
'IL','-89.39852800,40.63312500,0',
'IN','-86.20594400,39.72383000,0',
'KS','-98.48424600,39.01190200,0',
'KY','-85.11545900,37.47582900,0',
'LA','-92.14502400,31.24482300,0',
'MA','-71.38243700,42.40721100,0',
'MD','-76.64127100,39.04575500,0',
'ME','-69.44546900,45.25378300,0',
'MI','-84.84324200,43.43497300,0',
'MN','-94.68590000,46.72955300,0',
'MO','-92.77251500,38.58558000,0',
'MS','-89.70405900,32.72097800,0',
'MT','-110.36256600,46.87968200,0',
'NC','-79.01930000,35.75957300,0',
'ND','-101.00201200,47.55149300,0',
'NE','-99.90181300,41.49253700,0',
'NH','-71.63058200,43.51379000,0',
'NJ','-74.40566100,40.05832400,0',
'NM','-106.61958400,35.08740200,0',
'NV','-116.70330600,39.57887100,0',
'NY','-73.97790000,40.74996300,0',
'OH','-82.90712300,40.41728700,0',
'OK','-97.45916200,35.48924400,0',
'OR','-120.55420100,43.80413300,0',
'PA','-77.82386100,40.86293000,0',
'RI','-71.56124100,41.66802500,0',
'SC','-80.85599000,33.89280300,0',
'SD','-100.33284200,44.39499300,0',
'TN','-86.54411700,35.79122100,0',
'TX','-99.11859200,31.79012700,0',
'UT','-111.09373100,39.32098000,0',
'VA','-78.65689400,37.43157300,0',
'VT','-72.74287600,43.85237500,0',
'WA','-120.37484700,47.52910400,0',
'WI','-90.12852200,44.67311100,0',
'WV','-80.93050900,38.52765800,0',
'WY','-107.29028400,43.07596800,0',
'AB','-114.536194,54.765886,0',
'SK','-106.450864,52.939916,0',
'BC','-127.647621,53.726668,0',
'NT','-135.000000,64.282327,0',
'NWT','-135.000000,64.282327,0',
'MB','-98.813876, 53.760861,0',
'ON','-85.323214,51.253775,0',
'QC','-72.012564,53.711185,0',
'NL','-62.416216,53.710759,0',
'PE','-62.915849,46.219058,0',
'NS','-62.657188,44.692261,0',
'',''); # null entry

#  Hash table for DXCC entities and their GPS location
#  includes some deleted DXCC entities
#  Dxcc entity, longitude, latitude, altitude
%dxcclist = (
'246','13,42,0',
'178','-179,-24,0',
'247','112,9,0',
'260','8,44,0',
'4','57,-10,0',
'165','58,-20,0',
'207','63,-20,0',
'49','9,4,0',
'195','6,-1,0',
'489','175,-22,0',
'176','178,-18,0',
'460','177,-13,0',
'468','31,-26,0',
'474','10,37,0',
'293','107,11,0',
'107','-14,10,0',
'24','3,-54,0',
'199','-91,-69,0',
'18','50,40,0',
'75','45,42,0',
'514','19,42,0',
'315','80,7,0',
'117','6,46,0',
'289','-74,41,0',
'511','126,-9,0',
'154','44,15,0',
'336','35,32,0',
'436','13,33,0',
'215','33,35,0',
'470','39,-7,0',
'450','3,6,0',
'438','48,-19,0',
'444','-16,18,0',
'187','-2,14,0',
'483','1,6,0',
'190','-172,-14,0',
'286','33,0,0',
'430','37,-2,0',
'456','-18,15,0',
'82','-77,18,0',
'492','45,13,0',
'243','45,13,0',
'432','27,-29,0',
'440','34,-14,0',
'400','3,37,0',
'62','-60,13,0',
'159','73,4,0',
'129','-58,6,0',
'226','46,29,0',
'68','48,29,0',
'497','16,46,0',
'424','0,5,0',
'257','15,36,0',
'482','28,-15,0',
'348','48,29,0',
'458','-13,9,0',
'299','102,3,0',
'46','110,2,0',
'369','85,28,0',
'414','15,-4,0',
'210','7,49,0',
'404','29,-3,0',
'208','30,-3,0',
'381','104,1,0',
'454','30,-2,0',
'90','-62,11,0',
'2','43,14,0',
'402','26,-25,0',
'160','-175,-21,0',
'370','59,24,0',
'306','90,28,0',
'391','54,24,0',
'376','52,25,0',
'304','51,26,0',
'231','89,27,0',
'268','92,30,0',
'372','73,34,0',
'506','118,15,0',
'386','122,25,0',
'505','116,21,0',
'318','116,40,0',
'157','167,-1,0',
'203','2,43,0',
'422','-17,13,0',
'60','-77,25,0',
'181','33,-26,0',
'164','127,46,0',
'112','-71,-33,0',
'217','-80,-26,0',
'47','-109,-27,0',
'125','-79,-34,0',
'13','0,-90,0',
'446','-7,34,0',
'264','-8,36,0',
'70','-82,23,0',
'104','-68,-17,0',
'42','71,21,0',
'101','74,16,0',
'200','126,-9,0',
'272','-8,39,0',
'256','-17,33,0',
'149','-26,38,0',
'144','-56,-35,0',
'211','-60,44,0',
'252','-60,47,0',
'401','13,-9,0',
'409','-23,15,0',
'411','43,-12,0',
'230','13,53,0',
'81','7,52,0',
'375','121,15,0',
'51','39,15,0',
'510','34,32,0',
'191','-161,-10,0',
'234','-158,-22,0',
'501','18,44,0',
'281','-4,40,0',
'21','3,38,0',
'29','-15,28,0',
'32','-5,36,0',
'113','-10,29,0',
'245','-6,53,0',
'14','45,40,0',
'434','-11,6,0',
'330','51,36,0',
'179','29,47,0',
'52','25,59,0',
'53','39,9,0',
'27','28,54,0',
'135','75,43,0',
'262','69,39,0',
'280','58,38,0',
'227','2,49,0',
'59','-18,15,0',
'79','-62,16,0',
'169','45,-13,0',
'39','43,-12,0',
'58','107,11,0',
'516','-63,18,0',
'512','158,-20,0',
'162','167,-22,0',
'84','-61,15,0',
'67','80,12,0',
'175','-150,-18,0',
'508','-149,-23,0',
'36','-109,10,0',
'509','-140,-9,0',
'277','-56,47,0',
'57','18,5,0',
'453','55,-21,0',
'99','47,-12,0',
'124','43,-17,0',
'276','54,-16,0',
'213','-63,18,0',
'41','52,-46,0',
'131','70,-50,0',
'10','78,-38,0',
'298','-172,-14,0',
'63','-52,5,0',
'223','0,52,0',
'114','-4,54,0',
'265','-6,55,0',
'122','-2,49,0',
'279','-2,57,0',
'106','-3,49,0',
'294','-3,52,0',
'185','160,-9,0',
'507','166,-11,0',
'239','19,48,0',
'287','7,47,0',
'251','10,47,0',
'120','-79,0,0',
'71','-90,-1,0',
'78','-72,19,0',
'72','-70,18,0',
'116','-74,5,0',
'161','-82,4,0',
'216','-82,13,0',
'19','-79,16,0',
'228','-80,14,0',
'137','127,38,0',
'88','-80,9,0',
'80','-87,14,0',
'387','101,14,0',
'295','13,42,0',
'378','47,25,0',
'248','12,42,0',
'271','14,46,0',
'115','46,2,0',
'225','9,39,0',
'382','43,12,0',
'77','-62,12,0',
'109','-16,12,0',
'97','-61,14,0',
'95','-61,15,0',
'98','-61,13,0',
'339','140,36,0',
'177','154,24,0',
'192','142,28,0',
'194','140,30,0',
'363','107,48,0',
'259','16,78,0',
'118','-9,71,0',
'342','36,32,0',
'184','147,-10,0',
'291','-77,39,0',
'105','-75,20,0',
'166','146,15,0',
'20','-176,0,0',
'103','145,13,0',
'123','-170,17,0',
'174','-177,28,0',
'197','-162,6,0',
'134','-162,6,0',
'110','-158,21,0',
'138','-178,29,0',
'9','-171,-14,0',
'515','-171,-11,0',
'297','167,19,0',
'6','-134,58,0',
'182','-75,18,0',
'285','-65,18,0',
'202','-66,18,0',
'43','-68,18,0',
'193','128,26,0',
'261','-84,17,0',
'28','-80,9,0',
'266','11,60,0',
'100','-58,-35,0',
'254','6,50,0',
'146','25,55,0',
'212','23,43,0',
'136','-78,-12,0',
'354','36,34,0',
'206','16,48,0',
'224','25,60,0',
'5','20,60,0',
'167','19,60,0',
'503','15,50,0',
'218','15,50,0',
'504','17,48,0',
'209','4,51,0',
'237','-52,64,0',
'222','-7,62,0',
'221','13,56,0',
'163','147,-10,0',
'198','147,-10,0',
'267','147,-10,0',
'91','-70,13,0',
'344','126,39,0',
'263','5,52,0',
'85','-69,12,0',
'255','-63,18,0',
'119','107,-6,0',
'258','100,-1,0',
'183','115,-3,0',
'30','119,-5,0',
'108','-48,-16,0',
'56','-32,-4,0',
'253','-29,1,0',
'273','-29,-21,0',
'140','-55,6,0',
'61','48,81,0',
'151','29,61,0',
'302','-13,27,0',
'305','90,24,0',
'499','15,46,0',
'379','55,-5,0',
'219','7,0,0',
'284','18,59,0',
'269','21,52,0',
'466','33,16,0',
'244','32,5,0',
'478','31,31,0',
'236','24,38,0',
'180','24,40,0',
'45','28,36,0',
'40','24,36,0',
'282','179,-9,0',
'301','173,-1,0',
'31','-171,-4,0',
'48','-158,2,0',
'490','170,-1,0',
'232','46,2,0',
'3','69,35,0',
'278','12,44,0',
'22','134,7,0',
'390','33,40,0',
'242','-22,64,0',
'76','-92,16,0',
'308','-84,10,0',
'37','-87,6,0',
'406','12,4,0',
'214','9,42,0',
'408','19,5,0',
'412','15,-4,0',
'420','10,1,0',
'410','15,12,0',
'428','-5,7,0',
'416','3,6,0',
'442','-8,13,0',
'54','37,56,0',
'126','21,55,0',
'15','104,52,0',
'292','69,41,0',
'130','77,43,0',
'128','32,64,0',
'288','30,50,0',
'94','-62,17,0',
'66','-89,17,0',
'249','-63,17,0',
'464','17,-22,0',
'173','158,7,0',
'168','171,7,0',
'345','115,5,0',
'1','-76,45,0',
'150','149,-35,0',
'111','73,-53,0',
'153','159,-54,0',
'38','97,-12,0',
'147','159,-31,0',
'171','156,-17,0',
'189','168,-29,0',
'303','150,-16,0',
'35','106,-10,0',
'186','-53,48,0',
'12','-63,18,0',
'96','-62,17,0',
'65','-65,18,0',
'89','-71,22,0',
'172','-128,-25,0',
'513','-125,-25,0',
'141','-58,-52,0',
'235','-37,-54,0',
'238','-45,-61,0',
'240','-27,-59,0',
'241','-58,-62,0',
'64','-65,32,0',
'307','39,-7,0',
'26','46,2,0',
'33','72,-7,0',
'8','46,-9,0',
'44','55,-6,0',
'55','51,-10,0',
'321','114,22,0',
'155','102,3,0',
'220','110,2,0',
'139','56,18,0',
'127','43,15,0',
'324','77,29,0',
'11','93,12,0',
'142','73,11,0',
'50','-99,20,0',
'204','-113,18,0',
'480','-2,12,0',
'312','105,12,0',
'143','102,20,0',
'152','114,22,0',
'309','96,17,0',
'81','13,53,0',
'327','107,-6,0',
'333','45,32,0',
'158','168,-18,0',
'384','36,34,0',
'145','24,57,0',
'86','-87,12,0',
'275','26,45,0',
'74','-89,14,0',
'296','21,45,0',
'148','-67,10,0',
'17','-64,16,0',
'452','31,-18,0',
'502','22,42,0',
'7','20,41,0',
'233','-5,37,0',
'283','33,35,0',
'25','116,6,0',
'196','35,32,0',
'102','0,5,0',
'250','-6,-16,0',
'205','-14,-8,0',
'274','-12,-37,0',
'69','-81,19,0',
'188','-170,-19,0',
'270','-171,-9,0',
'170','175,-41,0',
'34','-177,-44,0',
'133','-178,-29,0',
'16','166,-51,0',
'132','-57,-26,0',
'462','28,-26,0',
'493','15,-27,0',
'201','38,-47,0',
'488','15,-23,0',
'2','72,-7,0',
'3','46,-12,0',
'0','0,0,0',
'','' # null entry
);

# Specify the name of the output file.  Just add '.kml' to the end of the file name
# Take the name of the file off the command line
$output ="$ARGV[0].kml";

open (FILE, ">$output") or die "$! error trying to overwrite";
print FILE '<?xml version="1.0" encoding="UTF-8"?>'."\n";
print FILE '<kml xmlns="http://www.opengis.net/kml/2.2">'."\n";
print FILE '<Folder>'."\n"."<name>$ARGV[0]</name>"."\n";

$file = $ARGV[0];
open(INFO, $file) or die "$! \nFile $ARGV[0] doesn't exist... ";		# Open the file
@lines = <INFO>;		# Read it into an array
close(INFO);			# Close the file
#print @lines;			# Print the array
#print @lines[0];
$count=0;
foreach $line (@lines)
{
  if($line =~ /<[Cc][Aa][Ll][Ll]:.>([^<]*)/)
  {  
    $call=$1;
    $call=~s/\s+$//;
    #print "$call ";
  }
  if($line =~ /<[Mm][Oo][Dd][Ee]:.>([^<]*)/)
  {
    $mode=$1;
    $mode=~s/\s+$//;
    #print "$mode ";
  }
  if($line =~ /<[Qq][Ss][Oo]_[Dd][Aa][Tt][Ee]:.:.>([^<]*)/)
  {
    $date=$1;
    $date=~s/\s+$//;
    #print "$date ";
  }
  if($line =~ /<[Qq][Ss][Oo]_[Dd][Aa][Tt][Ee]:.>([^<]*)/)
  {
    $date=$1;
    $date=~s/\s+$//;
    #print "$date ";
  }
  if($line =~ /<[Tt][Ii][Mm][Ee]_[Oo][Nn]:.>([^<]*)/)
  {
    $time = $1;
    $time =~s/\s+$//;
    #print "$time ";
  }
  if($line =~ /<[Dd][Xx][Cc][Cc]:.>([^<]*)/)
  {
    $dxcc = $1;
    $dxcc =~s/\s+$//;
    #print "$dxcc ";
  }
  if($line =~ /<[Ss][Tt][Aa][Tt][Ee]:.>([^<]*)/)
  {
    $state = $1;
    $state =~s/\s+$//;
    #print "$state ";
  }
  if($line =~ /<[Bb][Aa][Nn][Dd]:.>([^<]*)/)
  {
    $band = $1;
    $band =~s/\s+$//;
    #print "$band ";
  }
  if($line =~ /<[Ee][Oo][Rr]>/)
  { 
    $count++;
    #print information to standard out for debugging   
    print "Record $count--> ";
    print "$call ";
    print "$band ";
    print "$mode ";
    print "$date ";
    print "$time ";
    print "$dxcc ";
    print "$state ";
    print "\n";

    print FILE '<Placemark>'."\n";
    print FILE "<name>$call</name>\n";
    print FILE "<description>Band: $band\nMode: $mode\nDate: $date\nTime: $time\nDXCC: $dxcc\nState: $state\n</description>\n";
    print FILE "<Point>\n<coordinates>";
    if($statelocation{uc($state)} ne '') #if state is specified lookup coordinates in hash table
    {
      print FILE "$statelocation{uc($state)}";
    }
    elsif($dxcclist{$dxcc} ne '')  #if DXCC is specified lookup coordinates in hash table
    {   
      print FILE "$dxcclist{$dxcc}";
    }    
    else   #else just make the coordinates 0,0,0
    {
      print FILE "0,0,0";  #  default location when one can't be determined.
    }
    print FILE "</coordinates>\n</Point>\n";
    print FILE "</Placemark>\n\n";
   
    $call='';$mode='';$date='';$time='';$dxcc='';$state='';  #reset the variables
  }  #end of if EOR  
  if($line =~ /<[Ee][Oo][Hh]>/) #  End of header detected
  {
    $call='';$mode='';$date='';$time='';$dxcc='';$state='';  #reset the variables
  }
}#end of loop

#make a dot for the home location.

    print FILE '<Placemark>'."\n";
    print FILE "<visibility>1</visibility>  
    <Style>
    <IconStyle>
      <Icon>       
       <href>root://icons/palette-4.png</href>
        <x>32</x>
        <y>32</y>
        <w>32</w>
        <h>32</h>
      </Icon>
    </IconStyle>  
    </Style>";
    print FILE "<name>QTH</name>\n";
    print FILE "<description>QTH</description>\n";
    print FILE "<Point>\n<coordinates>";
    print FILE "-121.193870, 38.765357,0";  #enter your coordinates here
    print FILE "</coordinates>\n</Point>\n";
    print FILE "</Placemark>\n\n";


print FILE '</Folder>'."\n".'</kml>'."\n";  #close the kml tags
close FILE;  #close the file

print "Saved as $output\n";  #  Print the name of the file it was saved as

}

#  Else don't do anything and print a usage error message.
else
{
  print "Usage: name of ADIF file must be specified on the command line\nEx: adiftokml.pl logfile.adi\n\n";
}
