Skip to content

Instantly share code, notes, and snippets.

@fitnr
Last active August 29, 2015 13:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fitnr/9880962 to your computer and use it in GitHub Desktop.
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.
<?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();
}
<?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