geocoder-php/pickpoint-provider
PickPoint provider for the PHP Geocoder library. Adds support for geocoding through the PickPoint API, returning normalized address/location results and integrating with Geocoder’s standard provider interface for easy swapping in existing apps.
Install the Package
composer require geocoder-php/pickpoint-provider
Ensure your composer.json requires geocoder-php/geocoder:^5.0 (or latest stable).
Configure Laravel Service Provider
Register the provider in config/app.php under providers:
Geocoder\Provider\PickPoint\PickPointProvider::class,
Set Up Geocoder Client
In a service provider (e.g., AppServiceProvider):
use Geocoder\Geocoder;
use Geocoder\Provider\PickPoint\PickPointProvider;
public function register()
{
$this->app->singleton(Geocoder::class, function ($app) {
$client = new \GuzzleHttp\Client(); // PSR-18 compliant
$geocoder = new Geocoder();
$geocoder->registerProvider(new PickPointProvider($client, 'YOUR_PICKPOINT_API_KEY'));
return $geocoder;
});
}
First Use Case: Geocoding an Address
$geocoder = app(Geocoder::class);
$results = $geocoder->geocodeQuery('123 Main St, Anytown, USA');
foreach ($results as $result) {
echo $result->getCoordinates(); // Output: [lat, lng]
}
Reverse Geocoding (Coordinates → Address)
$geocoder->reverseQuery([40.7128, -74.0060]); // NYC coordinates
Batch Processing
Use Laravel’s collect() to process multiple addresses:
$addresses = ['addr1', 'addr2', 'addr3'];
$geocoded = collect($addresses)->map(fn($addr) => $geocoder->geocodeQuery($addr));
Integration with Laravel Models
Add a geocode() accessor to a model (e.g., Order):
public function getGeocodeAttribute()
{
return $this->geocoder->geocodeQuery($this->address)->first()?->getCoordinates();
}
Caching Responses Cache geocoding results for 1 hour (adjust TTL as needed):
$cacheKey = 'geocode_' . md5($address);
return Cache::remember($cacheKey, now()->addHours(1), function() use ($geocoder, $address) {
return $geocoder->geocodeQuery($address);
});
$geocoder->registerProvider(new \Geocoder\Provider\GoogleMapsProvider('GOOGLE_API_KEY'));
throttle middleware for API calls:
Route::middleware(['throttle:10,1'])->group(function () {
// Geocoding routes
});
API Key Management
.env:
PICKPOINT_API_KEY=your_key_here
config/geocoder.php:
'providers' => [
'pickpoint' => [
'key' => env('PICKPOINT_API_KEY'),
'validate' => true, // Enable validation
],
],
Rate Limits
use Symfony\Component\HttpClient\RetryStrategy;
$client = \Http::withOptions([
'retry' => RetryStrategy::fromOptions([
'max_retries' => 3,
'delay' => 1000, // 1 second
]),
]);
Data Format Quirks
[lng, lat] order. Normalize:
$coords = $result->getCoordinates();
$normalized = [$coords[1], $coords[0]]; // Swap if needed
Error Handling
try {
$geocoder->geocodeQuery($address);
} catch (\Geocoder\Exception\UnsupportedProviderException $e) {
Log::error("PickPoint API key invalid: " . $e->getMessage());
}
class CustomPickPointProvider extends \Geocoder\Provider\PickPoint\PickPointProvider
{
public function geocode($query)
{
$response = $this->httpClient->get($this->url, [
'query' => ['q' => $query, 'key' => $this->apiKey],
]);
Log::debug('PickPoint API Response', ['body' => $response->getBody()]);
return parent::geocode($query);
}
}
tinker for Testing:
php artisan tinker
>>> $geocoder->geocodeQuery('1600 Pennsylvania Ave');
Custom Response Parsing
Override parse() in a custom provider to handle non-standard responses:
protected function parse($data)
{
return collect($data['results'])->map(function ($item) {
return new Collection([
'coordinates' => [$item['lat'], $item['lng']],
'formatted' => $item['formatted_address'],
]);
});
}
Add Metadata Attach custom metadata to results:
$result->setExtraInfo(['pickpoint_id' => $item['id']]);
Async Processing Use Laravel Queues for background geocoding:
GeocodeJob::dispatch($address)->onQueue('geocoding');
class GeocodeJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable;
public function handle()
{
$geocoder->geocodeQuery($this->address);
}
}
How can I help you explore Laravel packages today?