Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Determining the distance from one zip code to another

by princepawn (Parson)
on Sep 29, 2000 at 21:44 UTC ( [id://34650]=perlquestion: print w/replies, xml ) Need Help??

princepawn has asked for the wisdom of the Perl Monks concerning the following question:

I have always wondered how those (apparently) Perl/CGI programs work that report the distance between two zip codes.

Are there some readily available Perl systems for this?

Replies are listed 'Best First'.
Re: Determining the distance from one zip code to another
by lhoward (Vicar) on Sep 29, 2000 at 22:13 UTC
    You may also want to check out this older perlmonks article: Some of the comments include links to zipcode database and links to the formula for computing the distance between 2 points of latitude/longitude.
Re: Determining the distance from one zip code to another
by jima (Vicar) on Sep 29, 2000 at 22:09 UTC
Re: Determining the distance from one zip code to another
by steveAZ98 (Monk) on Sep 30, 2000 at 00:30 UTC
    Here is a module that I wrote for that purpose. It will have to be modified for your needs, but should give you a good starting point for further development. Someday I will get around to making it an independent module. HTH
    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 "<div align=center>Lat: $lat Long: $lng</div>\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(l +at/$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 "<div align=center>Lat: $lat Long: $lng</div>\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(l +at/$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 cnam +e='$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 <swalker@ssdw.com> August 2000 =cut
Re (tilly) 1: Determining the distance from one zip code to another
by tilly (Archbishop) on Sep 29, 2000 at 22:07 UTC
    I assume that they just buy a zip database, convert zips to longitude and latitude, then plug in the appropriate formula.

    Oh, and the US Postal Service sells software for turning addresses into zips. I highly recommend using that rather than trying to roll your own solution. (Even if it does cost money.)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://34650]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (7)
As of 2024-03-28 11:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found