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