File Coverage

lib/Geo/Coder/OpenCage.pm
Criterion Covered Total %
statement 28 74 37.8
branch 3 24 12.5
condition 2 6 33.3
subroutine 7 10 70.0
pod 4 4 100.0
total 44 118 37.2


line stmt bran cond sub pod time code
1             package Geo::Coder::OpenCage;
2             # ABSTRACT: Geocode coordinates and addresses with the OpenCage Geocoder
3             $Geo::Coder::OpenCage::VERSION = '0.34';
4 8     8   746348 use strict;
  8         82  
  8         262  
5 8     8   44 use warnings;
  8         13  
  8         213  
6              
7 8     8   39 use Carp;
  8         15  
  8         450  
8 8     8   5637 use HTTP::Tiny;
  8         335631  
  8         379  
9 8     8   3349 use JSON::MaybeXS;
  8         56510  
  8         569  
10 8     8   4202 use URI;
  8         35145  
  8         6451  
11             # FIXME - must be a way to get this from dist.ini?
12             my $version = 0.34;
13             my $ua_string;
14              
15             sub new {
16 3     3 1 1881 my $class = shift;
17 3         10 my %params = @_;
18              
19 3 100       10 if (!$params{api_key}) {
20 1         16 croak "api_key is a required parameter for new()";
21             }
22              
23 2         27 $ua_string = $class . ' ' . $version;
24 2   33     19 my $ua = $params{ua} || HTTP::Tiny->new(agent => $ua_string);
25 2         184 my $api_url = 'https://api.opencagedata.com/geocode/v1/json';
26            
27 2 50 33     9 if (defined($params{http} && $params{http} == 1 )){
28 0         0 $api_url =~ s|^https|http|;
29             }
30             my $self = {
31             version => $version,
32             api_key => $params{api_key},
33 2         20 ua => $ua,
34             json => JSON::MaybeXS->new(utf8 => 1),
35             url => URI->new($api_url),
36             };
37              
38 2         9053 return bless $self, $class;
39             }
40              
41             sub ua {
42 0     0 1   my $self = shift;
43 0           my $ua = shift;
44 0 0         if (defined($ua)) {
45 0           $ua->agent($ua_string);
46 0           $self->{ua} = $ua;
47             }
48 0           return $self->{ua};
49             }
50              
51             # see list: https://opencagedata.com/api#forward-opt
52             my %valid_params = (
53             abbrv => 1,
54             address_only => 1,
55             add_request => 1,
56             bounds => 1,
57             countrycode => 1,
58             format => 0,
59             jsonp => 0,
60             language => 1,
61             limit => 1,
62             min_confidence => 1,
63             no_annotations => 1,
64             no_dedupe => 1,
65             no_record => 1,
66             q => 1,
67             pretty => 1, # makes no actual difference
68             proximity => 1,
69             roadinfo => 1,
70             );
71              
72             sub geocode {
73 0     0 1   my $self = shift;
74 0           my %params = @_;
75              
76 0 0         if (defined($params{location})) {
77 0           $params{q} = delete $params{location};
78             } else {
79 0           warn "location is a required parameter for geocode()";
80 0           return undef;
81             }
82              
83 0           for my $k (keys %params) {
84 0 0         if (!defined($params{$k})) {
85 0           warn "Unknown geocode parameter: $k";
86 0           delete $params{$k};
87             }
88 0 0         if (!$params{$k}) { # is a real parameter but we dont support it
89 0           warn "Unsupported geocode parameter: $k";
90 0           delete $params{$k};
91             }
92             }
93              
94 0           $params{key} = $self->{api_key};
95            
96             # sort the params for better cachability
97 0           my @final_params;
98 0           foreach my $k (sort keys %params){
99 0           push(@final_params, $k => $params{$k})
100            
101             }
102 0           my $URL = $self->{url}->clone();
103 0           $URL->query_form(\@final_params);
104             # print STDERR 'url: ' . $URL->as_string . "\n";
105 0           my $response = $self->{ua}->get($URL);
106              
107 0 0         if (!$response) {
108             my $reason = (ref($response) eq 'HTTP::Response')
109             ? $response->status_line() #
110 0 0         : $response->{reason};
111 0           warn "failed to fetch '$URL': ", $reason;
112 0           return undef;
113             }
114              
115             # Support HTTP::Tiny and LWP:: CPAN packages
116             my $content = (ref($response) eq 'HTTP::Response')
117             ? $response->decoded_content()
118 0 0         : $response->{content};
119             my $is_success = (ref($response) eq 'HTTP::Response')
120             ? $response->is_success()
121 0 0         : $response->{success};
122              
123 0           my $rh_content = $self->{json}->decode($content);
124              
125              
126 0 0         if (!$is_success) {
127 0           warn "response when requesting '$URL': " . $rh_content->{status}{code} . ', ' . $rh_content->{status}{message};
128 0           return undef;
129             }
130 0           return $rh_content;
131             }
132              
133             sub reverse_geocode {
134 0     0 1   my $self = shift;
135 0           my %params = @_;
136              
137 0           foreach my $k (qw(lat lng)) {
138 0 0         if (!defined($params{$k})) {
139 0           warn "$k is a required parameter";
140 0           return undef;
141             }
142             }
143              
144 0           $params{location} = join(',', delete @params{'lat', 'lng'});
145 0           return $self->geocode(%params);
146             }
147              
148             1;
149              
150             __END__