86 lines
3.0 KiB
PHP
86 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Http;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
/**
|
|
* City-Lookup via Google Geocoding. Wenn nur ein Treffer → direkt flyTo.
|
|
* Wenn mehrere (z.B. "Linz" Österreich vs Pennsylvania) → array für User-Auswahl.
|
|
*/
|
|
class FoxCitiesController
|
|
{
|
|
public function __invoke(Request $request): JsonResponse
|
|
{
|
|
$request->validate([
|
|
'query' => 'required|string|max:120',
|
|
]);
|
|
|
|
$key = config('services.google.maps_key');
|
|
if (empty($key)) {
|
|
return response()->json(['error' => 'no_key'], 503);
|
|
}
|
|
|
|
$query = $request->string('query')->toString();
|
|
|
|
try {
|
|
$response = Http::timeout(8)->get('https://maps.googleapis.com/maps/api/geocode/json', [
|
|
'address' => $query,
|
|
'language' => 'de',
|
|
'key' => $key,
|
|
]);
|
|
|
|
if (! $response->successful()) {
|
|
return response()->json(['error' => 'api_error', 'status' => $response->status()], 502);
|
|
}
|
|
|
|
$data = $response->json();
|
|
if (($data['status'] ?? null) !== 'OK' || empty($data['results'])) {
|
|
return response()->json(['results' => []], 200);
|
|
}
|
|
|
|
// Nur Städte/Ortschaften behalten — keine POI/Adressen
|
|
$cityTypes = ['locality', 'administrative_area_level_1', 'administrative_area_level_2', 'political'];
|
|
$candidates = [];
|
|
foreach ($data['results'] as $r) {
|
|
$types = $r['types'] ?? [];
|
|
if (! array_intersect($cityTypes, $types)) {
|
|
continue;
|
|
}
|
|
$components = $r['address_components'] ?? [];
|
|
$country = '';
|
|
$region = '';
|
|
foreach ($components as $c) {
|
|
if (in_array('country', $c['types'] ?? [], true)) {
|
|
$country = $c['long_name'] ?? '';
|
|
}
|
|
if (in_array('administrative_area_level_1', $c['types'] ?? [], true)) {
|
|
$region = $c['long_name'] ?? '';
|
|
}
|
|
}
|
|
$candidates[] = [
|
|
'name' => $r['address_components'][0]['long_name'] ?? $query,
|
|
'formatted' => $r['formatted_address'] ?? '',
|
|
'country' => $country,
|
|
'region' => $region,
|
|
'lat' => $r['geometry']['location']['lat'] ?? null,
|
|
'lng' => $r['geometry']['location']['lng'] ?? null,
|
|
];
|
|
|
|
if (count($candidates) >= 5) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return response()->json(['results' => $candidates]);
|
|
} catch (\Throwable $e) {
|
|
Log::warning('Cities lookup exception', ['e' => $e->getMessage()]);
|
|
|
|
return response()->json(['error' => 'exception'], 500);
|
|
}
|
|
}
|
|
}
|