While working on a demo project, I needed to get the geographical coordinates of a real estate object, by its address: street, postcode, city, and country. In this tutorial, I will show you how to use a package called GeocoderLaravel, to achieve this.
GeocoderLaravel package is a Laravel wrapper around another package called Geocoder PHP, created for easier use within Laravel framework specifically.
Both packages have a lot of features, but we're interested in this scenario.
- Example Input: "16-18, Argyle Street, Camden, London, WC1H 8EG, United Kingdom"
- Example Output: [51.5291450, -0.1239401]
To do that, we need to use one of the 3rd party Geolocation services. There are a lot of them, including the ones that have API, but probably the most simple one is Google Maps API.
Important notice: using Google Maps API (and the majority of the other similar services) is not free. They may have some limited free usage, so check their pricing docs. Keep in mind that you need to watch the usage cause they often charge per API call.
Now, step by step.
Step 1. Install GeocoderLaravel Package
composer require toin0u/geocoder-laravelphp artisan vendor:publish --provider="Geocoder\Laravel\Providers\GeocoderService"
Simple, right?
Step 2. Add Google Maps API Key
Google Maps API Key looks something like this: AIzaSyAWRsRGOFbTXRlLHDOSudkerLjUtBfElUt
. You can read here how to register and get that key.
After you do that, you can put it into the Laravel config.
GeocoderLaravel package comes with its config, supporting various providers of Geolocation.
config/geocoder.php:
return [ // ... 'providers' => [ Chain::class => [ GoogleMaps::class => [ env('GOOGLE_MAPS_LOCALE', 'us'), env('GOOGLE_MAPS_API_KEY'), // <- THIS IS WHAT WE NEED ], GeoPlugin::class => [], ], ], // ...];
As you can see, GoogleMaps
is the provider enabled by default, so all you need to do is provide the API key in the .env
file.
.env:
APP_NAME=LaravelAPP_ENV=localAPP_KEY=base64:wgvwuEojBNlCrmg7Pmn3x...APP_DEBUG=true ## ... GOOGLE_MAPS_API_KEY=AIzaSyAWRsRGOFbTXRlLHDOSudkerLjUtBfElUt
Notice: protect your .env
file and this API key, cause, as I stated above, you are charged for API calls, so someone with that API key may directly damage you financially. Also, you can protect that API key from Google Maps API settings, restricting it by domain or other parameters.
Step 3. Call Geocoder For Coordinates
Here's a snippet that will get you the data:
$address = "16-18, Argyle Street, Camden, London, WC1H 8EG, United Kingdom";$result = app('geocoder')->geocode($address)->get();$coordinates = $result[0]->getCoordinates();$lat = $coordinates->getLatitude();$long = $coordinates->getLongitude();
Since we're using the global helper app('geocoder')
, you can call it wherever you want: in Controller, Queued Job, Service class, etc.
Obviously, you are not guaranteed to get the results, especially if your address is inputted by your users. So, you should check if there are results returned.
Also, you may want to put this logic somewhere in the Job that would be fired and put into the queue, to avoid users waiting for a few seconds to get the API results.
So, simple piece of code, but a lot of caveats and potential things to go wrong. That said, when it does go well, it feels like simple magic!
Hello,
I work on Windows 11 in a local environment with
php artisan serve
and use the Mapbox provider instead of Google. I have followed the above steps with some slight changes because of the different provider, but I don't get any results back.After some debugging I found out it must have somthing to do with the lack of ssl encryption in my local environment. A fix was to change a package file, to use the http adapter without verifcation.
Because I don't want to edit the package files I tried Symfony's webserver with ssl, which didn't solve the problem.
Do you had the same problem? If not not, how does your local environment look like?
Thanks in advance.
Need more details here.
Personally I don't use Windows, but maybe from your error messages, I can help you in googling the solution.
Thanks for your reply.
.vendor\toin0u\geocoder-laravel\src\ProviderAndDumperAggregator.php L:268
Both the error and my temporary fixes lead to an missing ssl certificate, which the use the symfony server should have solved. Do you have any other ideas what I can try or maybe a suggestion for another local development environment?
It actually had to do with my local environment. The Symfony server was not sufficient because PHP still did not have an SSL certificate set up.
This helped me: https://docs.boltcms.io/5.0/howto/curl-ca-certificates
Anyway, thanks for your time, Povilas and for the great content both here and on Youtube. I really appreciate your work.
This looks like a fantastic and robust package, but I am having a hard time figuring out how to get local filesystem or database based caching to run with. The docs provide a Redis example but I can't use that in my environment. Can't seem to find Laravel-specific examples on the web. Does anyone have a link or a hint?
I did some digging on this to find a PSR-6 compatible filesystem caching adapter. I found two,
duncan3dc/cache
andcache/filesystem-adapter
, but both have versioning problems with Laravel 10. THe former package doesn't seem to be maintained at all, the latter requires Flysystem ^1.0 while Laravel 10 comes with 3.8 and the maintainer isn't processing pull requests to get this updated.Any ideas would be welcome!