File Coverage

lib/Geo/Coder/Many/Googlev3.pm
Criterion Covered Total %
statement 15 48 31.2
branch 0 14 0.0
condition 0 6 0.0
subroutine 5 8 62.5
pod 2 2 100.0
total 22 78 28.2


line stmt bran cond sub pod time code
1             package Geo::Coder::Many::Googlev3;
2              
3 2     2   5 use strict;
  2         1  
  2         61  
4 2     2   5 use warnings;
  2         2  
  2         34  
5 2     2   5 use Carp;
  2         2  
  2         88  
6 2     2   597 use Geo::Coder::Many::Util;
  2         2  
  2         79  
7 2     2   8 use base 'Geo::Coder::Many::Generic';
  2         3  
  2         730  
8              
9             =head1 NAME
10              
11             Geo::Coder::Many::Googlev3 - Plugin for version 3 of the google maps geocoder
12              
13             =head1 VERSION
14              
15             Version 0.02
16              
17             =cut
18              
19             our $VERSION = '0.02';
20              
21             # Requires Geo::Coder::Googlev3 0.07 or above
22 0     0     sub _MIN_MODULE_VERSION { return '0.07'; }
23              
24             =head1 SYNOPSIS
25              
26             This class wraps Geo::Coder::Googlev3 such that it can be used in
27             Geo::Coder::Many, by converting the results to a standard form.
28              
29             Note: this module supports v3 of the Google geocoder. There is also
30             Geo::Coder::Google (also supported by Geo::Coder::Many) which supports
31             the older version 2.
32              
33             =head1 METHODS
34              
35             =head2 geocode
36              
37             Takes a location string, geocodes it using Geo::Coder::Googlev3, and returns the
38             result in a form understandable to Geo::Coder::Many
39              
40             =cut
41              
42             # see details of Google's response format here:
43             # v3: http://code.google.com/apis/maps/documentation/geocoding/
44              
45             sub geocode {
46 0     0 1   my $self = shift;
47 0           my $location = shift;
48 0 0         defined $location or croak "Geo::Coder::Many::Googlev3::geocode
49             method must be given a location.";
50              
51 0           my $raw = $self->{GeoCoder}->geocode( location => $location,
52             raw => 1,
53             );
54             # was there a response
55 0 0         if (!defined($raw)){
56 0           carp "no response from googlev3 when requesting $location";
57 0           return;
58             }
59              
60             # was response any good?
61 0 0         if ($raw->{status} ne 'OK'){
62             # carp $raw->{status} . " when requesting $location";
63 0           return;
64             }
65              
66 0           my $Response = Geo::Coder::Many::Response->new({ location => $location});
67              
68 0           foreach my $raw_reply ( @{$raw->{results}} ){
  0            
69 0           my $precision = 0; # unknown
70              
71 0 0 0       if (defined($raw_reply->{geometry})
72             && defined($raw_reply->{geometry}{viewport}) ){
73            
74 0           my $box = $raw_reply->{geometry}{viewport};
75             # lng and lat in decimal degree format
76            
77             $precision =
78             Geo::Coder::Many::Util::determine_precision_from_bbox({
79             'lon1' => $box->{southwest}{lng},
80             'lat1' => $box->{southwest}{lat},
81             'lon2' => $box->{northeast}{lng},
82             'lat2' => $box->{northeast}{lat},
83 0           });
84              
85             }
86             # which country?
87             # need to scan the address components
88 0           my $country = undef;
89 0           foreach my $rh_address_component (@{$raw_reply->{address_components}}){
  0            
90 0           my $ra_types = $rh_address_component->{types};
91 0           my $p = 0;
92 0           my $c = 0;
93 0           foreach my $x (@$ra_types){
94 0 0         $p = 1 if ($x eq 'political');
95 0 0         $c = 1 if ($x eq 'country');
96 0 0 0       if ($c && $p){
97 0           $country = $rh_address_component->{long_name};
98             }
99             }
100             }
101              
102             my $tmp = {
103             address => $raw_reply->{formatted_address},
104             country => $country,
105             latitude => $raw_reply->{geometry}{location}{lat},
106             longitude => $raw_reply->{geometry}{location}{lng},
107 0           precision => $precision,
108             };
109 0           $Response->add_response( $tmp, $self->get_name());
110             }
111 0           return $Response;
112             }
113              
114             =head2 get_name
115              
116             The short name by which Geo::Coder::Many can refer to this geocoder.
117              
118             =cut
119              
120 0     0 1   sub get_name { my $self = shift; return 'googlev3 ' . $self->{GeoCoder}->VERSION; }
  0            
121              
122             1;