Skip to content

Instantly share code, notes, and snippets.

@rtt
Last active December 14, 2015 19:18
Show Gist options
  • Select an option

  • Save rtt/5135293 to your computer and use it in GitHub Desktop.

Select an option

Save rtt/5135293 to your computer and use it in GitHub Desktop.
A Geocoder
<?php
class ReportableHTTPGeocodingFailure extends Exception {}
class HTTPGeocodingFailure extends Exception {}
class GeoLocation {
function __construct($lng, $lat) {
$this->lng = $lng;
$this->lat = $lat;
}
function __toString() {
return sprintf('<GeoLocation(%s, %s)>', $this->lng, $this->lat);
}
}
interface Geocoder {
function _geocode($q, $country);
}
class HTTPGeocoder {
private function normalise($q) {
return trim(strtolower($q));
}
final public function geocode($q, $country='GB') {
$q = $this->normalise($q);
$failed = array('geocoded' => false);
try {
$query = $this->_geocode($q, $country);
}
catch (ReportableHTTPGeocodingFailure $e) {
return array_merge($failed, array('message' => $e->getMessage()));
}
catch (HTTPGeocodingFailure $e) {
return array_merge($failed, array('message' => $e->getMessage()));
}
catch (Exception $e) {
return array_merge(
$failed,
array('message' => sprintf('General error: %s', $e->getMessage()))
);
}
return array(
'geocoded' => true,
'geolocation' => $query,
'query' => $q
);
}
}
class GoogleGeocoder extends HTTPGeocoder {
private $endpoint = "http://maps.google.com/maps/api/geocode/json";
protected function _geocode($q, $country) {
$params = array(
"sensor" => "false",
"region" => $country,
"address" => $q
);
$url = sprintf(
"%s?%s",
$this->endpoint,
http_build_query($params)
);
// make request
$resp = @file_get_contents($url);
if (false === $resp) {
throw new Exception('HTTP Error [no response?]');
}
// parse json
$json = @json_decode($resp, true);
if (null === $json) {
throw new Exception('Response Decode Error');
}
if ('ZERO_RESULTS' == $json['status']) {
throw new HTTPGeocodingFailure($json['status']);
}
elseif ('OK' !== $json['status']) {
throw new ReportableHTTPGeocodingFailure($json['status']);
}
$place = $json['results'][0];
return array(
'geolocation' => array(
'lng' => $place['geometry']['location']['lng'],
'lat' => $place['geometry']['location']['lat']
)
);
}
}
function error_response($msg, $and_exit=true) {
echo json_encode(array('success' => false, 'msg' => $msg));
if ($and_exit) {
exit();
}
}
function success_response($resp) {
echo json_encode(array('success' =>$resp));
}
// -- init --
header('Content-type: application/json');
// check backend specified
if (!isset($_GET['backend'])) {
error_response('Please specify a backend');
}
$backend = $_GET['backend'];
if (!class_exists($backend)) {
error_response('Backend not found');
}
if (!isset($_GET['q'])) {
error_response('Please specify a query');
}
// should be good to go
$backend = new $backend();
$result = $backend->geocode($_GET['q']);
success_response($result);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment