diff --git a/inc/VegGuide/Build.pm b/inc/VegGuide/Build.pm index 137fa4f..27b4905 100644 --- a/inc/VegGuide/Build.pm +++ b/inc/VegGuide/Build.pm @@ -84,6 +84,7 @@ my %Requires = ( 'JSON::XS' => '0', 'Lingua::EN::Inflect' => '0', 'List::AllUtils' => '0', + 'Locale::Country' => '3.23', 'LockFile::Simple' => '0', 'LWPx::ParanoidAgent' => '0', 'LWP::Simple' => '0', diff --git a/lib/VegGuide/Geocoder.pm b/lib/VegGuide/Geocoder.pm index f4466f3..b86831c 100644 --- a/lib/VegGuide/Geocoder.pm +++ b/lib/VegGuide/Geocoder.pm @@ -4,82 +4,52 @@ use strict; use warnings; use Geo::Coder::Google 0.06; +use Locale::Country 3.23 qw( country2code ); use VegGuide::Config; use VegGuide::Geocoder::Result; use VegGuide::Util qw( string_is_empty ); use VegGuide::Validate qw( validate SCALAR_TYPE ); -my %Geocoders = ( - map { - lc $_->[0] => { - geocoder => Geo::Coder::Google->new( - host => $_->[1], - apikey => VegGuide::Config->GoogleAPIKey(), - ), - hostname => $_->[1], - country => $_->[0], - } - }[ 'Australia' => 'maps.google.com.au' ], - [ 'Austria' => 'maps.google.com' ], - [ 'Belgium' => 'maps.google.com' ], - [ 'Brazil' => 'maps.google.com' ], - [ 'Canada' => 'maps.google.ca' ], - [ 'Czech Republic' => 'maps.google.com' ], - [ 'Denmark' => 'maps.google.dk' ], - [ 'Finland' => 'maps.google.fi' ], - [ 'France' => 'maps.google.fr' ], - [ 'Germany' => 'maps.google.de' ], - [ 'Hong Kong' => 'maps.google.com' ], - [ 'Hungary' => 'maps.google.com' ], - [ 'India' => 'maps.google.com' ], - [ 'Ireland' => 'maps.google.com' ], - [ 'Italy' => 'maps.google.it' ], - [ 'Japan' => 'maps.google.co.jp' ], - [ 'Luxembourg' => 'maps.google.com' ], - [ 'Netherlands' => 'maps.google.nl' ], - [ 'New Zealand' => 'maps.google.com' ], - [ 'Poland' => 'maps.google.com' ], - [ 'Portugal' => 'maps.google.com' ], - [ 'Puerto Rico' => 'maps.google.com' ], - [ 'Singapore' => 'maps.google.com' ], - [ 'Spain' => 'maps.google.es' ], - [ 'Sweden' => 'maps.google.se' ], - [ 'Switzerland' => 'maps.google.com' ], - [ 'Taiwan' => 'maps.google.com.tw' ], - [ 'United Kingdom' => 'maps.google.com' ], - [ 'USA' => 'maps.google.com' ], -); - { - my $spec = { country => SCALAR_TYPE }; + my $spec = { + country => SCALAR_TYPE, + }; sub new { my $class = shift; my %p = validate( @_, $spec ); - my $country = lc $p{country}; + my $country = $p{country}; - $country = 'usa' + $country = 'USA' if $country =~ /^(?:US|United States)/i; - return unless $Geocoders{$country}; - - my $meth = '_' . $country . '_geocode_address'; + my $meth = '_' . ( lc $country ) . '_geocode_address'; $meth =~ s/ /_/g; $meth = $class->can($meth) || '_standard_geocode_address'; return bless { - geocoder => $Geocoders{$country}{geocoder}, - hostname => $Geocoders{$country}{hostname}, - country => $Geocoders{$country}{country}, - method => $meth, + method => $meth, + country => $country, + cctld => $class->_cctld_for_country($country), }; } } -sub Countries { - return map { $_->{country} } values %Geocoders; +{ + my %exception = ( + gb => 'uk', + ); + + sub _cctld_for_country { + shift; + my $country = shift; + + my $code = country2code($country); + + return $exception{$code} // $code; + } } { @@ -109,14 +79,17 @@ sub geocode_full_address { my $self = shift; my $address = shift; - return VegGuide::Geocoder::Result->new( - $self->{geocoder}->geocode($address) ); -} + my %region; + $region{region} = $self->{cctld} + if $self->{cctld}; -sub hostname { - my $self = shift; + my $geocoder = Geo::Coder::Google->new( + apiver => 3, + key => VegGuide::Config->GoogleAPIKey(), + %region, + ); - return $self->{hostname}; + return VegGuide::Geocoder::Result->new( $geocoder->geocode($address) ); } sub country { @@ -171,7 +144,7 @@ sub _japan_geocode_address { return ( join ', ', - grep {defined} + grep { defined } $p{localized_region}, $address ); } @@ -188,7 +161,7 @@ sub _taiwan_geocode_address { return ( join ', ', - grep {defined} + grep { defined } $p{localized_city}, $address ); } diff --git a/lib/VegGuide/Geocoder/Result.pm b/lib/VegGuide/Geocoder/Result.pm index eab1340..0191652 100644 --- a/lib/VegGuide/Geocoder/Result.pm +++ b/lib/VegGuide/Geocoder/Result.pm @@ -16,9 +16,9 @@ sub new { return unless $geocode_info; return bless { - latitude => $geocode_info->{Point}{coordinates}[1], - longitude => $geocode_info->{Point}{coordinates}[0], - canonical_address => $geocode_info->{address}, + latitude => $geocode_info->{results}{geometry}{location}{lat}, + longitude => $geocode_info->{results}{geometry}{location}{lng}, + canonical_address => $geocode_info->{formatted_address}, }; } diff --git a/t/Geocoder.t b/t/Geocoder.t index 26b89f4..33ddd77 100644 --- a/t/Geocoder.t +++ b/t/Geocoder.t @@ -1,5 +1,6 @@ use strict; use warnings; +use utf8; use Test::More; use VegGuide::Config; @@ -44,7 +45,16 @@ BEGIN { my $lat = shift; my $long = shift; - return { Point => { coordinates => [ $long, $lat ] } }; + return { + results => { + geometry => { + location => { + lat => $lat, + lng => $long, + }, + }, + }, + }; } } @@ -52,22 +62,6 @@ require VegGuide::Geocoder; my %addresses = address_test_data(); -NEW: -{ - ok( - !VegGuide::Geocoder->new( country => 'does not exist' ), - 'Cannot make Geocoder for an invalid country' - ); - - for my $c ( sort keys %addresses ) { - ok( - VegGuide::Geocoder->new( country => $c ), - "Can make Geocoder for $c" - ); - } -} - -GEOCODE: { for my $c ( sort keys %addresses ) { my $geocoder = VegGuide::Geocoder->new( country => $c ); @@ -85,7 +79,6 @@ GEOCODE: } } -ADDRESS_PROCESSING: { for my $c ( sort keys %addresses ) { my $geocoder = VegGuide::Geocoder->new( country => $c );