| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- <?php
- declare(strict_types=1);
- namespace App\Service\Utils;
- use App\ApiResources\Utils\GpsCoordinate;
- use App\Tests\Service\Utils\GpsCoordinateUtilsTest;
- use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
- use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
- use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
- use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
- use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
- use Symfony\Contracts\HttpClient\HttpClientInterface;
- /**
- * Class GpsCoordinateSearching : service aidant à la manipulation de l'API OpenStreetMap.
- */
- class GpsCoordinateUtils
- {
- private HttpClientInterface $clientOpenStreetMap;
- public function __construct(
- HttpClientInterface $openstreetmap,
- ) {
- $this->clientOpenStreetMap = $openstreetmap;
- }
- /**
- * Renvoie un tableau d'adresse existante correspondant à la recherche d'adresse demandée.
- *
- * @throws \JsonException
- * @throws ClientExceptionInterface
- * @throws RedirectionExceptionInterface
- * @throws ServerExceptionInterface
- * @throws TransportExceptionInterface
- *
- * @see GpsCoordinateUtilsTest::testSearchGpsCoordinates()
- */
- public function searchGpsCoordinates(?string $street, ?string $cp, ?string $city, ?string $country): mixed
- {
- try {
- $url = sprintf('search?addressdetails=1&format=json&limit=10&%s', $this->prepareQuery($street, $cp, $city, $country));
- $response = $this->clientOpenStreetMap->request('GET', $url)->getContent();
- } catch (\Exception $e) {
- throw new NotFoundHttpException('no_reverse_gps_coordinate', $e, 404);
- }
- return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
- }
- /**
- * Prépare la query pour l'api de recherche gps.
- */
- public function prepareQuery(?string $street, ?string $cp, ?string $city, ?string $country): string
- {
- $query = [
- $street ? sprintf('street=%s', $street) : null,
- $cp ? sprintf('postalcode=%s', $cp) : null,
- $city ? sprintf('city=%s', $city) : null,
- $country ? sprintf('country=%s', $country) : null,
- ];
- return implode('&', array_filter($query));
- }
- /**
- * Renvoi l'adresse correspondant à la latitude et longitude demandée.
- *
- * @throws ClientExceptionInterface
- * @throws RedirectionExceptionInterface
- * @throws ServerExceptionInterface
- * @throws TransportExceptionInterface
- * @throws \JsonException
- *
- * @see GpsCoordinateUtilsTest::testReverseGpsCoordinates()
- */
- public function reverseGpsCoordinates(float $latitude, float $longitude): mixed
- {
- try {
- $url = sprintf('reverse?addressdetails=1&format=json&lat=%s&lon=%s', $latitude, $longitude);
- $response = $this->clientOpenStreetMap->request('GET', $url)->getContent();
- } catch (\Exception $e) {
- throw new NotFoundHttpException('no_reverse_gps_coordinate', $e, 404);
- }
- return json_decode($response, true, 512, JSON_THROW_ON_ERROR);
- }
- /**
- * Transforme une réponse d'API en ressource GpsCoordinate.
- *
- * @param mixed[] $gpsApiResponse
- *
- * @see GpsCoordinateUtilsTest::testCreateGpsCoordinate()
- */
- public function createGpsCoordinate(array $gpsApiResponse): GpsCoordinate
- {
- if (!isset($gpsApiResponse['address']) || !is_array($gpsApiResponse['address'])) {
- throw new NotFoundHttpException('No address found for the given GPS coordinates.', null, 404);
- }
- $address = $this->transformAddress($gpsApiResponse['address']);
- $gpsCoordinate = new GpsCoordinate();
- $gpsCoordinate
- ->setLatitude((float) $gpsApiResponse['lat'])
- ->setLongitude((float) $gpsApiResponse['lon'])
- ->setCity($address['city'] ?? null)
- ->setCp($address['cp'] ?? null)
- ->setStreetAddress($address['streetAddress'] ?? null)
- ->setStreetAddressSecond($address['streetAddressSecond'] ?? null);
- return $gpsCoordinate;
- }
- /**
- * Permet de faire correspondre le bloc adresse renvoyé par l'API avec des éléments plus communs.
- *
- * @param list<string> $address
- *
- * @return array<string, string|null>
- */
- public function transformAddress(array $address): array
- {
- $addressTransformed['streetAddress'] = array_key_exists('road', $address) ? $address['road'] : (array_key_exists('hamlet', $address) ? $address['hamlet'] : null);
- $addressTransformed['streetAddressSecond'] = array_key_exists('road', $address) && array_key_exists('hamlet', $address) ? $address['hamlet'] : null;
- $addressTransformed['city'] = array_key_exists('town', $address) ? $address['town'] : (array_key_exists('village', $address) ? $address['village'] : null);
- $addressTransformed['cp'] = array_key_exists('postcode', $address) ? $address['postcode'] : null;
- return $addressTransformed;
- }
- }
|