From ba39bd37c519b91dfb593a44a9de2a18a2fb07a3 Mon Sep 17 00:00:00 2001 From: Dimitri Gritsajuk Date: Fri, 10 May 2024 15:14:55 +0200 Subject: [PATCH] [PAP] enable geojson format for addresses list --- features/api/pap_address.feature | 6 ++++ migrations/Version20240510130946.php | 19 ++++++++++ .../Api/Pap/GetNearPointsController.php | 35 ++++++++++++++++--- src/Entity/Pap/Address.php | 10 ++++++ src/Entity/Pap/Building.php | 2 +- 5 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 migrations/Version20240510130946.php diff --git a/features/api/pap_address.feature b/features/api/pap_address.feature index 025884a2d0a..bc337aa61a2 100644 --- a/features/api/pap_address.feature +++ b/features/api/pap_address.feature @@ -56,6 +56,7 @@ Feature: [ { "number": "55", + "priority": null, "address": "Rue du Rocher", "insee_code": "75108", "postal_codes": ["75008"], @@ -86,6 +87,7 @@ Feature: }, { "number": "65", + "priority": null, "address": "Rue du Rocher", "insee_code": "75108", "postal_codes": ["75008"], @@ -112,6 +114,7 @@ Feature: }, { "number": "70", + "priority": null, "address": "Rue du Rocher", "insee_code": "75108", "postal_codes": ["75008"], @@ -138,6 +141,7 @@ Feature: }, { "number": "67", + "priority": null, "address": "Rue du Rocher", "insee_code": "75108", "postal_codes": ["75008"], @@ -184,6 +188,7 @@ Feature: "latitude": 48.880085, "longitude": 2.321696, "number": "62", + "priority": null, "postal_codes": [ "75008" ], @@ -203,6 +208,7 @@ Feature: { "uuid": "a0b9231b-9ff5-49b9-aa7a-1d28abbba32f", "number": "55", + "priority": null, "address": "Rue du Rocher", "insee_code": "75108", "postal_codes": ["75008"], diff --git a/migrations/Version20240510130946.php b/migrations/Version20240510130946.php new file mode 100644 index 00000000000..f4012d69df8 --- /dev/null +++ b/migrations/Version20240510130946.php @@ -0,0 +1,19 @@ +addSql('ALTER TABLE pap_address ADD priority SMALLINT UNSIGNED DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE pap_address DROP priority'); + } +} diff --git a/src/Controller/Api/Pap/GetNearPointsController.php b/src/Controller/Api/Pap/GetNearPointsController.php index 08ef34d13bf..ab3ae223f1d 100644 --- a/src/Controller/Api/Pap/GetNearPointsController.php +++ b/src/Controller/Api/Pap/GetNearPointsController.php @@ -2,6 +2,8 @@ namespace App\Controller\Api\Pap; +use App\Entity\Pap\Address; +use App\Entity\Pap\BuildingStatistics; use App\Repository\Pap\AddressRepository; use App\Repository\Pap\CampaignRepository; use App\Repository\Pap\VotePlaceRepository; @@ -10,16 +12,19 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; +use Symfony\Component\Serializer\Normalizer\NormalizerInterface; class GetNearPointsController extends AbstractController { private const MAX_LIMIT = 300; - #[Route(path: '/v3/pap/address/near', name: 'api_pap_get_near_addresses', methods: ['GET'])] + #[Route(path: '/v3/pap/address/near.{format}', name: 'api_pap_get_near_addresses', requirements: ['format' => 'json|geojson'], defaults: ['format' => 'json'], methods: ['GET'])] public function getAddressAction( + string $format, Request $request, AddressRepository $addressRepository, - CampaignRepository $campaignRepository + CampaignRepository $campaignRepository, + NormalizerInterface $normalizer, ): Response { if (!$request->query->has('latitude') || !$request->query->has('longitude')) { return $this->json('Some required parameters are missing. (latitude, longitude)', Response::HTTP_BAD_REQUEST); @@ -34,14 +39,36 @@ public function getAddressAction( return $this->json([], Response::HTTP_OK); } - return $this->json($addressRepository->findNear( + $addresses = $addressRepository->findNear( $activeCampaignIds, $request->query->filter('latitude', null, \FILTER_VALIDATE_FLOAT), $request->query->filter('longitude', null, \FILTER_VALIDATE_FLOAT), $latitudeDelta, $longitudeDelta, $limit > self::MAX_LIMIT ? self::MAX_LIMIT : $limit - ), Response::HTTP_OK, [], ['groups' => ['pap_address_list']]); + ); + + if ('geojson' === $format) { + $addresses = [ + 'type' => 'FeatureCollection', + 'features' => array_map(function (Address $address) use ($normalizer) { + $building = $address->getBuilding(); + /** @var BuildingStatistics $campaignStatistics */ + $campaignStatistics = $building->getCampaignStatistics(); + + return [ + 'type' => 'Feature', + 'geometry' => [ + 'type' => 'Point', + 'coordinates' => [$address->getLongitude(), $address->getLatitude()], + ], + 'properties' => $normalizer->normalize($address, context: ['groups' => ['pap_address_list']]), + ]; + }, $addresses), + ]; + } + + return $this->json($addresses, Response::HTTP_OK, [], ['groups' => ['pap_address_list']]); } #[Route(path: '/v3/pap/vote-places/near', name: 'api_pap_get_near_vote_places', methods: ['GET'])] diff --git a/src/Entity/Pap/Address.php b/src/Entity/Pap/Address.php index 391ddc92741..0b193d95b80 100644 --- a/src/Entity/Pap/Address.php +++ b/src/Entity/Pap/Address.php @@ -172,6 +172,16 @@ class Address */ public ?VotePlace $votePlace = null; + /** + * @ORM\Column(type="smallint", nullable=true, options={"unsigned": true}) + * + * @Groups({ + * "pap_address_list", + * "pap_address_read", + * }) + */ + public ?int $priority = null; + public function __construct( ?UuidInterface $uuid = null, ?string $number = null, diff --git a/src/Entity/Pap/Building.php b/src/Entity/Pap/Building.php index 3275424c9d1..65cde0fa510 100644 --- a/src/Entity/Pap/Building.php +++ b/src/Entity/Pap/Building.php @@ -183,6 +183,6 @@ public function setType(string $type): void */ public function getCampaignStatistics(): ?CampaignStatisticsInterface { - return $this->currentCampaign ? $this->findStatisticsForCampaign($this->currentCampaign) : null; + return $this->currentCampaign ? $this->findStatisticsForCampaign($this->currentCampaign) : new BuildingStatistics($this, $this->currentCampaign); } }