package Geo::Coder::Many::PlaceFinder; use warnings; use strict; use Carp; use Geo::Coder::Many::Generic; use Geo::Coder::Many::Util; use base 'Geo::Coder::Many::Generic'; =head1 NAME Geo::Coder::Many::PlaceFinder - Yahoo PlaceFinder plugin for Geo::Coder::Many =head1 VERSION Version 0.03 =cut our $VERSION = '0.03'; # Requires Geo::Coder::PlaceFinder 0.02 or above sub _MIN_MODULE_VERSION { return '0.02'; } =head1 SYNOPSIS This module adds Yahoo PlaceFinder support to Geo::Coder::Many. Use as follows: use Geo::Coder::Many; use Geo::Coder::PlaceFinder; my $options = { }; my $geocoder_many = Geo::Coder::Many->new( $options ); my $place_finder = Geo::Coder::PlaceFinder->new( appid => 'YOUR_APP_ID' ); my $place_finder_options = { geocoder => $place_finder, daily_limit => 50000, }; $geocoder_many->add_geocoder( $place_finder_options ); my $location = $geocoder_many->geocode( { location => '82 Clerkenwell Road, London, EC1M 5RF' } ); =head1 USAGE POLICY As of writing, Yahoo PlaceFinder allows up to 50000 requests per day. This may change, so you should check the latest documentation to make sure you aren't going to get blocked. http://developer.yahoo.com/geo/placefinder/ =head1 SUBROUTINES/METHODS =head2 geocode This is called by Geo::Coder::Many - it sends the geocoding request (via Geo::Coder::PlaceFinder) and extracts the resulting location, returning it in a standard Geo::Coder::Many::Response. =cut sub geocode { my $self = shift; my $location = shift; defined $location or croak "geocode method must be given a location\n"; my @raw_replies = $self->{GeoCoder}->geocode( location => $location ); my $response = Geo::Coder::Many::Response->new( { location => $location } ); my $http_response = $self->{GeoCoder}->response(); my $location_data = []; foreach my $raw_reply ( @raw_replies ) { my @address_lines = @{$raw_reply}{'line1', 'line2', 'line3', 'line4'}; @address_lines = grep {!/^\s*$/x} @address_lines; my $address = (join ', ', @address_lines); my $precision = 0; if (defined($raw_reply->{boundingbox})){ my $box = $raw_reply->{boundingbox}; # lng and lat in decimal degree format $precision = Geo::Coder::Many::Util::determine_precision_from_bbox({ 'lon1' => $box->{west}, 'lat1' => $box->{south}, 'lon2' => $box->{east}, 'lat2' => $box->{north}, }); } my $tmp = { address => $address, country => $raw_reply->{country}, longitude => $raw_reply->{longitude}, latitude => $raw_reply->{latitude}, precision => $precision, }; $response->add_response( $tmp, $self->get_name() ); } $response->set_response_code($http_response->code()); return $response; } =head2 get_name Returns the name of the geocoder type - used by Geo::Coder::Many =cut sub get_name { my $self = shift; return 'place_finder ' . $self->{GeoCoder}->VERSION; }; 1; # End of Geo::Coder::Many::PlaceFinder