package Zips;
use strict;
use Time::HiRes qw(gettimeofday);
sub get_coords {
my ($s) = shift;
my $dbh = $s->dbh;
my ($zip) = @_;
my $sth = $dbh->prepare(qq! SELECT lat,lng FROM zipcodes WHERE zip='$zip' !);
$sth->execute();
my ($lat,$lng) = $sth->fetchrow();
$sth->finish();
return ($lat,$lng);
}
sub radius_select {
my ($s) = shift;
my $dbh = $s->dbh;
my ($zip,$m) = @_;
my ($lat, $lng) = $s->get_coords($zip);
if (($lat)&&($lng)) {
print "
Lat: $lat Long: $lng
\n";
my $d = $m / 3958.75;
my $div = 57.2958;
my $sth = $dbh->prepare(qq!
SELECT zip,cname,state, ( 3958.75 * ACOS( COS($lat/$div
) * COS(lat/$div)
+ SIN($lat/$div) * SIN(lat/$div)
* COS($lng/$div - lng/$div) ) ) as dist FROM zipcodes
WHERE (ACOS( COS($lat/$div) * COS(lat/$div)
+ SIN($lat/$div) * SIN(lat/$div)
* COS($lng/$div - lng/$div) )) < $d
ORDER BY dist
!) || die "Can't select from zipcodes: ", $dbh->errstr;
#$s->write_log($sth->{Statement});
my $b = gettimeofday;
$sth->execute() || die "Can't execute select on zipcodes: ", $sth->errstr;
$s->e->{'qtime'} = gettimeofday-$b;
my $r_all = $sth->fetchall_arrayref();
$sth->finish();
return $r_all;
} else {
print "Invalid Zip Code.\n";
}
}
sub get_limit_byzip {
my ($s) = shift;
my $dbh = $s->dbh;
my ($zip,$m) = @_;
my $d = 200 / 3958.75;
my ($lat, $lng) = $s->get_coords($zip);
if (($lat)&&($lng)) {
print "Lat: $lat Long: $lng
\n";
my $d = $m / 3958.75;
my $div = 57.2958;
my $sth = $dbh->prepare(qq!
SELECT zip,cname,state, ( 3958.75 * ACOS( COS($lat/$div
) * COS(lat/$div)
+ SIN($lat/$div) * SIN(lat/$div)
* COS($lng/$div - lng/$div) ) ) as dist FROM zipcodes
WHERE (ACOS( COS($lat/$div) * COS(lat/$div)
+ SIN($lat/$div) * SIN(lat/$div)
* COS($lng/$div - lng/$div) )) < $d
Group by dist limit $m
!) || die "Can't select from zipcodes: ", $dbh->errstr;
#$s->write_log($sth->{Statement});
my $b = gettimeofday;
$sth->execute() || die "Can't execute select on zipcodes: ", $sth->errstr;
$s->e->{'qtime'} = gettimeofday-$b;
my $r_all = $sth->fetchall_arrayref();
$sth->finish();
return $r_all;
} else {
print "Invalid Zip Code.\n";
}
}
sub get_dist_byzip {
my ($s) = shift;
my ($zip, $zip2) = @_;
my ($lat, $lng) = $s->get_coords($zip);
my ($lat2,$lng2) = $s->get_coords($zip2);
my $div = 57.2958;
my $dist = (3958.75 * acos( cos($lat/$div) * cos($lat2/$div)
+ sin($lat/$div) * sin($lat2/$div)
* cos($lng/$div - $lng2/$div) ) );
return $dist;
}
sub get_zips_bycity {
my ($s) = shift;
my ($city,$state,$dist) = @_;
my $sth = $s->dbh->prepare(qq! SELECT zip FROM zipcodes WHERE cname='$city' and state=
'$state' !);
$sth->execute();
my $zip = $sth->fetchrow();
$sth->finish();
return $s->radius_select($zip,$dist);
}
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ); }
1;
__END__
=pod
=head1 NAME
Zips.pm
=head1 METHODS AVAILABLE
$s->get_zips($zip, $dist)
$s->get_coords($zip) => ($lat,$lng);
$s->radius_select($zip,$m) => $r_all;
$s->dist_select_byzip($zip, $zip2) => $dist;
$s->acos()
=head1 AUTHOR
Stephen T. Walker
August 2000
=cut