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 debug => 1, # will print the URL and some other info
40 my $result = Geo::USCensus::Geocoding->query($request);
42 if ($result->matches) {
43 my $match = $result->match(0);
44 print $match->matchedAddress,"\n",
45 $match->coordinates->{x},',',$match->coordinates->{y},"\n",
46 $match->censustract,"\n";
53 Send a request to the web service. See
54 L<http://geocoding.geo.census.gov/geocoder> for API documentation. This
55 package will always use the JSON data format and the Geographies return type.
57 Returns an object of class Geo::USCensus::Geocoding.
61 my $ua = LWP::UserAgent->new;
62 my $api_uri = 'http://geocoding.geo.census.gov/geocoder/geographies/address';
67 benchmark => 'Public_AR_Census2010',
68 vintage => 'Census2010_Census2010',
70 if (ref $_[0] eq 'HASH') {
71 %opt = (%opt, %{ $_[0] });
76 $DEBUG = $opt{debug} || 0;
77 $opt{format} = 'json';
79 foreach (qw(street city state zip)) {
80 die "$_ required\n" unless length($opt{$_});
83 my $uri = URI->new($api_uri);
84 $uri->query_form(\%opt);
85 warn "$class->query\n$uri\n\n" if $DEBUG;
86 my $http_req = HTTP::Request->new(GET => $uri->as_string);
87 my $resp = $ua->request($http_req);
88 my $self = { addr_response => $resp };
90 if ( $resp->is_success ) {
92 my $tree = eval { from_json($resp->content) };
94 $self->message("Unable to parse response:\n$@");
97 if (!exists $tree->{result}) {
98 $self->message("Response does not contain geocoding results.");
99 warn $self->message. "\n".$resp->content."\n\n";
102 $tree = $tree->{result};
105 if (exists( $tree->{addressMatches} )) {
106 foreach my $am (@{ $tree->{addressMatches} }) {
107 push @matches, Geo::USCensus::Geocoding::Match->new($am);
109 } # else what? does this happen if there's no match? a proper REST
110 # interface should throw a 404
111 $self->{matches} = \@matches;
113 $self->message( $resp->status_line );
122 Sets/gets an explicit error status.
129 $self->{_message} = shift;
131 $self->{_message} || '';
136 Returns the number of matches found.
142 $self->{matches} ? scalar @{ $self->{matches} } : 0;
147 Returns a specific match (starting from zero). Matches are returned
148 as L<Geo::USCensus::Geocoding::Match> objects, in the order they were
149 returned by the service.
156 $self->{matches}->[$i];
161 Mark Wells, C<< <mark at freeside.biz> >>
165 Commercial support for this module is available from Freeside Internet
168 L<http://www.freeside.biz/>
173 =head1 LICENSE AND COPYRIGHT
175 Copyright (C) 2014 Mark Wells.
177 This program is free software; you can redistribute it and/or modify it
178 under the terms of either: the GNU General Public License as published
179 by the Free Software Foundation; or the Artistic License.
181 See http://dev.perl.org/licenses/ for more information.