Vlastní poskytovatelia
Poskytovateľa ako closure zaregistrujete za behu — napríklad v metóde boot() service providera — a jeho meno pridáte do pipeline:
use RoundlyConsulting\Geolocation\Facades\Geolocation;
// e.g. in a service provider's boot()
Geolocation::extend('my_provider', fn () => new MyProvider());// config/geolocation.php
'pipeline' => ['maxmind_database', 'my_provider', 'ipinfo', 'default'],Implementácia poskytovateľa polohy
Implementujte GeolocationProvider. Vráťte Location, alebo null, ak má pokračovať ďalší poskytovateľ — prázdna Location ($location->isEmpty()) odovzdá slovo tiež. Výnimka, ktorú váš poskytovateľ vyhodí, vyhľadávanie ukončí:
use RoundlyConsulting\Geolocation\DataTransferObjects\GeolocationQuery;
use RoundlyConsulting\Geolocation\DataTransferObjects\Location;
use RoundlyConsulting\Geolocation\Enum\GeolocationType;
use RoundlyConsulting\Geolocation\GeolocationProvider;
final class OfficeNetworkProvider implements GeolocationProvider
{
public function locate(GeolocationQuery $query): ?Location
{
if ($query->ipAddress === null || ! str_starts_with($query->ipAddress, '10.20.')) {
return null; // not ours — defer to the next provider
}
return new Location(
humanReadable: 'Example HQ, Springfield',
street: 'Main Street 1',
city: 'Springfield',
countryIsoCode: 'US',
latitude: 39.7817,
longitude: -89.6501,
type: GeolocationType::Ip,
);
}
}Namiesto extend() môžete triedu pridať do mapy providers. Poskytovatelia sa získavajú z kontajnera, takže závislosti v konštruktore sa injektujú:
// config/geolocation.php — resolved from the container, so constructor dependencies are injected
'providers' => [
// ...the bundled providers
'office' => \App\Geolocation\OfficeNetworkProvider::class,
],
'pipeline' => ['office', 'maxmind_database', 'ipinfo', 'default'],Implementácia poskytovateľa vzdialenosti
Implementujte DistanceProvider, aby trieda odpovedala na volania distance(). Trieda môže implementovať oba kontrakty, ako to robí pribalený poskytovateľ Google:
use RoundlyConsulting\Geolocation\DataTransferObjects\Distance;
use RoundlyConsulting\Geolocation\DataTransferObjects\DistanceQuery;
use RoundlyConsulting\Geolocation\DistanceProvider;
final class StraightLineProvider implements DistanceProvider
{
public function distance(DistanceQuery $query): ?Distance
{
$metres = (int) round($query->from()->distanceTo($query->to()));
return new Distance(
humanReadableDistance: round($metres / 1000, 1).' km',
distanceInMeters: $metres,
humanReadableDuration: '',
durationInSeconds: 0,
type: $query->type,
);
}
}Čítanie prepisov z volania
Hodnoty z volania prečítate cez trait HasProviderOverrides. $this->override('key') vráti hodnotu z withTimeout() alebo hodnotu určenú menu vášho poskytovateľa cez withToken() / withConfig(), a null, ak kľúč pre toto volanie nastavený nie je:
use RoundlyConsulting\Geolocation\Concerns\HasProviderOverrides;
final class MyProvider implements GeolocationProvider
{
use HasProviderOverrides;
public function locate(GeolocationQuery $query): ?Location
{
$token = $this->override('token') ?? config('services.my_geo.token');
$timeout = $this->override('timeout') ?? 5;
$region = $this->override('region'); // any key passed through withConfig()
// ...
}
}
// The provider sees withTimeout() plus the values aimed at its own name:
Geolocation::withConfig('my_provider', ['region' => 'eu'])->locateIp($ip);Limit požiadaviek pre vlastného poskytovateľa
HTTP volania posielajte cez trait InteractsWithRateLimits a budú spomalené rovnako ako pri pribalených poskytovateľoch. throttled() číta geolocation.services.{name}.rate_limits a limit má kľúč geolocation:{name}:{owner}:
use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use RoundlyConsulting\Geolocation\Concerns\InteractsWithRateLimits;
final class NominatimProvider implements GeolocationProvider
{
use InteractsWithRateLimits;
public function locate(GeolocationQuery $query): ?Location
{
if ($query->address === null) {
return null;
}
// Paced by geolocation.services.nominatim.rate_limits, keyed geolocation:nominatim:{owner}
$response = $this->throttled('nominatim', fn (): Response => Http::get(
'https://nominatim.example.com/search',
['q' => $query->address],
));
// ...map $response->json() onto a Location, or return null
}
}Potom poskytovateľovi pridajte blok rate_limits v services. Nominatim od OpenStreetMap napríklad striktne povoľuje 1 požiadavku za sekundu:
// config/geolocation.php → 'services'
'nominatim' => [
// ...your provider settings...
'rate_limits' => [
'enabled' => true,
'limit' => 1,
'per' => 'second',
'adaptive' => true,
],
],Rovnako sa zapája Google Places for Laravel: keď sú nainštalované oba balíky, cez extend() zaregistruje poskytovateľa google_places, ktorého môžete pridať do pipeline.
Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.