$Log->{Found} on ".MakeDate($Log->{FoundDate})." by $Log->{FoundBy}:\n";
if ($Log->{FoundLat} != 0) {
print IPODOUT " ".Deg2DMMLat($Log->{FoundLat}).' '.Deg2DMMLong($Log->{FoundLong})."
\n";
}
else {
print IPODOUT "\n";
}
print IPODOUT "$Log->{FoundNote}\n";
}
close IPODOUT;
}
}
sub GetExportedDate
{
my ($FileDate, $RecordDate) = @_;
if (length($RecordDate) > 0) {
return XMLTime2Time($RecordDate);
}
else {
return $FileDate;
}
}
sub MakeLocFile
{
print "Generating file $OutputLocFile\n";
open(OUTPUT, ">$OutputLocFile");
print OUTPUT "\n";
print OUTPUT "\n";
foreach my $ID (keys %Caches) {
my $Cache = $Caches{$ID};
my $Name = $Cache->{Name};
my $Diff;
my $ModID = $ID;
$Name =~ s/[,|\'|\"]//g;
$Name =~ s/[\x80-\xFF]+//ig;
$Name =~ s/\&\#\d+?\;//ig;
$Name =~ s/\&\w+?\;//ig;
foreach my $NewName (keys %CacheNameChanges) {
my $InputName = $CacheNameChanges{$NewName}->{InputName};
my $OutputName = $CacheNameChanges{$NewName}->{OutputName};
$InputName =~ s/(\W)/\\$1/g;
$OutputName =~ s/(\W)/\\$1/g;
$Name =~ s/$InputName/$OutputName/i;
}
$Diff = " ($Cache->{Difficulty}-$Cache->{Terrain})";
$Name = uc($Name).uc($Diff);
my $Lat = $Cache->{Latitude};
my $Lon = $Cache->{Longitude};
my $URL = $Cache->{URL};
my $Symbol = $Cache->{Symbol};
substr($ModID,1,1) = substr($Cache->{DescriptiveString},0,1);
if (substr($Cache->{DescriptiveString},1,1) eq "m") {
substr($ModID,1,1) = lc(substr($ModID,1,1));
}
print OUTPUT "\n";
print OUTPUT " \n";
print OUTPUT " \n";
print OUTPUT " geocache$Symbol\n";
print OUTPUT " $URL\n";
print OUTPUT "\n";
}
print OUTPUT "\n";
close OUTPUT;
}
sub XMLTime2Time
{
my $XMLTime = @_[0];
$XMLTime =~ s/[+-]\d\d:\d\d$//;
$XMLTime =~ s/[a-zA-Z]*$//;
my $RetTime = ParseDate($XMLTime);
return $RetTime;
}
sub MakeDate
{
my $Time = @_[0];
my $Text = UnixDate($Time, "%m\/%d\/%Y");
return $Text;
}
sub GetNearestCaches
{
my ($ID, $NumToStore) = @_;
my $DegToRad = 3.1415926535 / 180.;
my @Dists = ();
my @Nearest = ();
my $Cache = $Caches{$ID};
my $RefLat = $Cache->{Latitude} * $DegToRad;
my $RefLong = $Cache->{Longitude} * $DegToRad;
my ($Lat, $Long, $DeltaLong);
foreach my $CacheID (keys %Caches) {
$Lat = $Caches{$CacheID}->{Latitude} * $DegToRad;
$Long = $Caches{$CacheID}->{Longitude} * $DegToRad;
$DeltaLong = $Long - $RefLong;
my $Distance = 3956.088331 * acos(sin($RefLat) * sin($Lat) + cos($RefLat) * cos($Lat) * cos($DeltaLong));
my $Bearing = atan2(sin($DeltaLong)*cos($Lat), cos($RefLat)*sin($Lat)-sin($RefLat)*cos($Lat)*cos($DeltaLong)) / $DegToRad;
$Bearing += 360. if $Bearing < 0.;
push @Dists, [ $CacheID, $Distance, $Bearing ];
}
@Nearest = sort {$a->[1] <=> $b->[1]} @Dists;
shift @Nearest;
$NearestCaches{$ID} = [ (@Nearest)[0 .. $NumToStore-1] ];
}
sub GetDistances
{
my $Location = @_[0];
my @Dists = ();
my $DegToRad = 3.1415926535 / 180.;
my $RefLat = $ReferenceLocations{$Location}->{Latitude} * $DegToRad;
my $RefLong = $ReferenceLocations{$Location}->{Longitude} * $DegToRad;
my ($Lat, $Long);
foreach my $CacheID (keys %Caches) {
$Lat = $Caches{$CacheID}->{Latitude} * $DegToRad;
$Long = $Caches{$CacheID}->{Longitude} * $DegToRad;
my $DeltaLong = $Long - $RefLong;
my $Distance = 3956.088331 * acos(sin($RefLat) * sin($Lat) + cos($RefLat) * cos($Lat) * cos($DeltaLong));
my $Bearing = atan2(sin($DeltaLong)*cos($Lat), cos($RefLat)*sin($Lat)-sin($RefLat)*cos($Lat)*cos($DeltaLong)) / $DegToRad;
$Bearing += 360. if $Bearing < 0.;
push @Dists, [ $CacheID, $Distance, $Bearing ];
}
return @Dists;
}
sub ProcessLogText
{
my $LogText = @_[0];
$LogText =~ s/\[(\/*[i|b|u])\]/<\1>/gi;
$LogText =~ s/\[br\]/ /gi;
return $LogText;
}
sub Deg2DMMLat
{
my $Latitude = @_[0];
my $Ret = sprintf "%s %d %.3f",
(($Latitude > 0.)?'N':'S', int(abs($Latitude)), (abs($Latitude) - int(abs($Latitude)))*60.);
return $Ret;
}
sub Deg2DMMLong
{
my $Longitude = @_[0];
my $Ret = sprintf "%s %d %.3f",
(($Longitude > 0.)?'E':'W', int(abs($Longitude)), (abs($Longitude) - int(abs($Longitude))) * 60.);
return $Ret;
}
sub FixCacheType
{
my $Type = @_[0];
$Type =~ s/[ |-]*Cache//gi;
$Type =~ s/ \(Reverse\)//gi;
return $Type;
}
sub FixCacheName
{
my $Name = @_[0];
if (length $Name == 0) {
$Name = 'Generic Cache';
}
$Name =~ s/\"//g;
$Name =~ s/^\s+//g;
# Next two lines RER 06/18/06
$Name =~ s/^The //g;
$Name =~ s/^A //g;
return $Name;
}
sub EncodeHint
{
my $Hint = Rot13(@_[0]);
$Hint =~ s/(\[.+?\])/Rot13($&)/eg;
$Hint =~ s/<.+?>//g;
return $Hint;
}
sub Rot13
{
my $Text = @_[0];
$Text =~ tr/A-Za-z/N-ZA-Mn-za-m/;
return $Text;
}
sub ProcessDescriptionText
{
my $Text = @_[0];
$Text =~ s/<(p|P)(\s.*?|)>/[[!p!]]/gi;
$Text =~ s/<\/(p|P)(\s.*?|)>/[[!\/p!]]/gi;
$Text =~ s/<(b|B)(r|R)(\s.*?|\/|)>/[[!br!]]/gi;
$Text =~ s/<\/(b|B)(r|R)(\s.*?|)>/[[!\/br!]]/gi;
$Text =~ s/<.*?>//gi;
$Text =~ s/\[\[!//gi;
return $Text;
}
sub ProcessHintText
{
my $Hint = @_[0];
$Hint =~ s/<(\/*[i|b|u])>/\[\1\]/gi;
# $Hint =~ s/ /\[br\]/gi;
$Hint =~ s/<.+?>//g;
$Hint =~ s/\[(\/*[i|b|u])\]/<\1>/gi;
$Hint =~ s/\[br\]/ /gi;
return $Hint;
}
sub GetIgnoreCaches
{
if (-r 'IgnoreCaches.txt') {
open(IGNOREFILE, " GetCoord($Fields[1]),
Longitude => GetCoord($Fields[2])
};
}
}
close CORRECTFILE;
}
}
sub GetReferenceLocations
{
if (-r 'RefLocations.txt') {
open(REFFILE, "= 3) {
$MaxDistance = $Fields[3];
}
if ($#Fields >= 2) {
$ReferenceLocations{$Fields[0]} = {
Latitude => GetCoord($Fields[1]),
Longitude => GetCoord($Fields[2]),
MaxDistance => $MaxDistance
};
}
}
close REFFILE;
}
}
sub SplitInputLine
{
my $Line = @_[0];
my @Fields = ();
chomp($Line);
if ($Line =~ /^\s*\#/) {
return @Fields;
}
else {
$Line =~ s/\s*\#.*//;
}
my @Fields = split(/\s*,\s*/, $Line);
return @Fields;
}
sub GetCoord
{
my $CoordString = @_[0];
my $Result = 0;
if ($CoordString =~ /\s*([N|S|E|W])\D*(\d+)\D*([\d|.]+)/i) {
my $Direction = uc($1);
$Result = $2 + $3 / 60.;
if ($Direction eq 'S' || $Direction eq 'W') {
$Result = -$Result;
}
}
elsif ($CoordString =~ /\s*-{0,1}\d+\.\d+/) {
$Result = $CoordString;
}
return $Result;
}
sub GetCacheNotes
{
if (-r 'Notes.xml') {
my $Parser = new XML::Twig(
twig_handlers=>{'note' => \&GetCacheNote}, input_filter => 'safe');
$Parser->parsefile('Notes.xml');
$Parser->purge;
}
}
sub GetCacheNote
{
my ($t, $note) = @_;
my $CacheNumber = $note->{'att'}->{'id'};
my $ID = GetCacheWaypoint($CacheNumber);
# print "Got note for cache $ID\n";
my $CacheNote = HTML::Entities::encode_entities($note->text);
$CacheNotes{$ID} = $CacheNote;
}
sub GetCacheWaypoint
{
my $Base31 = '0123456789ABCDEFGHJKMNPQRTVWXYZ';
my $ID;
my $CacheNumber = @_[0];
if ($CacheNumber < 65536) {
$ID = sprintf("GC%X", $CacheNumber);
}
else {
my $TmpNumber = ($CacheNumber - 65536) / 31;
my $i;
for ($i = 0; $i < 3; $i++) {
my $IntVal = int(($TmpNumber - int($TmpNumber))*31 + 0.01);
$ID .= substr($Base31, $IntVal, 1);
$TmpNumber /= 31;
}
my $IntVal = int(($TmpNumber - int($TmpNumber))*31 + 0.01) + index($Base31, 'G');
$ID .= substr($Base31, $IntVal, 1);
$ID = 'GC'.reverse $ID;
}
return $ID;
}
sub GetCacheNameChanges
{
if (-r 'CacheNameChanges.txt') {
open(NAMEFILE, " $Fields[0],
OutputName => $Fields[1]
};
}
}
close NAMEFILE;
}
}