Geo-PostalCode-NoDB

 view release on metacpan or  search on metacpan

lib/Geo/PostalCode/NoDB.pm  view on Meta::CPAN

sub _lon_miles {
    my $self = shift;
    my ($lat) = @_;

    # Formula from:
    #   http://www.malaysiagis.com/related_technologies/mapping/basics1b.cfm
    my $r =
      cos( $lat * PI / 180 ) *
      ( 2 * PI * $self->{_earth_radius} / LON_DEGREES );
    $r;
}

sub _min {
    return $_[0] < $_[1] ? $_[0] : $_[1];
}

1;
__END__

=head1 NAME

Geo::PostalCode::NoBD - Find closest zipcodes, distance, latitude, and longitude; no Berkeley DB.

=head1 SYNOPSIS

  use Geo::PostalCode::NoBD;

  my $gp = Geo::PostalCode::NoBD->new(csvfile => "us_zip_codes.csv");

  my $record = $gp->lookup_postal_code(postal_code => '07302');
  my $lat   = $record->{lat};
  my $lon   = $record->{lon};
  my $city  = $record->{city};
  my $state = $record->{state};

  my $distance = $gp->calculate_distance(postal_codes => ['07302','10004']);

  my $record = $gp->lookup_city_state(city => "Jersey City",state => "NJ");
  my $lat          = $record->{lat};
  my $lon          = $record->{lon};
  my $postal_codes = $record->{postal_codes};

  my $postal_codes = $gp->nearby_postal_codes(lat => $lat, lon => $lon,
                                                   distance => 50);

=head1 DESCRIPTION

Geo::PostalCode::NoBD is almost the same as Geo::PostalCode, except that
all Berkeley DB support has been removed in favor of loading the entire
CSV database into memory.

=head1 ORIGINAL DESCRIPTION

This is a module for calculating the distance between two postal
codes.  It can find the postal codes within a specified distance of another
postal code or city and state.  It can lookup the city, state, latitude and longitude by
postal code.

=head1 RATIONALE BEHIND NO BERKELEY DB

On a busy day at work, I couldn't get Geo::PostalCode to work
with newer data (the data source TJMATHER points to is no
longer available), so the tests shippsed with his module pass, but trying to
use real data no longer seems to work. DB_File marked the Geo::PostalCode::InstallDB
output file as invalid type or format. If you don't run into that issue by not wanting
to use this module, please drop me a note! I would love to learn how other people
made it work.


So, in order to get my shit done, I decided to create this module. Loading the whole data into memory
from the class constructor has been proven to be enough for massive usage (citation needed)
on a Dancer application where this module is instantiated only once.

=head1 DATA

I have mirrored working data at:

L<http://damog.net/files/misc/zipcodes-csv-10-Aug-2004.zip>

Take a minute to go through its README to learn where this data comes from
and potentially send a thank you note to those who made it available.

=head1 METHODS

=over 4

=item $gp = Geo::PostalCode::NoDB->new(csvfile => $csv_file_path,
                                 [units => mi | km ,]
                                 [earth_radius => earth_radius_in_desired_units ,]
                                );

Returns a new Geo::PostalCode::NoDB object.

You can control the distance units used by providing a C<units>
option, which can be C<mi> for miles (the default) or C<km> for
kilometers, or by providing a C<earth_radius> option set to the radius
of the Earth in your desired unit.  The Earth's radius is
approximately 3956 miles.

=item $record = $gp->lookup_postal_code(postal_code => $postal_code);

Returns a hash reference containing four keys:

  * lat - Latitude
  * lon - Longitude
  * city - City
  * state - State two-letter abbreviation.

=item $record = $gp->lookup_city_state(city => $city, state => $state);

Returns a hash reference containing three keys:

  * lat - Latitude (Average over postal codes in city)
  * lon - Longitude (Average over postal codes in city)
  * postal_codes - Array reference of postal codes in city

=item $miles = $gp->calculate_distance(postal_codes => \@postal_codes);

Returns the distance in miles between the two postal codes in @postal_codes.

=item $postal_codes = $gp->nearby_postal_codes(lat => $lat, lon => $lon, distance => $distance );



( run in 1.363 second using v1.01-cache-2.11-cpan-39bf76dae61 )