1 package Geo::USCensus::Geocoding;
9 use Geo::USCensus::Geocoding::Match;
13 Geo::USCensus::Geocoding - The U.S. Census Bureau geocoding service
21 our $VERSION = '0.01';
26 use Geo::USCensus::Geocoding;
30 street => '123 Main Street',
31 city => 'San Francisco', # city
32 state => 'CA', # state/province
33 zip => '93102', # zip/postal code
35 benchmark => 'Public_AR_ACS2013', # default is "Public_AR_Current"
36 vintage => 'Census2010_ACS2013', # default is "Current_Current"
38 my $result = Geo::USCensus::Geocoding->query($request);
40 if ($result->matches) {
41 my $match = $result->match(0);
42 print $match->matchedAddress,"\n",
43 $match->coordinates->{x},',',$match->coordinates->{y},"\n",
44 $match->censustract,"\n";
51 Send a request to the web service. See
52 L<http://geocoding.geo.census.gov/geocoder> for API documentation. This
53 package will always use the JSON data format and the Geographies return type.
55 Returns an object of class Geo::USCensus::Geocoding.
59 my $ua = LWP::UserAgent->new;
60 my $api_uri = 'http://geocoding.geo.census.gov/geocoder/geographies/address';
65 benchmark => 'Public_AR_Current',
66 vintage => 'Current_Current',
68 if (ref $_[0] eq 'HASH') {
69 %opt = (%opt, %{ $_[0] });
74 $opt{format} = 'json';
76 foreach (qw(street city state zip)) {
77 die "$_ required\n" unless length($opt{$_});
80 my $uri = URI->new($api_uri);
81 $uri->query_form(\%opt);
82 warn "$class->query\n$uri\n\n" if $DEBUG;
83 my $http_req = HTTP::Request->new(GET => $uri->as_string);
84 my $resp = $ua->request($http_req);
85 my $self = { addr_response => $resp };
87 if ( $resp->is_success ) {
89 my $tree = eval { from_json($resp->content) };
91 $self->message("Unable to parse response:\n$@");
94 if (!exists $tree->{result}) {
95 $self->message("Response does not contain geocoding results.");
96 warn $self->message. "\n".$resp->content."\n\n";
99 $tree = $tree->{result};
102 if (exists( $tree->{addressMatches} )) {
103 foreach my $am (@{ $tree->{addressMatches} }) {
104 push @matches, Geo::USCensus::Geocoding::Match->new($am);
106 } # else what? does this happen if there's no match? a proper REST
107 # interface should throw a 404
108 $self->{matches} = \@matches;
110 $self->message( $resp->status_line );
119 Sets/gets an explicit error status.
126 $self->{_message} = shift;
128 $self->{_message} || '';
133 Returns the number of matches found.
139 $self->{matches} ? scalar @{ $self->{matches} } : 0;
144 Returns a specific match (starting from zero). Matches are returned
145 as L<Geo::USCensus::Geocoding::Match> objects, in the order they were
146 returned by the service.
153 $self->{matches}->[$i];
158 Mark Wells, C<< <mark at freeside.biz> >>
162 Commercial support for this module is available from Freeside Internet
165 L<http://www.freeside.biz/>
170 =head1 LICENSE AND COPYRIGHT
172 Copyright (C) 2014 Mark Wells.
174 This program is free software; you can redistribute it and/or modify it
175 under the terms of either: the GNU General Public License as published
176 by the Free Software Foundation; or the Artistic License.
178 See http://dev.perl.org/licenses/ for more information.