Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Pickpoint Provider Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require geocoder-php/pickpoint-provider
    

    Ensure your composer.json requires geocoder-php/geocoder:^5.0 (or latest stable).

  2. Configure Laravel Service Provider Register the provider in config/app.php under providers:

    Geocoder\Provider\PickPoint\PickPointProvider::class,
    
  3. 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;
        });
    }
    
  4. 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]
    }
    

Implementation Patterns

Core Workflows

  1. Reverse Geocoding (Coordinates → Address)

    $geocoder->reverseQuery([40.7128, -74.0060]); // NYC coordinates
    
  2. Batch Processing Use Laravel’s collect() to process multiple addresses:

    $addresses = ['addr1', 'addr2', 'addr3'];
    $geocoded = collect($addresses)->map(fn($addr) => $geocoder->geocodeQuery($addr));
    
  3. 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();
    }
    
  4. 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);
    });
    

Advanced Patterns

  • Fallback Providers: Combine with other providers (e.g., Google, OpenStreetMap) for redundancy:
    $geocoder->registerProvider(new \Geocoder\Provider\GoogleMapsProvider('GOOGLE_API_KEY'));
    
  • Rate Limiting: Use Laravel’s throttle middleware for API calls:
    Route::middleware(['throttle:10,1'])->group(function () {
        // Geocoding routes
    });
    

Gotchas and Tips

Common Pitfalls

  1. API Key Management

    • Gotcha: Hardcoding API keys in config files exposes them. Use Laravel’s .env:
      PICKPOINT_API_KEY=your_key_here
      
    • Tip: Validate the key in config/geocoder.php:
      'providers' => [
          'pickpoint' => [
              'key' => env('PICKPOINT_API_KEY'),
              'validate' => true, // Enable validation
          ],
      ],
      
  2. Rate Limits

    • Gotcha: PickPoint may throttle requests. Monitor usage via their dashboard.
    • Tip: Implement exponential backoff for retries:
      use Symfony\Component\HttpClient\RetryStrategy;
      
      $client = \Http::withOptions([
          'retry' => RetryStrategy::fromOptions([
              'max_retries' => 3,
              'delay' => 1000, // 1 second
          ]),
      ]);
      
  3. Data Format Quirks

    • Gotcha: PickPoint may return coordinates in [lng, lat] order. Normalize:
      $coords = $result->getCoordinates();
      $normalized = [$coords[1], $coords[0]]; // Swap if needed
      
  4. Error Handling

    • Gotcha: Silent failures if the API key is invalid. Explicitly check:
      try {
          $geocoder->geocodeQuery($address);
      } catch (\Geocoder\Exception\UnsupportedProviderException $e) {
          Log::error("PickPoint API key invalid: " . $e->getMessage());
      }
      

Debugging Tips

  • Log Raw Responses: Extend the provider to log API responses:
    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);
        }
    }
    
  • Use tinker for Testing:
    php artisan tinker
    >>> $geocoder->geocodeQuery('1600 Pennsylvania Ave');
    

Extension Points

  1. 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'],
            ]);
        });
    }
    
  2. Add Metadata Attach custom metadata to results:

    $result->setExtraInfo(['pickpoint_id' => $item['id']]);
    
  3. 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);
        }
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver