
#!/bin/perl
use CGI;
$q = new CGI;
$DEBUG=0;
#undef ( %sections, $template );
print $q->header if $DEBUG;
@cities = $q->param('city');
$bonus = $q->param('bonus');
$class_bonus = $q->param('class_bonus');
$promo_bonus = $q->param('promo_bonus');
$ticket_price = $q->param('ticket_price');
$ticket_price =~ s/[^0-9\.]//m; # Translate illegal to nothing.
$bonus_use_min = $q->param('bonus_use_min');
$class_bonus_use_min = $q->param('class_bonus_use_min');
$promo_bonus_use_min = $q->param('promo_bonus_use_min');
$min = $q->param('min');
$min_type = $q->param('min_type');
if( $min_type eq 'k' )
{
$min_km = $min;
$min_miles = km2miles( $min_km );
}
else
{
$min_miles = $min;
$min_km = miles2km( $min_miles );
}
if( $ticket_price )
{
parseTemplate("template_cost.htm");
}
else
{
parseTemplate("template.htm");
}
#added by Tim on 2/2/00 to make the airport codes uppercase
foreach $x ( 0 .. $#cities )
{
$len = length $cities[$x];
if( $len eq 3 )
{
$cities[$x] = uc $cities[$x];
}
}
#end added by Tim 2/2/00
foreach $x ( 0 .. $#cities ) { CleanCity( \$cities[$x] ); }
foreach $x ( 0 .. $#cities ) { $fullCity[$x] = findCity( $cities[$x], $x ); }
#undef ( $totalMl, $totalKm );
foreach $x ( 0 .. $#fullCity )
{
last unless ( $fullCity[$x] && $fullCity[$x + 1] );
($code1, $airportName1, $city1, $state1, $country1, $Lat1, $Long1) = split(/\t/, $fullCity[$x]);
($code2, $airportName2, $city2, $state2, $country2, $Lat2, $Long2) = split(/\t/, $fullCity[$x + 1]);
my ( @to ) = calDistance ( $Lat1, $Long1, $Lat2, $Long2 );
$rawTotalMl += $to[1];
$rawTotalKm += $to[0];
# Do a check for min distance
# and correct if necessary.
if( $to[1] < $min_miles )
{
$to[0] = $min_km;
$to[1] = $min_miles;
}
$totalMl += $to[1];
$totalKm += $to[0];
do { print "( $Lat1, $Long1, $Lat2, $Long2 ) ";
print "From " . $fullCity[$x] . " to " . $fullCity[$x + 1] . " \n";
print " -- $to[1]" } if $DEBUG;
}
# Different bonus miles
if( $bonus_use_min )
{
$totalBonusMl = sprintf ( "%8g", &round_to_3( $totalMl * $bonus ) );
$totalBonusKm = sprintf ( "%8g", &round_to_3( $totalKm * $bonus ) );
}
else
{
$totalBonusMl = sprintf ( "%8g", &round_to_3( $rawTotalMl * $bonus ) );
$totalBonusKm = sprintf ( "%8g", &round_to_3( $rawTotalKm * $bonus ) );
}
if( $class_bonus_use_min )
{
$totalClassBonusMl = sprintf ( "%8g", &round_to_3( $totalMl * $class_bonus ) );
$totalClassBonusKm = sprintf ( "%8g", &round_to_3( $totalKm * $class_bonus ) );
}
else
{
$totalClassBonusMl = sprintf ( "%8g", &round_to_3( $rawTotalMl * $class_bonus ) );
$totalClassBonusKm = sprintf ( "%8g", &round_to_3( $rawTotalKm * $class_bonus ) );
}
if( $promo_bonus_use_min )
{
$totalPromoBonusMl = sprintf ( "%8g", &round_to_3( $totalMl * $promo_bonus ) );
$totalPromoBonusKm = sprintf ( "%8g", &round_to_3( $totalKm * $promo_bonus ) );
}
else
{
$totalPromoBonusMl = sprintf ( "%8g", &round_to_3( $rawTotalMl * $promo_bonus ) );
$totalPromoBonusKm = sprintf ( "%8g", &round_to_3( $rawTotalKm * $promo_bonus ) );
}
$roundTripBonusMl = $totalBonusMl * 2;
$roundTripBonusKm = $totalBonusKm * 2;
$roundTripClassBonusMl = $totalClassBonusMl * 2;
$roundTripClassBonusKm = $totalClassBonusKm * 2;
$roundTripPromoBonusMl = $totalPromoBonusMl * 2;
$roundTripPromoBonusKm = $totalPromoBonusKm * 2;
# Round Trip distance
$roundTripMl = $totalMl * 2;
$roundTripKm = $totalKm * 2;
# The grand totals.
$totalGtMl = $totalMl + $totalBonusMl + $totalClassBonusMl + $totalPromoBonusMl;
$totalGtKm = $totalKm + $totalBonusKm + $totalClassBonusKm + $totalPromoBonusKm;
$roundTripGtMl = $roundTripMl + $roundTripBonusMl + $roundTripClassBonusMl + $roundTripPromoBonusMl;
$roundTripGtKm = $roundTripKm + $roundTripBonusKm + $roundTripClassBonusKm + $roundTripPromoBonusKm;
# Get the cost per mile/km.
$roundTripCostPerMl = sprintf( "%.2f", $ticket_price / $roundTripGtMl );
$roundTripCostPerKm = sprintf( "%.2f", $ticket_price / $roundTripGtKm );
$totalCostPerMl = sprintf( "%.2f", $ticket_price / $totalGtMl );
$totalCostPerKm = sprintf( "%.2f", $ticket_price / $totalGtKm );
print "
Total Trip: " . $totalMl . " ML" if $DEBUG;
do
{
undef ( $line );
$sections{'results'} =~ s|([\s\S]*?)||;
$rotation = $1;
foreach $x ( 0 .. $#fullCity )
{
my ( $temp ) = $rotation;
last unless ( $fullCity[$x] );
($code, $airportName, $city, $state, $country, $Lat, $Long) = split(/\t/, $fullCity[$x]);
$city_code[$x] = $code;
# This is a bit of a hack to add the 'to' to the end of a link if needed.
if( $fullCity[$x + 1] )
{
$to_text = ' to';
}
else
{
$to_text = '';
}
$airportName = $city . " Airport" unless $airportName;
$loc = ( $state ) ? $state : $country;
$temp =~ s//${$1}/g;
$line .= $temp;
}
$city_code_one = $city_code[0];
$city_code_two = $city_code[1];
$sections{'results'} =~ s//$line/;
$sections{'results'} =~ s//${$1}/g;
printOutput ( "results" );
} unless $DEBUG;
sub CleanCity {
my ($cityref) = shift;
open (STATE, "abriviations.df");
while ()
{
m!^([A-Z]{2})\t([A-Z]*)\t([0-9]*)\t(.+)!;
$cit = $4;
$cit =~ tr/a-z/A-Z/;
$twoChar{$cit} = $1;
# $twoChar{$2} = $1 if $2;
$twoChar{$3} = $1 if $3;
}
close (STATE);
$$cityref =~ tr/A-z/ /c; # Translate illegal to space
$$cityref =~ tr/ //s; # Squash mult spaces
$$cityref =~ s/(^ )|( $)//; # Remove leading and trailing space
my ( @parts ) = split ( / /, $$cityref );
foreach $x ( 1 .. $#parts ) # Don't process the first word, start on second.
{
$ct = $parts[$x];
$ct =~ tr/a-z/A-Z/;
$$cityref =~ s/$parts[$x]/$twoChar{$ct}/i if $twoChar{$ct};
}
}
sub findCity
{
my ($city, $index) = @_;
$found = 0;
return unless $city;
print $city, " -- " if $DEBUG;
@parts = split( / /, $city );
open DAT, "cities.df" or print "Unable to open data file: $!\n";
@cityList = ;
close DAT;
if ($city =~ /^[A-Z]{3}$/)
{
( $airport ) = grep( /^$city/, @cityList );
chomp ( $airport );
noMatch( $city, $index ) unless ($airport);
return $airport;
}
foreach $part (@parts)
{
@cityList = grep(/$part/i, @cityList);
}
toMany( $city, $index, @cityList ) if ($cityList[1]);
noMatch( $city, $index ) unless (@cityList);
chomp ($cityList[0]);
return $cityList[0];
}
sub toMany
{
local ($city, $index, @list) = @_;
($city, @rest) = split(/\t/, $city);
undef ( $formentries );
foreach $x ( 0 .. $#cities )
{
if ( $x eq $index )
{
$formentries .= " \n";
}
else { $formentries .= " "; }
}
$formentries .= " ";
$sections{'tomany'} =~ s//${$1}/g;
printOutput ( "tomany" );
}
sub noMatch
{
local ( $city, $index ) = @_;
undef ( $formentries );
foreach $x ( 0 .. $#cities )
{
if ( $x eq $index )
{ $formentries .= " \n"; }
else
{ $formentries .= " \n"; }
}
$formentries .= " ";
$sections{'nomatch'} =~ s//${$1}/g;
printOutput ( "nomatch" );
}
sub blankField
{
my ($item, $place, $missing) = @_;
my $x = ($item eq 1) ? 2 : 1;
($code, @rest) = split(/\t/, $place);
$code =~ s/ /+/g;
exit(0);
}
sub calDistance
{
local ( $lat1, $long1, $lat2, $long2 ) = @_;
do
{
print "CD COORD $lat1, $long1, $lat2, $long2 \n";
} if $DEBUG;
my $meters_per_mile = 1609.344;
my $dist = &great_circle_distance ( degrees_to_radians( $lat1, $long1, $lat2, $long2 ) );
# my $km = sprintf ( "%8g", &round_to_3( $dist / 1000 ) );
# ALTERED BY TIM 072604 (WE WERE COMPUTING FOR NAUTICAL MILES, BUT THEN CONVERTING TO KM USING STANDARD RATIO, NOT NAUTICAL)
#my $km = sprintf ( "%8g", &round_to_3( ($dist / 1000) * 1.15 ) );
my $ml = sprintf ( "%8g", &round_to_3( $dist / $meters_per_mile ) );
my $km = sprintf ( "%8g", &round_to_3( $ml * 1.60935 ) );
#my $km2 = ($dist / 1000) * 1.15;
#my $ml2 = $dist / $meters_per_mile;
#print( "Conetent-type: text/html\n\n" );
#print( "mile:$ml2 km:$km2 \n" );
do
{
print "COOR $lat1, $long1, $lat2, $long2";
print "From calDistance() ";
print "Dist: $dist \n";
print "KM: $km \n";
print "ML $ml \n";
} if $DEBUG;
return ( $km, $ml );
}
sub great_circle_distance
{
my ( $lat1, $long1, $lat2, $long2 ) = @_;
# approx radius of Earth in meters. True radius varies from
# 6357km (polar) to 6378km (equatorial).
my $earth_radius = 6367135;
my $dlon = $long2 - $long1;
my $dlat = $lat2 - $lat1;
my $a = ( sin($dlat / 2) ) ** 2
+ cos($lat1) * cos($lat2) * ( sin($dlon / 2) ) ** 2;
my $d = 2 * atan2(sqrt($a), sqrt(1 - $a));
return $earth_radius * $d;
}
sub round_to_3
{
my ( $num ) = @_;
my ( $lg, $round );
if ( $num == 0 ) { return 0; }
$lg = int( log( abs($num ) ) / log( 10.0 ) ); # log base 10 of num
$round = 10 ** ($lg - 2);
return int( $num / $round + 0.5 ) * $round;
}
BEGIN { $::pi = 4 * atan2(1,1); }
sub degrees_to_radians
{
my ( @dec ) = @_;
undef ( $x );
foreach $x ( 0 .. $#dec )
{
print "Dec $x: $dec[$x] " if $DEBUG;
$dec[$x] = $dec[$x] * $::pi / 180.0;
print "Dec $x: $dec[$x] " if $DEBUG;
}
return @dec;
}
sub parseTemplate
{
my ( $file ) = @_;
open (TMP, $file) || print "Unable to open teplate file $file - $!";
while ()
{
if ( // )
{
$sec = $1;
while ( $sections{$sec} !~ // )
{ ( $sections{$sec} ) .= ; }
$template .= "";
}
else { $template .= $_; }
}
close (TMP);
}
sub printOutput
{
my ( $sec ) = @_;
$template =~ s//$sections{$sec}/;
print $q->header;
print $template;
exit (0);
}
sub km2miles
{
local ( $km ) = @_;
my $meters_per_mile = 1609.344;
my $dist = $km * 1000;
my $miles = sprintf ( "%8g", &round_to_3( $dist / $meters_per_mile ) );
return ( $miles );
}
sub miles2km
{
local ( $miles ) = @_;
my $meters_per_mile = 1609.344;
my $dist = $miles * $meters_per_mile;
my $km = sprintf ( "%8g", &round_to_3( $dist / 1000 ) );
return ( $km );
}
^top
|