league/geotools
Geotools is a PHP geo library built on Geocoder and React. It supports batch geocoding/reverse geocoding with multiple providers, PSR-6 caching, CLI tools, coordinate conversion (DMS/UTM), and distance/bearing/point calculations.
Strengths:
Illuminate\Cache).schedule:run).Weaknesses:
geocoder/geocoder (~30MB+ dependencies), which may bloat Laravel’s vendor directory. Consider lazy-loading or conditional installation.League\Geotools\Geotools to Laravel’s container).HttpClientDiscovery) and caching backends (Redis, Memcached).parallel() → dispatch()).spatie/laravel-geotools or custom Eloquent accessors for database-backed geospatial operations.spatie/laravel-postgis) for geohash indexing or polygon containment checks.GEOADD/GEORADIUS for lightweight geolocation features.geocoder/geocoder pulls in heavy dependencies (e.g., symfony/http-client). Audit for unused providers.DB_DBL in MySQL).Mockery + Geocoder\Provider\Mock)?League\Geotools\Geotools in AppServiceProvider:
$this->app->singleton(Geotools::class, fn() => new Geotools());
GeoTools) for cleaner syntax:
use League\Geotools\Coordinate\Coordinate;
GeoTools::distance(new Coordinate([...]), new Coordinate([...]));
php artisan vendor:publish --tag=geotools-config
HttpClient for geocoder providers (avoid direct ReactPHP in routes).$geocoder = new ProviderAggregator();
$geocoder->registerProviders([new OpenStreetMap($this->httpClient)]);
GeocodeBatchJob) for async processing:
public function handle() {
$results = app(Geotools::class)
->batch($this->geocoder)
->setCache(cache())
->geocode($this->queries)
->parallel();
// Store results or dispatch follow-up jobs.
}
Phase 1: Core Integration
composer require league/geotools geocoder/geocoder
Phase 2: Caching & Batch
Phase 3: Async Workflows
parallel() → dispatch(new GeocodeBatchJob($queries))).Phase 4: Advanced Features
curl in favor of Guzzle).Geocoder\Provider\TimedGeocoder to enforce rate limits.spatie/laravel-postgis for Eloquent models:
use Spatie\Postgis\Types\Point;
$user->location = new Point($longitude, $latitude);
php artisan geotools:batch) for one-off migrations.geocoder/geocoder first, then league/geotools.geocoder/geocoder for breaking changes (e.g., provider API deprecations).composer.json for critical providers (e.g., google/maps)..env.config/caching.php to manage key expiration.GeocoderException) in a global handler:
try {
$result = GeoTools::geocode('Paris');
} catch (Ge
How can I help you explore Laravel packages today?