File Coverage

blib/lib/Geo/Parser/Text.pm
Criterion Covered Total %
statement 29 69 42.0
branch 0 4 0.0
condition n/a
subroutine 10 14 71.4
pod 2 4 50.0
total 41 91 45.0


line stmt bran cond sub pod time code
1             package Geo::Parser::Text;
2              
3 1     1   13907 use 5.006;
  1         3  
4 1     1   3 use strict;
  1         1  
  1         17  
5 1     1   2 use warnings;
  1         5  
  1         22  
6              
7 1     1   702 use XML::Simple;
  1         6503  
  1         7  
8 1     1   769 use LWP::UserAgent;
  1         36975  
  1         48  
9 1     1   13 use HTTP::Request;
  1         1  
  1         34  
10 1     1   6 use URI;
  1         2  
  1         34  
11 1     1   974 use Data::Dumper;
  1         8203  
  1         107  
12              
13              
14 1     1   9 use constant DEBUG => 0;
  1         2  
  1         98  
15 1     1   5 use constant GEO_HOST => q{http://geocode.xyz};
  1         2  
  1         692  
16              
17             sub new {
18 0     0 1   my $class = shift;
19 0           my $self = {
20             geo_host => shift
21             };
22              
23 0           bless ($self, $class);
24 0           return $self;
25             }
26              
27             sub geodata {
28 0     0 0   my $self = shift;
29 0 0         $self->{geodata} = $_[0] if $_[0];
30 0           return $self->{geodata};
31             }
32              
33             sub geocode {
34 0     0 1   my $self = shift;
35 0           my %params = @_;
36              
37 0           my %form_values;
38 0           foreach my $param (keys %params) {
39 0           $form_values{$param} = $params{$param};
40             }
41 0           $form_values{geoit} = 'XML'; #default
42              
43 0           warn Data::Dumper->Dump([\%form_values],['Form Values']) if DEBUG;
44              
45 0           $self->process_request(%form_values);
46              
47 0           my $geodata = $self->geodata;
48 0           my @a = split(//,$geodata);
49 0           my $geod = pop @a;
50 0           $geod = '' . $geod;
51 0           my %t;
52 0           my $ref = \%t;
53              
54 0           eval {
55 0           $ref = XMLin($geod);
56             };
57 0           warn Data::Dumper->Dump([$ref],['Response']) if DEBUG;
58              
59 0           $self->geodata($ref);
60              
61 0           return $self->geodata;
62              
63             }
64              
65             sub process_request {
66 0     0 0   my $self = shift;
67 0           my %form_values = @_;
68 0 0         $self->{geo_host} = GEO_HOST unless $self->{geo_host};
69              
70 0           my $uri = URI->new;
71 0           $uri->query_form(%form_values);
72 0           my $ua = LWP::UserAgent->new;
73 0           my $req = HTTP::Request->new(POST => $self->{geo_host});
74 0           $req->content_type('application/x-www-form-urlencoded');
75 0           $req->content($uri->query);
76              
77 0           my $res = $ua->request($req);
78 0           my $result = $res->as_string;
79              
80 0           warn $result if DEBUG;
81              
82 0           my $geodata = $result;
83              
84              
85 0           return $self->geodata($geodata);
86             }
87              
88              
89              
90             =head1 NAME
91              
92             Geo::Parser::Text - Perl extension for parsing, geocoding and standardizing locations from free form text. (See Geocode.xyz or Geolytica.com or addrs.xyz for coverage details)
93              
94             =head1 VERSION
95              
96             Version 0.04
97              
98             =cut
99              
100             our $VERSION = '0.04';
101              
102              
103             =head1 SYNOPSIS
104              
105             use Geo::Parser::Text;
106            
107             # initialize with your host
108             my $g = Geo::Parser::Text->new([geo_host]);
109              
110             # Scan text in $str for locations...
111             my $hashref = $g->geocode(scantext=>$str);
112              
113             # Geocode a single location from $str...
114             my $hashref = $g->geocode(locate=>$str);
115             #
116            
117             # Example...
118              
119             use Geo::Parser::Text;
120             use Data::Dumper;
121             my $g = Geo::Parser::Text->new('http://geocode.xyz');
122              
123             my $str = "The most important museums of Amsterdam are located on the Museumplein, located at the southwestern side of the Rijksmuseum.";
124             my $ref = $g->geocode(scantext=>$str,strict=>1,region='NL'); #in strict mode will return top matches only using context aware parsing (which may be slower)
125             print Dumper $ref;
126              
127             #expected response
128             $Response = {
129             'match' => [
130             {
131             'latt' => '52.35704',
132             'confidence' => '0.8',
133             'longt' => '4.88356',
134             'location' => 'MUSEUMPLEIN, AMSTERDAM, NL'
135             },
136             {
137             'confidence' => '0.8',
138             'latt' => '52.36017396823732',
139             'longt' => '4.895017880552782',
140             'location' => 'Amsterdam, NL'
141             },
142             {
143             'latt' => '52.35994',
144             'confidence' => '0.7',
145             'longt' => '4.88539',
146             'location' => 'Rijksmuseum, NL'
147             },
148             {
149             'location' => '1, MUSEUMPLEIN, RIJKSMUSEUM, NL',
150             'longt' => '4.88345',
151             'confidence' => '0.5',
152             'latt' => '52.3576'
153             },
154             {
155             'location' => 'Museumplein, NL',
156             'longt' => '4.88194',
157             'latt' => '52.35722',
158             'confidence' => '0.5'
159             },
160             {
161             'location' => 'most, NL',
162             'longt' => '6.01528',
163             'confidence' => '0.5',
164             'latt' => '51.38417'
165             }
166             ]
167             };
168            
169              
170             #or
171              
172             #forward geocode and cleanup/standardize input address
173             my $ref = $g->geocode(locate=>'10 Downing St, londino UK');
174             print Dumper $ref;
175              
176             #expected response
177             $Response = {
178             'longt' => '-0.1275923',
179             'standard' => {
180             'prov' => 'GB',
181             'confidence' => '0.80',
182             'city' => 'London',
183             'addresst' => '10 Downing St, London SW1A 2AB, UK',
184             'stnumber' => '10'
185             },
186             'latt' => '51.5034066'
187             };
188              
189              
190             #reverse geocode
191             my $ref = $g->geocode(locate=>'51.5034066,-0.1275923');
192             print Dumper $ref;
193              
194             #expected response
195             $Response = {
196             'confidence' => '0.9',
197             'distance' => '0',
198             'city' => 'London',
199             'inlatt' => '51.50341',
200             'stnumber' => '9',
201             'latt' => '51.50328',
202             'postal' => 'SW1A 2AG',
203             'staddress' => 'Downing Street',
204             'longt' => '-0.12751',
205             'inlongt' => '-0.12759',
206             'prov' => 'UK'
207             };
208              
209            
210             =head1 DESCRIPTION
211              
212             This module provides a Perl frontend for the geocode.xyz, geocoder.ca and addrs.xyz API.
213             It allows the programmer to extract locations containing street addresses, street intersections and city names along with their geocoded latitude,longitude from bodies of text such as microblogs or wikipedia entries. (It should work with any type of text, but dumping html text or paragraphs containing over 200 words, will slow down the response considerably. If you need faster parsing grab the geocode.xyz server image on the AWS, and run it on a faster server.
214             If you run your own instance, make sure to pass the instance ip address or domain name at invocation eg, Geo::Parser::Text->new($server). For North American locations use geolytica.com, and for Australia and New Zealand use addrs.xyz
215              
216             The api also geocodes single locations (returning the location matched with the highest probability from a string of text. If you pass a latitude,longitude pair, it will reverse geocode that point)
217              
218             For explanation on the API responses see http://geocode.xyz/api
219            
220             =head2 METHODS
221              
222             =head2 new
223              
224             my $geo = new ( host => 'geocode.xyz');
225              
226             Initialize with the default server. geocode.xyz for Europe, geocoder.ca for North America, addrs.xyz for Australia and New Zealand.
227              
228             =head2 geocode
229              
230             my $ref = $geo->geocode(locate=>'Paris France');
231              
232             Set the text to be scanned or string to be geocoded and return the hash reference with the response.
233             Takes a hash of parameter names and values.
234             You are required to pass a hash to geocode with either the scantext or locate key set to the text you want to geocode/geoparse.
235             You may also pass other optional arguments as described in the API.
236              
237             =over 1
238              
239             =back
240             =head1 EXPORT
241              
242             None by default.
243              
244              
245             =head1 REQUIREMENTS
246              
247             XML::Simple,
248             LWP::UserAgent,
249             HTTP::Request,
250             URI
251              
252             =head1 AUTHOR
253              
254             Ervin Ruci, C<< >>
255              
256             =head1 BUGS
257              
258             Please report any bugs or feature requests to C, or through
259             the web interface at L. I will be notified, and then you'll
260             automatically be notified of progress on your bug as I make changes.
261              
262              
263              
264              
265             =head1 SUPPORT
266              
267             You can find documentation for this module with the perldoc command.
268              
269             perldoc Geo::Parser::Text
270              
271              
272             You can also look for information at:
273              
274             =over 4
275              
276             =item * RT: CPAN's request tracker (report bugs here)
277              
278             L
279              
280             =item * AnnoCPAN: Annotated CPAN documentation
281              
282             L
283              
284             =item * CPAN Ratings
285              
286             L
287              
288             =item * Search CPAN
289              
290             L
291              
292             =back
293              
294              
295             =head1 ACKNOWLEDGEMENTS
296              
297              
298             =head1 LICENSE AND COPYRIGHT
299              
300             Copyright 2016 Ervin Ruci.
301              
302             This program is free software; you can redistribute it and/or modify it
303             under the terms of the the Artistic License (2.0). You may obtain a
304             copy of the full license at:
305              
306             L
307              
308             Any use, modification, and distribution of the Standard or Modified
309             Versions is governed by this Artistic License. By using, modifying or
310             distributing the Package, you accept this license. Do not use, modify,
311             or distribute the Package, if you do not accept this license.
312              
313             If your Modified Version has been derived from a Modified Version made
314             by someone other than you, you are nevertheless required to ensure that
315             your Modified Version complies with the requirements of this license.
316              
317             This license does not grant you the right to use any trademark, service
318             mark, tradename, or logo of the Copyright Holder.
319              
320             This license includes the non-exclusive, worldwide, free-of-charge
321             patent license to make, have made, use, offer to sell, sell, import and
322             otherwise transfer the Package with respect to any patent claims
323             licensable by the Copyright Holder that are necessarily infringed by the
324             Package. If you institute patent litigation (including a cross-claim or
325             counterclaim) against any party alleging that the Package constitutes
326             direct or contributory patent infringement, then this Artistic License
327             to you shall terminate on the date that such litigation is filed.
328              
329             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
330             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
331             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
332             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
333             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
334             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
335             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
336             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
337              
338              
339             =head1 SEE ALSO
340              
341             Geo::Coder::Canada
342             Geo::Coder::OpenCage
343             Geo::Parse::OSM
344             Text::NLP
345             =cut
346              
347             1; # End of Geo::Parser::Text