mirror of
https://forge.chapril.org/tykayn/osm-commerces
synced 2025-10-09 17:02:46 +02:00
ajout api controller, failsafe sur js bubble
This commit is contained in:
parent
adf9daa117
commit
884c190ee5
3 changed files with 469 additions and 203 deletions
201
src/Controller/ApiController.php
Normal file
201
src/Controller/ApiController.php
Normal file
|
@ -0,0 +1,201 @@
|
|||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Stats;
|
||||
use App\Repository\StatsRepository;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpFoundation\StreamedResponse;
|
||||
|
||||
class ApiController extends AbstractController
|
||||
{
|
||||
#[Route('/api/v1/stats_geojson', name: 'api_stats_geojson', methods: ['GET'])]
|
||||
public function statsGeojson(StatsRepository $statsRepository): JsonResponse
|
||||
{
|
||||
$statsList = $statsRepository->findAll();
|
||||
$features = [];
|
||||
foreach ($statsList as $stats) {
|
||||
// Calcul du barycentre des commerces de la zone
|
||||
$lat = null;
|
||||
$lon = null;
|
||||
$places = $stats->getPlaces();
|
||||
$count = 0;
|
||||
$sumLat = 0;
|
||||
$sumLon = 0;
|
||||
foreach ($places as $place) {
|
||||
if ($place->getLat() && $place->getLon()) {
|
||||
$sumLat += $place->getLat();
|
||||
$sumLon += $place->getLon();
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
if ($count > 0) {
|
||||
$lat = $sumLat / $count;
|
||||
$lon = $sumLon / $count;
|
||||
}
|
||||
$feature = [
|
||||
'type' => 'Feature',
|
||||
'geometry' => $lat && $lon ? [
|
||||
'type' => 'Point',
|
||||
'coordinates' => [$lon, $lat],
|
||||
] : null,
|
||||
'properties' => [
|
||||
'id' => $stats->getId(),
|
||||
'name' => $stats->getName(),
|
||||
'zone' => $stats->getZone(),
|
||||
'completion_percent' => $stats->getCompletionPercent(),
|
||||
'places_count' => $stats->getPlacesCount(),
|
||||
'avec_horaires' => $stats->getAvecHoraires(),
|
||||
'avec_adresse' => $stats->getAvecAdresse(),
|
||||
'avec_site' => $stats->getAvecSite(),
|
||||
'avec_accessibilite' => $stats->getAvecAccessibilite(),
|
||||
'avec_note' => $stats->getAvecNote(),
|
||||
'population' => $stats->getPopulation(),
|
||||
'siren' => $stats->getSiren(),
|
||||
'codeEpci' => $stats->getCodeEpci(),
|
||||
'codesPostaux' => $stats->getCodesPostaux(),
|
||||
'date_created' => $stats->getDateCreated() ? $stats->getDateCreated()->format('c') : null,
|
||||
'date_modified' => $stats->getDateModified() ? $stats->getDateModified()->format('c') : null,
|
||||
],
|
||||
];
|
||||
$features[] = $feature;
|
||||
}
|
||||
$geojson = [
|
||||
'type' => 'FeatureCollection',
|
||||
'features' => $features,
|
||||
'meta' => [
|
||||
'generated_at' => (new \DateTime())->format('c'),
|
||||
'source' => 'https://osm-commerces.cipherbliss.com/api/v1/stats_geojson'
|
||||
]
|
||||
];
|
||||
return new JsonResponse($geojson, Response::HTTP_OK, [
|
||||
'Content-Type' => 'application/geo+json'
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/api/v1/stats/{insee}', name: 'api_stats_by_insee', methods: ['GET'])]
|
||||
public function statsByInsee(StatsRepository $statsRepository, string $insee): JsonResponse
|
||||
{
|
||||
$stats = $statsRepository->findOneBy(['zone' => $insee]);
|
||||
if (!$stats) {
|
||||
return new JsonResponse(['error' => 'Zone non trouvée'], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
$data = [
|
||||
'id' => $stats->getId(),
|
||||
'name' => $stats->getName(),
|
||||
'zone' => $stats->getZone(),
|
||||
'completion_percent' => $stats->getCompletionPercent(),
|
||||
'places_count' => $stats->getPlacesCount(),
|
||||
'avec_horaires' => $stats->getAvecHoraires(),
|
||||
'avec_adresse' => $stats->getAvecAdresse(),
|
||||
'avec_site' => $stats->getAvecSite(),
|
||||
'avec_accessibilite' => $stats->getAvecAccessibilite(),
|
||||
'avec_note' => $stats->getAvecNote(),
|
||||
'population' => $stats->getPopulation(),
|
||||
'siren' => $stats->getSiren(),
|
||||
'codeEpci' => $stats->getCodeEpci(),
|
||||
'codesPostaux' => $stats->getCodesPostaux(),
|
||||
'date_created' => $stats->getDateCreated() ? $stats->getDateCreated()->format('c') : null,
|
||||
'date_modified' => $stats->getDateModified() ? $stats->getDateModified()->format('c') : null,
|
||||
];
|
||||
return new JsonResponse($data, Response::HTTP_OK);
|
||||
}
|
||||
|
||||
#[Route('/api/v1/stats/{insee}/places', name: 'api_stats_places_by_insee', methods: ['GET'])]
|
||||
public function statsPlacesByInsee(StatsRepository $statsRepository, string $insee): JsonResponse
|
||||
{
|
||||
$stats = $statsRepository->findOneBy(['zone' => $insee]);
|
||||
if (!$stats) {
|
||||
return new JsonResponse(['error' => 'Zone non trouvée'], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
$features = [];
|
||||
foreach ($stats->getPlaces() as $place) {
|
||||
$lat = $place->getLat();
|
||||
$lon = $place->getLon();
|
||||
$feature = [
|
||||
'type' => 'Feature',
|
||||
'geometry' => ($lat && $lon) ? [
|
||||
'type' => 'Point',
|
||||
'coordinates' => [$lon, $lat],
|
||||
] : null,
|
||||
'properties' => [
|
||||
'id' => $place->getId(),
|
||||
'name' => $place->getName(),
|
||||
'main_tag' => $place->getMainTag(),
|
||||
'osmId' => $place->getOsmId(),
|
||||
'email' => $place->getEmail(),
|
||||
'note' => $place->getNote(),
|
||||
'zip_code' => $place->getZipCode(),
|
||||
'siret' => $place->getSiret(),
|
||||
'has_opening_hours' => $place->hasOpeningHours(),
|
||||
'has_address' => $place->hasAddress(),
|
||||
'has_website' => $place->hasWebsite(),
|
||||
'has_wheelchair' => $place->hasWheelchair(),
|
||||
'has_note' => $place->hasNote(),
|
||||
'completion_percent' => $place->getCompletionPercentage(),
|
||||
],
|
||||
];
|
||||
$features[] = $feature;
|
||||
}
|
||||
$geojson = [
|
||||
'type' => 'FeatureCollection',
|
||||
'features' => $features,
|
||||
'meta' => [
|
||||
'generated_at' => (new \DateTime())->format('c'),
|
||||
'source' => 'https://osm-commerces.cipherbliss.com/api/v1/stats/by_insee/' . $insee . '/places'
|
||||
]
|
||||
];
|
||||
return new JsonResponse($geojson, Response::HTTP_OK, [
|
||||
'Content-Type' => 'application/geo+json'
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/api/v1/stats/by_insee/{insee}/places.csv', name: 'api_stats_places_csv_by_insee', methods: ['GET'])]
|
||||
public function statsPlacesCsvByInsee(StatsRepository $statsRepository, string $insee): StreamedResponse
|
||||
{
|
||||
$stats = $statsRepository->findOneBy(['zone' => $insee]);
|
||||
if (!$stats) {
|
||||
$response = new StreamedResponse();
|
||||
$response->setCallback(function() {
|
||||
echo 'error\nZone non trouvée';
|
||||
});
|
||||
$response->headers->set('Content-Type', 'text/csv');
|
||||
$response->setStatusCode(Response::HTTP_NOT_FOUND);
|
||||
return $response;
|
||||
}
|
||||
$response = new StreamedResponse(function() use ($stats) {
|
||||
$handle = fopen('php://output', 'w');
|
||||
// En-têtes CSV
|
||||
fputcsv($handle, [
|
||||
'id', 'name', 'main_tag', 'osmId', 'email', 'note', 'zip_code', 'siret', 'lat', 'lon', 'has_opening_hours', 'has_address', 'has_website', 'has_wheelchair', 'has_note'
|
||||
]);
|
||||
foreach ($stats->getPlaces() as $place) {
|
||||
fputcsv($handle, [
|
||||
$place->getId(),
|
||||
$place->getName(),
|
||||
$place->getMainTag(),
|
||||
$place->getOsmId(),
|
||||
$place->getEmail(),
|
||||
$place->getNote(),
|
||||
$place->getZipCode(),
|
||||
$place->getSiret(),
|
||||
$place->getLat(),
|
||||
$place->getLon(),
|
||||
$place->hasOpeningHours(),
|
||||
$place->hasAddress(),
|
||||
$place->hasWebsite(),
|
||||
$place->hasWheelchair(),
|
||||
$place->hasNote(),
|
||||
$place->getCompletionPercentage(),
|
||||
]);
|
||||
}
|
||||
fclose($handle);
|
||||
});
|
||||
$response->headers->set('Content-Type', 'text/csv');
|
||||
$response->headers->set('Content-Disposition', 'attachment; filename="places_'.$insee.'.csv"');
|
||||
return $response;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue