67 lines
1.8 KiB
PHP
67 lines
1.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Pcm\GeocodeBundle\Service;
|
|
|
|
use Exception;
|
|
use Pcm\GeocodeBundle\Entity\GeocodeData;
|
|
use Pcm\GeocodeBundle\Model\LatLonModel;
|
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|
use Symfony\Contracts\HttpClient\ResponseInterface;
|
|
|
|
class Geocoder
|
|
{
|
|
private const API_URL = "https://nominatim.openstreetmap.org/search";
|
|
|
|
public function __construct(private HttpClientInterface $client) {}
|
|
|
|
/**
|
|
* Returns a LatLonModel object
|
|
*
|
|
* @param string $postcode
|
|
* @return GeocodeData
|
|
*/
|
|
public function geocodePostcode(string $postcode): LatLonModel
|
|
{
|
|
$client = $this->setClientHeaders();
|
|
$response = $this->makeApiRequest($client, $postcode);
|
|
$data = $response->toArray();
|
|
$this->throwIfNoResponseData($data);
|
|
|
|
return $this->createGeocodeDataObject($data);
|
|
}
|
|
|
|
private function setClientHeaders(): HttpClientInterface
|
|
{
|
|
return $this->client->withOptions([
|
|
'headers' => ["User-Agent" => "Geocode"]
|
|
]);
|
|
}
|
|
|
|
private function makeApiRequest(HttpClientInterface $client, string $postcode): ResponseInterface
|
|
{
|
|
return $client->request(
|
|
method: 'GET',
|
|
url: self::API_URL,
|
|
options: [
|
|
'query' => [
|
|
'format' => 'json',
|
|
'postalcode' => $postcode
|
|
]
|
|
]
|
|
);
|
|
}
|
|
|
|
private function throwIfNoResponseData(array $data): void
|
|
{
|
|
if (empty($data))
|
|
throw new Exception("No data was received from API response! Were the arguments valid?");
|
|
}
|
|
|
|
private function createGeocodeDataObject(array $data): LatLonModel
|
|
{
|
|
return new LatLonModel((float) $data[0]['lat'], (float) $data[0]['lon']);
|
|
}
|
|
}
|