Installation:
composer require ano/google-maps-bundle
Register the bundle in config/bundles.php (Symfony 4.4+):
return [
// ...
Ano\Bundle\GoogleMapsBundle\AnoGoogleMapsBundle::class => ['all' => true],
];
Configuration:
Add your Google Maps API key to config/packages/ano_google_maps.yaml:
ano_google_maps:
api_key: 'YOUR_GOOGLE_MAPS_API_KEY'
First Use Case: Query geocoding in a controller:
use Ano\Bundle\GoogleMapsBundle\Service\GeocodeAPIQuery;
public function geocodeAddress(Request $request)
{
$query = new GeocodeAPIQuery([
'address' => $request->input('address'),
'sensor' => 'false',
]);
$result = $query->getResult();
return response()->json([
'formatted_address' => $result->getAddress()->getFormattedAddress(),
'coordinates' => [
'lat' => $result->getGeometry()->getLatitude(),
'lng' => $result->getGeometry()->getLongitude(),
],
]);
}
Geocoding Addresses:
GeocodeAPIQuery for address-to-coordinates conversion.$address = $result->getAddress();
$coordinates = $result->getGeometry();
Form Validation:
Address constraint in Symfony forms:
$builder->add('address', TextType::class, [
'constraints' => [
new Address([
'invalidAddressMessage' => 'Invalid address format.',
'notSpecificEnoughMessage' => 'Address too vague.',
]),
],
]);
Service Integration:
GeocodeAPIQuery via dependency injection:
use Ano\Bundle\GoogleMapsBundle\Service\GeocodeAPIQuery;
class MyService {
private $geocodeQuery;
public function __construct(GeocodeAPIQuery $geocodeQuery) {
$this->geocodeQuery = $geocodeQuery;
}
}
Batch Processing: Loop through addresses and cache results:
$addresses = ['addr1', 'addr2'];
$results = collect($addresses)->map(function ($addr) {
return (new GeocodeAPIQuery(['address' => $addr]))->getResult();
})->toArray();
Reverse Geocoding:
Extend the bundle by implementing ReverseGeocodeAPIQuery (see "Extension Points").
Event-Driven:
Dispatch events after geocoding (e.g., GeocodeSuccessEvent):
$result = $query->getResult();
$this->dispatcher->dispatch(new GeocodeSuccessEvent($result));
API Key Management:
# .env
GOOGLE_MAPS_API_KEY=your_key_here
Update config:
ano_google_maps:
api_key: '%env(GOOGLE_MAPS_API_KEY)%'
Rate Limits:
Deprecation:
sensor parameter is deprecated. Omit it or set to true:
$query = new GeocodeAPIQuery(['address' => '...', 'sensor' => 'true']);
Partial Results:
if (!$result->getAddress()->isComplete()) {
// Handle incomplete data
}
Enable Debug Mode:
Set debug: true in config to log API responses:
ano_google_maps:
api_key: '%env(GOOGLE_MAPS_API_KEY)%'
debug: true
Error Handling:
Catch GoogleMapsException for API errors:
try {
$result = $query->getResult();
} catch (GoogleMapsException $e) {
Log::error('Geocoding failed: ' . $e->getMessage());
}
Add New Services:
Extend the bundle by implementing additional API wrappers (e.g., DirectionsAPIQuery):
namespace App\Service;
use Ano\Bundle\GoogleMapsBundle\Service\AbstractGoogleMapsQuery;
class DirectionsAPIQuery extends AbstractGoogleMapsQuery {
// Implement Directions API logic
}
Custom Validators: Override default validator messages or add new constraints by extending:
namespace App\Validator\Constraints;
use Ano\Bundle\GoogleMapsBundle\Validator\Constraints\Address;
class CustomAddress extends Address {
public function validatedBy() { return 'app.address_validator'; }
}
Response Transformation:
Decorate the GeocodeAPIQuery service to modify responses:
$container->set('ano_google_maps.geocode', function ($c) {
$original = $c->get('ano_google_maps.geocode');
return new CustomGeocodeDecorator($original);
});
Caching: Cache results for 30 minutes (Google’s recommended TTL):
$cacheKey = 'geocode_' . md5($address);
$result = Cache::remember($cacheKey, 1800, function () use ($query) {
return $query->getResult();
});
Async Processing: Use Symfony Messenger to offload geocoding to a queue:
$message = new GeocodeMessage($address);
$this->messageBus->dispatch($message);
How can I help you explore Laravel packages today?