Skip to content

Instantly share code, notes, and snippets.

@barnabywalters
Last active January 2, 2016 14:39
Show Gist options
  • Save barnabywalters/8318401 to your computer and use it in GitHub Desktop.
Save barnabywalters/8318401 to your computer and use it in GitHub Desktop.
<?php
// where $app is a silex/pimple container — this could easily be rewritten as an ordinary function though
// example usage: list($location, $err) = $app['nominatim.reverse']([-1.125, 3.526])
function nameForLocation(array $location, $fallback='Unknown Location') {
if (isset($location['name'])) return $location['name'];
if (isset($location['street-address']) and isset($location['region']))
return "{$location['street-address']}, {$location['region']}";
if (isset($location['latitude']) and isset($location['longitude']))
return round($location['latitude'], 2) . ', ' . round($location['longitude'], 2);
return $fallback;
}
$app['nominatim.reverse'] = $app->share(function () use ($app) {
return function (array $coordinates) use ($app) {
$client = new Guzzle\Http\Client(isset($app['nominatim.server']) ? $app['nominatim.server'] : 'http://nominatim.openstreetmap.org/');
$query = [
'lat' => $coordinates[0],
'lon' => $coordinates[1],
'email' => $app['nominatim.email'],
'format' => 'json',
'zoom' => isset($app['nominatim.zoom']) ? $app['nominatim.zoom'] : 17,
'addressdetails' => '1'
];
$cacheKey = 'nominatim.reverse.'.implode(',', $coordinates);
if ($app['cache']->contains($cacheKey)) {
return [$app['cache']->fetch($cacheKey), null];
}
try {
// figure out if we need to sleep for a short while for Nominatim
if ($app['cache']->contains('nominatim.last-query-time')) {
$nextQueryTime = 1 + $app['cache']->fetch('nominatim.last-query-time');
if (microtime(true) < $nextQueryTime) {
time_sleep_until($nextQueryTime);
}
}
$data = $client->get([
'reverse{?data*}',
['data' => $query]
])->send()->json();
$app['cache']->save('nominatim.last-query-time', microtime(true));
$adr = $data['address'];
$region = function ($g) {
if ($g['country_code'] == 'us')
return @($g['state'] ?: $g['county']);
else
return @($g['county'] ?: $g['state']);
};
$location = @([
'street-address' => $adr['road'] ?: null,
'extended-address' => $adr['suburb'] ?: null,
'locality' => $adr['hamlet'] ?: $adr['village'] ?: $adr['town'] ?: $adr['city'] ?: null,
'region' => $region($adr),
'country-name' => $adr['country'] ?: null,
'postal-code' => $adr['postcode'] ?: null,
'country-code' => $adr['country_code'] ?: null,
'latitude' => $coordinate
s[0],
'longitude' => $coordinates[1]
]);
$location['name'] = nameForLocation($location);
$app['cache']->save($cacheKey, $location);
return [$location, null];
} catch (Guzzle\Common\Exception\GuzzleException $e) {
return [null, $e];
}
};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment