Last active
August 29, 2015 13:57
-
-
Save fitnr/9880962 to your computer and use it in GitHub Desktop.
The new Census Geocoding API (http://geocoding.geo.census.gov/geocoder/) is really great, but doesn't accept cross-site AJAX request. This is a simple PHP wrapper to passes javascript requests to the Census.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
require 'census-geocoder-lib.php'; | |
// Who doesn't want to send in coordinates or addresses, and get Census geography back? | |
try { | |
// try passing ?lat=36.54&lng=-86.5&returntype=geographies&searchtype=coordinates | |
$api = new census_geocode($_GET); | |
echo $api->run(); | |
/* | |
// another way, specifying the returntype and searchtype: | |
// try passing ?returntype=locations&searchtype=onelineaddress&address=1600+Pennsylvania+Avenue+Washington+DC | |
$api2 = new census_geocode($_GET); | |
echo $api2->run(); | |
*/ | |
} catch (Exception $e) { | |
print $e->getmessage(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Census Geocoder wrapper | |
* | |
* see http://geocoding.geo.census.gov/geocoder/Geocoding_Services_API.pdf for details on the census api | |
* One difference is that this accepts `lat` and `lng` as inputs for coordinates, whereas the census wants x and y. | |
* If you are like me you have a hard time thinking of the globe as graph paper, so `lat` and `lng` are better | |
*/ | |
class census_geocode { | |
// These are all of the string settings. Lat and Lon (x and y) are assigned especially, because they are floats. | |
private $params = array( | |
'vintage' => 'Census2010_Census2010', | |
'benchmark' => 'Public_AR_Census2010', | |
'format' => 'json', | |
'layers' => NULL, | |
'address' => NULL, | |
'street' => NULL, | |
'city' => NULL, | |
'state' => NULL, | |
'zip' => NULL | |
); | |
private $returntypes = array('geographies', 'locations'); | |
private $searchtypes = array('onelineaddress', 'address', 'coordinates'); | |
private $url = 'http://geocoding.geo.census.gov/geocoder/%1$s/%2$s'; | |
public $encoded; | |
/** | |
* @param $raw array A set of parameters, perhaps raw $_GET data | |
* @param $curlopts array Optional arguments for php libcurl | |
* @param $url string The census API endpoint | |
*/ | |
function __construct($raw, $curlopts=array(), $url=false) { | |
$this->url = ($url) ? $url : $this->url; | |
$this->curlopts = $curlopts; | |
// the basic options in the geocoder aren't set as GET options, instead the url itself changes | |
$this->url = $this->set_geocoder_type($raw); | |
// encode the url parameters | |
$this->encoded = $this->encode_params($raw); | |
} | |
function set_geocoder_type($raw) { | |
if (array_key_exists('returntype', $raw) && in_array($raw['returntype'], $this->returntypes)): | |
$this->returntype = $raw['returntype']; | |
endif; | |
if (array_key_exists('searchtype', $raw) && in_array($raw['searchtype'], $this->searchtypes)): | |
$this->searchtype = $raw['searchtype']; | |
endif; | |
if ($this->returntype && $this->searchtype): | |
return sprintf($this->url, $this->returntype, $this->searchtype); | |
else : | |
throw new Exception('Need both a returntype and a searchtype', 1); | |
endif; | |
} | |
function encode_params($raw) { | |
if ($this->searchtype === 'coordinates') : | |
if (!array_key_exists('lat', $raw) || !array_key_exists('lng', $raw)) : | |
throw new Exception('Need both a lat and a lng', 1); | |
endif; | |
// assign numeric versions of the x and y | |
$this->params['x'] = floatval($raw['lng']); | |
$this->params['y'] = floatval($raw['lat']); | |
endif; | |
// start off the encoded string | |
$encoded = '?'; | |
foreach ($this->params as $key => $value): | |
$passed_val = (array_key_exists($key, $raw)) ? strval($raw[$key]) : NULL; | |
$value = ($passed_val) ? $passed_val : $value; | |
if ($value) : | |
$encoded .= urlencode($key) .'='. urlencode($value) . '&'; | |
endif; | |
endforeach; | |
return substr($encoded, 0, -1); | |
} | |
function run() { | |
if (!isset($this->encoded)): | |
throw new Exception('Missing encoded arguments', 1); | |
endif; | |
$handle = curl_init($this->url . $this->encoded); | |
curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE); | |
if ($this->curlopts): | |
curl_setopt_array($handle, $this->curlopts); | |
endif; | |
$result = curl_exec($handle); | |
if ($result === false): | |
throw new Exception(curl_error($handle), 1); | |
endif; | |
curl_close($handle); | |
return $result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment