File Coverage

blib/lib/Geo/Yandex.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Geo::Yandex;
2              
3 1     1   1046 use vars qw ($VERSION);
  1         3  
  1         75  
4             $VERSION = '0.3';
5              
6             my $API = 'geocode-maps.yandex.ru/1.x';
7              
8 1     1   5 use strict;
  1         2  
  1         39  
9 1     1   1145 use utf8;
  1         13  
  1         7  
10 1     1   654 use Geo::Yandex::Location;
  0            
  0            
11             use LWP::UserAgent;
12             use URI::Escape;
13             use XML::LibXML;
14              
15             sub new {
16             my ($class, $key) = @_;
17            
18             unless ($key) {
19             warn "API key is not specified\n";
20             return undef;
21             }
22              
23             my $this = {
24             key => $key,
25             error => '',
26             };
27            
28             bless $this, $class;
29            
30             return $this;
31             }
32              
33             sub location {
34             my ($this, %data) = @_;
35              
36             $this->{'error'} = '';
37              
38             unless ($data{'address'} && $this->{'key'}) {
39             $this->{'error'} = "Either address or API key are not specified\n";
40             return undef;
41             }
42            
43             my $uri
44             = "http://$API/?key=" . uri_escape_utf8($this->{'key'})
45             . '&geocode=' . uri_escape_utf8($data{'address'});
46            
47             $uri .= '&ll=' . $data{'center'} if $data{'center'};
48             $uri .= '&spn=' . $data{'size'} if $data{'size'};
49             $uri .= '&results=' . $data{'results'} if $data{'results'};
50             $uri .= '&skip=' . $data{'skip'} if $data{'skip'};
51              
52             my $useragent = new LWP::UserAgent;
53             my $request = new HTTP::Request(GET => $uri);
54             my $response = $useragent->request($request);
55              
56             if ($response->is_success) {
57             return $this->parse_response($response->content);
58             }
59             else {
60             $this->{'error'} = "HTTP request error: " . $response->status_line . "\n";
61             return ();
62             }
63             }
64              
65             sub parse_response {
66             my ($this, $content) = @_;
67              
68             my $parser = new XML::LibXML;
69             my $xml = $parser->parse_string($content);
70            
71             my $context = new XML::LibXML::XPathContext;
72             $context->registerNs('ymaps', 'http://maps.yandex.ru/ymaps/1.x');
73             $context->registerNs('gml', 'http://www.opengis.net/gml');
74             $context->registerNs('xal', 'urn:oasis:names:tc:ciq:xsdschema:xAL:2.0');
75             $context->registerNs('ygeo', 'http://maps.yandex.ru/geocoder/1.x');
76            
77             my $ymaps = ${$context->findnodes('/ymaps:ymaps', $xml)}[0];
78             my $request = ${$context->findnodes('.//ygeo:request', $ymaps)}[0]->textContent;
79             my $found = ${$context->findnodes('.//ygeo:found', $ymaps)}[0]->textContent;
80              
81             return () unless $found;
82              
83             my @featureMembers = $context->findnodes('.//gml:featureMember', $ymaps);
84             my @ret;
85             foreach my $featureMember (@featureMembers) {
86             push @ret, new Geo::Yandex::Location($context, $featureMember);
87             }
88            
89             return @ret;
90             }
91              
92             1;
93              
94             __END__