Intégration fonctionnalites V1

This commit is contained in:
bastien
2026-07-04 22:30:18 +02:00
parent 55a558b536
commit 10ee859602
54 changed files with 4802 additions and 1018 deletions
+112
View File
@@ -0,0 +1,112 @@
<?php
namespace App\Services;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
class GeocodingService
{
/**
* @return array<int, array<string, mixed>>
*/
public function search(string $query): array
{
$query = trim($query);
if (strlen($query) < 3) {
return [];
}
try {
$response = $this->client()->get(config('services.nominatim.url').'/search', [
'q' => $query,
'format' => 'json',
'addressdetails' => 1,
'limit' => 5,
'countrycodes' => 'fr',
]);
} catch (ConnectionException|RequestException $exception) {
Log::warning('Geocoding search failed.', [
'query' => $query,
'message' => $exception->getMessage(),
]);
return [];
}
if (! $response->successful()) {
return [];
}
return collect($response->json())
->map(fn (array $item) => $this->formatResult($item))
->filter(fn (array $item) => $item['address'] !== '')
->values()
->all();
}
/**
* @return array{latitude: float, longitude: float}|null
*/
public function geocode(string $address, ?string $city = null, ?string $zipCode = null): ?array
{
$query = collect([$address, $zipCode, $city, 'France'])
->filter(fn (?string $part) => $part !== null && trim($part) !== '')
->implode(', ');
$results = $this->search($query);
if ($results === [] || $results[0]['latitude'] === null || $results[0]['longitude'] === null) {
return null;
}
return [
'latitude' => $results[0]['latitude'],
'longitude' => $results[0]['longitude'],
];
}
private function client(): PendingRequest
{
return Http::withHeaders([
'User-Agent' => config('services.nominatim.user_agent'),
'Accept-Language' => 'fr',
])
->withOptions([
'verify' => (bool) config('services.nominatim.verify_ssl', true),
])
->timeout(8)
->connectTimeout(4);
}
/**
* @param array<string, mixed> $item
* @return array<string, mixed>
*/
private function formatResult(array $item): array
{
$addressParts = $item['address'] ?? [];
$street = trim(($addressParts['house_number'] ?? '').' '.($addressParts['road'] ?? ''));
if ($street === '') {
$street = trim((string) ($item['name'] ?? ''));
}
return [
'label' => (string) ($item['display_name'] ?? $street),
'address' => $street,
'city' => $addressParts['city']
?? $addressParts['town']
?? $addressParts['village']
?? $addressParts['municipality']
?? '',
'zip_code' => (string) ($addressParts['postcode'] ?? ''),
'latitude' => isset($item['lat']) ? (float) $item['lat'] : null,
'longitude' => isset($item['lon']) ? (float) $item['lon'] : null,
];
}
}