mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-18 16:24:24 +00:00
93 lines
2.7 KiB
PHP
93 lines
2.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/*
|
|
* Chill is a software for social workers
|
|
*
|
|
* For the full copyright and license information, please view
|
|
* the LICENSE file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Chill\MainBundle\Service\Import;
|
|
|
|
use League\Csv\Reader;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
|
|
|
/**
|
|
* Load French's postal codes from opendata.
|
|
*
|
|
* Currently, the source is datanova / la poste:
|
|
* https://datanova.legroupe.laposte.fr/explore/dataset/laposte_hexasmal/information/
|
|
*/
|
|
class PostalCodeFRFromOpenData
|
|
{
|
|
private const CSV = 'https://datanova.laposte.fr/data-fair/api/v1/datasets/laposte-hexasmal/data-files/019HexaSmal.csv';
|
|
|
|
public function __construct(private readonly PostalCodeBaseImporter $baseImporter, private readonly HttpClientInterface $client, private readonly LoggerInterface $logger)
|
|
{
|
|
}
|
|
|
|
public function import(): void
|
|
{
|
|
$response = $this->client->request('GET', self::CSV);
|
|
|
|
if (200 !== $response->getStatusCode()) {
|
|
throw new \RuntimeException('could not download CSV');
|
|
}
|
|
|
|
$tmpfile = tmpfile();
|
|
|
|
if (false === $tmpfile) {
|
|
throw new \RuntimeException('could not create temporary file');
|
|
}
|
|
|
|
foreach ($this->client->stream($response) as $chunk) {
|
|
fwrite($tmpfile, $chunk->getContent());
|
|
}
|
|
|
|
fseek($tmpfile, 0);
|
|
|
|
$csv = Reader::createFromStream($tmpfile);
|
|
$csv->setDelimiter(';');
|
|
$csv->setHeaderOffset(0);
|
|
|
|
foreach ($csv as $offset => $record) {
|
|
$this->handleRecord($record);
|
|
}
|
|
|
|
$this->baseImporter->finalize();
|
|
fclose($tmpfile);
|
|
|
|
$this->logger->info(self::class.' postal code fetched', ['offset' => $offset ?? 0]);
|
|
}
|
|
|
|
private function handleRecord(array $record): void
|
|
{
|
|
if ('' !== trim($record['coordonnees_geographiques'] ?? $record['coordonnees_gps'])) {
|
|
[$lat, $lon] = array_map(static fn ($el) => (float) trim($el), explode(',', $record['coordonnees_geographiques'] ?? $record['coordonnees_gps']));
|
|
} else {
|
|
$lat = $lon = 0.0;
|
|
}
|
|
|
|
$ref = trim((string) $record['Code_commune_INSEE']);
|
|
|
|
if (str_starts_with($ref, '987')) {
|
|
// some differences in French Polynesia
|
|
$ref .= '.'.trim((string) $record['Libellé_d_acheminement']);
|
|
}
|
|
|
|
$this->baseImporter->importCode(
|
|
'FR',
|
|
trim((string) $record['Libellé_d_acheminement']),
|
|
trim((string) $record['Code_postal']),
|
|
$ref,
|
|
'INSEE',
|
|
$lat,
|
|
$lon,
|
|
4326
|
|
);
|
|
}
|
|
}
|