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.
Installation:
composer require league/geotools
Add to composer.json:
"require": {
"league/geotools": "^0.5"
}
Basic Usage:
use League\Geotools\Geotools;
use League\Geotools\Coordinate\Coordinate;
$geotools = new Geotools();
$coordinate = new Coordinate('48.8566, 2.3522'); // Paris
First Use Case: Calculate distance between two points:
$paris = new Coordinate('48.8566, 2.3522');
$london = new Coordinate('51.5074, -0.1278');
$distance = $geotools->distance($paris, $london, 'km');
echo $distance; // ~343.5 km
Coordinate Handling:
$coordinate = new Coordinate('48°49′24″N, 2°18′26″E');
$converted = $geotools->convert($coordinate);
echo $converted->toDegreesMinutesSeconds();
Batch Geocoding:
$geocoder = new \Geocoder\ProviderAggregator();
$geocoder->registerProviders([/* ... */]);
$results = $geotools->batch($geocoder)
->setCache(new \Cache\Adapter\Filesystem\FilesystemCachePool())
->geocode(['Paris', 'London'])
->parallel();
Distance Calculations:
$distance = $geotools->distance($paris, $london, 'mi', 'vincenty');
CLI Integration:
php vendor/bin/geotools distance "48.8566,2.3522" "51.5074,-0.1278" --units=km
Service Provider:
// app/Providers/GeotoolsServiceProvider.php
public function register()
{
$this->app->singleton(Geotools::class, function ($app) {
return new Geotools();
});
}
Facade:
// app/Facades/Geotools.php
public static function distance($coord1, $coord2, $units = 'm', $algorithm = 'haversine')
{
return app(Geotools::class)->distance($coord1, $coord2, $units, $algorithm);
}
Cached Geocoding:
// Use Laravel's cache
$cache = new \League\Geotools\Cache\LaravelCache();
$geotools->batch($geocoder)->setCache($cache)->geocode(['query']);
Request Handling:
public function handle($request, Closure $next)
{
$query = $request->input('query');
$results = app(Geotools::class)->batch($geocoder)->geocode([$query])->serie();
return response()->json($results);
}
Provider Limitations:
if (!$provider->supports('reverse')) {
throw new \RuntimeException('Provider does not support reverse geocoding');
}
Coordinate Normalization:
-90 to 90), longitudes wrapped (-180 to 180):
$coordinate = new Coordinate('91, 181'); // Auto-corrected to 90, -179
Batch Parallelism:
serie() for controlled execution:
$results = $geotools->batch($geocoder)->geocode($queries)->serie();
Ellipsoid Mismatches:
$coordinate = new Coordinate('48.8566, 2.3522', Ellipsoid::WGS84);
CLI for Testing:
php vendor/bin/geotools convert "48.8566,2.3522"
Cache Validation:
$cache->clear();
Provider Errors:
try {
$results = $geotools->batch($geocoder)->geocode(['invalid']);
} catch (\Geocoder\Exception\UnsupportedException $e) {
log::error($e->getMessage());
}
Custom Ellipsoids:
$customEllipsoid = Ellipsoid::createFromArray([
'name' => 'Custom',
'a' => 6371000, // Semi-major axis
'invF' => 298.25
]);
PSR-6 Cache Integration:
CacheInterface for custom storage:
class RedisCache implements CacheInterface {
public function get($key) { /* ... */ }
public function set($key, $value, $ttl = null) { /* ... */ }
public function delete($key) { /* ... */ }
}
Distance Algorithm Extensions:
Distance class:
class CustomDistance extends \League\Geotools\Distance {
public function customAlgorithm($coord1, $coord2) { /* ... */ }
}
Laravel Events:
event(new Geocoded($query, $results));
How can I help you explore Laravel packages today?