Guard added for ArcGIS api key; ArcGIS issues in LocationController and Geocoder fixed
This commit is contained in:
parent
07399d7d45
commit
5563826a08
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Services\Location\Geocoder;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class LocationController extends Controller
|
||||
{
|
||||
|
||||
@ -4,11 +4,14 @@ namespace App\Services\Location;
|
||||
|
||||
use \App\Models\User;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Geocoder
|
||||
{
|
||||
private bool $missingKeyWarned = false;
|
||||
|
||||
public function __construct(private array $cfg = [])
|
||||
{
|
||||
$this->cfg = config("services.geocoding");
|
||||
@ -65,6 +68,31 @@ class Geocoder
|
||||
return rtrim($this->cfg["arcgis"]["endpoint"], "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* fetch arcgis api key (log once if missing)
|
||||
*/
|
||||
private function arcgisKey(): ?string
|
||||
{
|
||||
$key = $this->cfg['arcgis']['api_key'] ?? null;
|
||||
|
||||
if (!$key) {
|
||||
$this->warnMissingKey();
|
||||
return null;
|
||||
}
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
private function warnMissingKey(): void
|
||||
{
|
||||
if ($this->missingKeyWarned) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->missingKeyWarned = true;
|
||||
Log::warning('arcgis api key missing; geocoding disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* pull a bias from the user (zip -> centroid) and cache it
|
||||
*/
|
||||
@ -85,8 +113,13 @@ class Geocoder
|
||||
return null;
|
||||
}
|
||||
|
||||
$key = $this->arcgisKey();
|
||||
if (!$key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$cacheKey = "geo:bias:zip:{$zip}";
|
||||
$bias = Cache::remember($cacheKey, now()->addDays(7), function () use ($zip) {
|
||||
$bias = Cache::remember($cacheKey, now()->addDays(7), function () use ($zip, $key) {
|
||||
$a = $this->cfg['arcgis'];
|
||||
|
||||
$params = [
|
||||
@ -94,7 +127,7 @@ class Geocoder
|
||||
'category' => 'Postal',
|
||||
'maxLocations' => 1,
|
||||
'f' => 'pjson',
|
||||
'token' => $a['api_key'],
|
||||
'token' => $key,
|
||||
'countryCode' => $a['country_code'] ?? null,
|
||||
];
|
||||
|
||||
@ -139,17 +172,25 @@ class Geocoder
|
||||
private function forwardArcgis(string $query, ?array $bias): ?array
|
||||
{
|
||||
$a = $this->cfg['arcgis'];
|
||||
$key = $this->arcgisKey();
|
||||
if (!$key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$params = [
|
||||
'singleLine' => $query,
|
||||
'outFields' => $a['out_fields'] ?? '*',
|
||||
'maxLocations' => (int)($a['max_results'] ?? 5),
|
||||
'f' => 'pjson',
|
||||
'token' => $a['api_key'],
|
||||
'token' => $key,
|
||||
'category' => $a['categories'] ?? 'POI,Address',
|
||||
'countryCode' => $a['country_code'] ?? null,
|
||||
];
|
||||
|
||||
if (!empty($a['store'])) {
|
||||
$params['forStorage'] = 'true';
|
||||
}
|
||||
|
||||
if ($bias && $bias['lat'] && $bias['lon']) {
|
||||
$params['location'] = $bias['lon'].','.$bias['lat'];
|
||||
if (!empty($bias['radius_km'])) {
|
||||
@ -181,12 +222,21 @@ class Geocoder
|
||||
private function reverseArcgis(float $lat, float $lon): ?array
|
||||
{
|
||||
$a = $this->cfg['arcgis'];
|
||||
$key = $this->arcgisKey();
|
||||
if (!$key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$params = [
|
||||
'location' => "{$lon},{$lat}",
|
||||
'f' => 'pjson',
|
||||
'token' => $a['api_key'],
|
||||
'token' => $key,
|
||||
];
|
||||
|
||||
if (!empty($a['store'])) {
|
||||
$params['forStorage'] = 'true';
|
||||
}
|
||||
|
||||
$res = $this->http()->get($this->arcgisBase().'/reverseGeocode', $params);
|
||||
if (!$res->ok()) {
|
||||
Log::warning('arcgis reverse geocode failed', ['status' => $res->status()]);
|
||||
@ -247,8 +297,10 @@ class Geocoder
|
||||
return [];
|
||||
}
|
||||
|
||||
$bias = $this->biasForUser($user);
|
||||
|
||||
return match ($provider) {
|
||||
"arcgis" => $this->arcgisSuggestions($query, $limit),
|
||||
"arcgis" => $this->arcgisSuggestions($query, $limit, $bias),
|
||||
default => [],
|
||||
};
|
||||
}
|
||||
@ -256,17 +308,34 @@ class Geocoder
|
||||
/**
|
||||
* get the suggestions from arcgis
|
||||
*/
|
||||
private function arcgisSuggestions(string $query, int $limit): array
|
||||
private function arcgisSuggestions(string $query, int $limit, ?array $bias = null): array
|
||||
{
|
||||
$key = $this->arcgisKey();
|
||||
if (!$key) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$params = [
|
||||
"singleLine" => $query,
|
||||
"outFields" => $this->cfg["arcgis"]["out_fields"] ?? "*",
|
||||
"maxLocations" => $limit,
|
||||
// you can bias results with 'countryCode' or 'location' here if desired
|
||||
"category" => $this->cfg["arcgis"]["categories"] ?? "POI,Address",
|
||||
"countryCode" => $this->cfg["arcgis"]["country_code"] ?? null,
|
||||
"f" => "pjson",
|
||||
"token" => $this->cfg["arcgis"]["api_key"],
|
||||
"token" => $key,
|
||||
];
|
||||
|
||||
if ($bias && $bias['lat'] && $bias['lon']) {
|
||||
$params['location'] = $bias['lon'] . ',' . $bias['lat'];
|
||||
if (!empty($bias['radius_km'])) {
|
||||
$params['searchExtent'] = $this->bboxFromBias(
|
||||
(float) $bias['lat'],
|
||||
(float) $bias['lon'],
|
||||
(float) $bias['radius_km']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->cfg["arcgis"]["store"])) {
|
||||
$params["forStorage"] = "true";
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user