First commit
This commit is contained in:
32
src/Entity/GeocodeData.php
Normal file
32
src/Entity/GeocodeData.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pcm\GeocodeBundle\Entity;
|
||||
|
||||
class GeocodeData
|
||||
{
|
||||
private float $latitude;
|
||||
|
||||
private float $longitude;
|
||||
|
||||
public function setLatitude(float $latitude): void
|
||||
{
|
||||
$this->latitude = $latitude;
|
||||
}
|
||||
|
||||
public function setLongitude(float $longitude): void
|
||||
{
|
||||
$this->longitude = $longitude;
|
||||
}
|
||||
|
||||
public function getLatitude(): float
|
||||
{
|
||||
return $this->getLatitude();
|
||||
}
|
||||
|
||||
public function getLongitude(): float
|
||||
{
|
||||
return $this->getLongitude();
|
||||
}
|
||||
}
|
||||
66
src/Geocoder.php
Normal file
66
src/Geocoder.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pcm\GeocodeBundle;
|
||||
|
||||
use Exception;
|
||||
use Pcm\GeocodeBundle\Entity\GeocodeData;
|
||||
use Symfony\Component\HttpClient\HttpClient;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
use Symfony\Contracts\HttpClient\ResponseInterface;
|
||||
|
||||
class Geocoder
|
||||
{
|
||||
private const API_URL = "https://nominatim.openstreetmap.org/search";
|
||||
|
||||
/**
|
||||
* @param string $postcode
|
||||
* @return GeocodeData
|
||||
*/
|
||||
public function geocodePostcode(string $postcode): GeocodeData
|
||||
{
|
||||
$client = $this->getHttpClient();
|
||||
$response = $this->makeApiRequest($client, $postcode);
|
||||
$data = $response->toArray();
|
||||
$this->throwIfNoResponseData($data);
|
||||
|
||||
return $this->createGeocodeDataObject($data);
|
||||
}
|
||||
|
||||
private function getHttpClient(): HttpClientInterface
|
||||
{
|
||||
return HttpClient::create([
|
||||
'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): GeocodeData
|
||||
{
|
||||
$geocodeData = new GeocodeData();
|
||||
$geocodeData->setLatitude((float) $data[0]['lat']);
|
||||
$geocodeData->setLongitude((float) $data[0]['lon']);
|
||||
|
||||
return $geocodeData;
|
||||
}
|
||||
}
|
||||
18
src/Interface/MappableInterface.php
Normal file
18
src/Interface/MappableInterface.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pcm\GeocodeBundle\Interface;
|
||||
|
||||
interface MappableInterface
|
||||
{
|
||||
public function getLatitude(): ?float;
|
||||
|
||||
public function getLongitude(): ?float;
|
||||
|
||||
public function setLatitude(float $lat): self;
|
||||
|
||||
public function setLongitude(float $lon): self;
|
||||
|
||||
public function isGeocoded(): bool;
|
||||
}
|
||||
9
src/PcmGeocodeBundle.php
Normal file
9
src/PcmGeocodeBundle.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pcm\GeocodeBundle;
|
||||
|
||||
use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
|
||||
|
||||
class PcmGeocodeBundle extends AbstractBundle {}
|
||||
41
src/Trait/MappableTrait.php
Normal file
41
src/Trait/MappableTrait.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Pcm\GeocodeBundle\Trait;
|
||||
|
||||
trait MappableTrait
|
||||
{
|
||||
private ?float $latitude = null;
|
||||
|
||||
private ?float $longitude = null;
|
||||
|
||||
public function getLatitude(): ?float
|
||||
{
|
||||
return $this->latitude;
|
||||
}
|
||||
|
||||
public function getLongitude(): ?float
|
||||
{
|
||||
return $this->longitude;
|
||||
}
|
||||
|
||||
public function setLatitude(float $lat): self
|
||||
{
|
||||
$this->latitude = $lat;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setLongitude(float $lon): self
|
||||
{
|
||||
$this->longitude = $lon;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isGeocoded(): bool
|
||||
{
|
||||
return $this->getLatitude() && $this->getLongitude();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user