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

Google Geolocation Bundle Laravel Package

dreadlokeur/google-geolocation-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require buzz:buzz
    composer require dreadlokeur/google-geolocation-bundle
    

    (Note: The original README uses Git submodules, but Composer is preferred for modern Laravel/Symfony projects.)

  2. Register the Bundle: In config/bundles.php (Symfony) or config/app.php (Laravel via Symfony bridge):

    return [
        // ...
        Google\GeolocationBundle\GoogleGeolocationBundle::class => ['all' => true],
    ];
    
  3. Configuration: Publish the bundle config:

    php artisan config:publish google-geolocation-bundle
    

    Update config/packages/google_geolocation.yaml:

    google_geolocation:
        api_key: "YOUR_GOOGLE_API_KEY"
        base_url: "https://maps.googleapis.com/maps/api/geocode/json"
    
  4. First Use Case: Geocode an address in a controller:

    use Google\GeolocationBundle\Service\Geocoder;
    
    public function geocodeAddress(Geocoder $geocoder)
    {
        $result = $geocoder->geocode('1600 Amphitheatre Parkway, Mountain View, CA');
        return response()->json($result);
    }
    

Implementation Patterns

Core Workflows

  1. Geocoding Addresses:

    $geocoder = $this->container->get('google_geolocation.geocoder');
    $response = $geocoder->geocode('123 Main St, Anytown, USA');
    
    • Returns structured data (e.g., address_components, geometry).
  2. Reverse Geocoding:

    $reverseGeocoder = $this->container->get('google_geolocation.reverse_geocoder');
    $location = $reverseGeocoder->reverseGeocode(37.422, -122.084);
    
  3. Batch Processing: Use Laravel’s collect() to process multiple addresses:

    $addresses = ['addr1', 'addr2', 'addr3'];
    $results = collect($addresses)->map(fn($addr) => $geocoder->geocode($addr));
    

Integration Tips

  • Caching Responses: Cache API responses to reduce calls (e.g., using Laravel’s Cache facade):

    $cacheKey = 'geocode_' . md5($address);
    return Cache::remember($cacheKey, now()->addHours(1), function() use ($geocoder, $address) {
        return $geocoder->geocode($address);
    });
    
  • Error Handling: Wrap API calls in a try-catch for Google\GeolocationBundle\Exception\GeocodingException:

    try {
        $result = $geocoder->geocode($address);
    } catch (GeocodingException $e) {
        Log::error('Geocoding failed: ' . $e->getMessage());
        return response()->json(['error' => 'Geocoding unavailable'], 500);
    }
    
  • Laravel Service Providers: Bind the service manually in AppServiceProvider:

    $this->app->bind('google_geolocation.geocoder', function ($app) {
        return new \Google\GeolocationBundle\Service\Geocoder(
            $app['config']['google_geolocation.api_key']
        );
    });
    

Gotchas and Tips

Pitfalls

  1. API Key Restrictions:

    • Google may block requests if the API key is used excessively or from unexpected referrers.
    • Fix: Restrict the key in the Google Cloud Console to your domain.
  2. Rate Limits:

    • Free tier allows $200/month of usage (~40,000 requests/day).
    • Tip: Implement exponential backoff for retries:
      $attempts = 0;
      while ($attempts < 3) {
          try {
              return $geocoder->geocode($address);
          } catch (GeocodingException $e) {
              $attempts++;
              sleep(2 ** $attempts); // Exponential delay
          }
      }
      
  3. Deprecated Buzz Library:

    • The bundle relies on Buzz, which is unmaintained. Use GuzzleHttp instead (Laravel’s default):
      // Replace Buzz with Guzzle in a custom service:
      $client = new \GuzzleHttp\Client();
      $response = $client->get($url, ['query' => ['key' => $apiKey]]);
      
  4. Symfony2 Legacy:

    • The bundle is designed for Symfony2, so Laravel integration requires:
      • Service container adjustments (e.g., app() helper vs. DI container).
      • Event dispatching may not align with Laravel’s events.

Debugging

  • Enable Debug Mode: Set google_geolocation.debug: true in config to log raw API responses:

    google_geolocation:
        debug: true
    
  • Validate API Responses: Google’s API returns a status field (e.g., OK, ZERO_RESULTS). Check:

    if ($result['status'] !== 'OK') {
        throw new \RuntimeException('Geocoding failed: ' . $result['status']);
    }
    

Extension Points

  1. Custom Response Handling: Extend the Geocoder service to transform responses:

    class CustomGeocoder extends \Google\GeolocationBundle\Service\Geocoder
    {
        public function geocode($address)
        {
            $result = parent::geocode($address);
            return $this->formatResult($result);
        }
    
        protected function formatResult($result)
        {
            return [
                'formatted_address' => $result['results'][0]['formatted_address'],
                'latitude' => $result['results'][0]['geometry']['location']['lat'],
                'longitude' => $result['results'][0]['geometry']['location']['lng'],
            ];
        }
    }
    
  2. Add Proximity Search: Use the nearby_search endpoint (requires extending the bundle):

    // Example: Find places near a coordinate
    $url = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json';
    $params = [
        'location' => '37.422,-122.084',
        'radius' => '1000',
        'key' => $apiKey,
    ];
    
  3. Laravel Scout Integration: Use geocoded data with Laravel Scout for location-aware search:

    // In a model using Scout:
    public function toSearchableArray()
    {
        return [
            'address' => $this->address,
            'lat' => $this->latitude,
            'lng' => $this->longitude,
        ];
    }
    
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.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
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