├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── composer.json ├── config └── geocode.php ├── phpunit.xml ├── src └── Jcf │ └── Geocode │ ├── Exceptions │ └── EmptyArgumentsException.php │ ├── Facades │ └── Geocode.php │ ├── Geocode.php │ ├── GeocodeServiceProvider.php │ └── Response.php └── tests └── .gitkeep /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - 5.3 5 | - 5.4 6 | - 5.5 7 | - 5.6 8 | - hhvm 9 | 10 | before_script: 11 | - composer self-update 12 | - composer install --prefer-source --no-interaction --dev 13 | 14 | script: phpunit 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Google Geocoding API for Laravel 2 | 3 | [![Latest Stable Version](https://poser.pugx.org/jcf/geocode/v/stable.svg)](https://packagist.org/packages/jcf/geocode) [![Total Downloads](https://poser.pugx.org/jcf/geocode/downloads.svg)](https://packagist.org/packages/jcf/geocode) [![License](https://poser.pugx.org/jcf/geocode/license.svg)](https://packagist.org/packages/jcf/geocode) 4 | 5 | A simple [Laravel](http://laravel.com/) service provider for Google Geocoding API. 6 | 7 | ## Installation 8 | 9 | This package can be installed via [Composer](http://getcomposer.org). 10 | 11 | Run composer require command. 12 | 13 | ```sh 14 | composer require "jcf/geocode":"~1.3" 15 | ``` 16 | 17 | ### Laravel 5.5 18 | 19 | Both the service provider and alias will be automatically installed by Laravel 5.5 package discovery. If you don't use auto discovery, follow the instructions for Laravel 5.0-5.4 below: 20 | 21 | ### Laravel 5.0-5.4 22 | 23 | After updating composer, add the service provider to the providers array in app/config/app.php 24 | 25 | ```php 26 | Jcf\Geocode\GeocodeServiceProvider::class, 27 | ``` 28 | Add then alias Geocode adding its facade to the aliases array in the same file : 29 | 30 | ```php 31 | 'Geocode' => Jcf\Geocode\Facades\Geocode::class, 32 | ``` 33 | 34 | ### Laravel 4 35 | 36 | After updating composer, add the service provider to the providers array in app/config/app.php 37 | 38 | ```php 39 | 'Jcf\Geocode\GeocodeServiceProvider', 40 | ``` 41 | Add then alias Geocode adding its facade to the aliases array in the same file : 42 | 43 | ```php 44 | 'Geocode' => 'Jcf\Geocode\Facades\Geocode' 45 | ``` 46 | 47 | ### Lumen 5 48 | 49 | After updating composer, register the service provider in bootstrap/app.php 50 | 51 | ```php 52 | $app->register(Jcf\Geocode\GeocodeServiceProvider::class); 53 | ``` 54 | 55 | Since facade are not enabled by default on Lumen, don't forget to add this. 56 | 57 | ```php 58 | use Jcf\Geocode\Geocode; 59 | 60 | ``` 61 | 62 | ## Configuration 63 | 64 | Add the following line to the .env file: 65 | 66 | ```sh 67 | GEOCODE_GOOGLE_APIKEY= 68 | ``` 69 | 70 | You can optionally set the response language. 71 | 72 | ```sh 73 | GEOCODE_GOOGLE_LANGUAGE=en # pt-BR, es, de, it, fr, en-GB 74 | 75 | ``` 76 | 77 | [Supported Languages](https://developers.google.com/maps/faq?hl=en#languagesupport) for Google Maps Geocoding API. 78 | 79 | 80 | ## Usage 81 | You can find data from addresses: 82 | ```php 83 | $response = Geocode::make()->address('1 Infinite Loop'); 84 | 85 | if ($response) { 86 | echo $response->latitude(); 87 | echo $response->longitude(); 88 | echo $response->formattedAddress(); 89 | echo $response->locationType(); 90 | } 91 | 92 | // Output 93 | // 37.331741 94 | // -122.0303329 95 | // 1 Infinite Loop, Cupertino, CA 95014, USA 96 | // ROOFTOP 97 | ``` 98 | 99 | Or from latitude/longitude: 100 | 101 | ```php 102 | $response = Geocode::make()->latLng(40.7637931,-73.9722014); 103 | if ($response) { 104 | echo $response->latitude(); 105 | echo $response->longitude(); 106 | echo $response->formattedAddress(); 107 | echo $response->locationType(); 108 | } 109 | 110 | // Output 111 | // 40.7637931 112 | // -73.9722014 113 | // 767 5th Avenue, New York, NY 10153, USA 114 | // ROOFTOP 115 | 116 | ``` 117 | 118 | If you need other data rather than formatted address, latitude, longitude or location type, you can use the `raw()` method: 119 | ```php 120 | $response = Geocode::make()->latLng(40.7637931,-73.9722014); 121 | if ($response) { 122 | echo $response->raw()->address_components[8]['types'][0]; 123 | echo $response->raw()->address_components[8]['long_name']; 124 | } 125 | 126 | // Output 127 | // postal_code 128 | // 10153 129 | ``` 130 | 131 | That's it. Pull requests are welcome. 132 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jcf/geocode", 3 | "description": "Google Geocoding API for Laravel", 4 | "keywords": ["laravel", "google", "geocode", "geocoding", "address", "latitude", "longitude", "api"], 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "João Carlos", 9 | "email": "jotacfurtado@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": ">=5.4.0", 14 | "guzzlehttp/guzzle": "~5.3|~6.0" 15 | }, 16 | "autoload": { 17 | "psr-0": { 18 | "Jcf\\Geocode": "src/" 19 | } 20 | }, 21 | "minimum-stability": "stable", 22 | "extra": { 23 | "laravel": { 24 | "providers": [ 25 | "Jcf\\Geocode\\GeocodeServiceProvider" 26 | ], 27 | "aliases": { 28 | "Geocode": "Jcf\\Geocode\\Facades\\Geocode" 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /config/geocode.php: -------------------------------------------------------------------------------- 1 | env('GEOCODE_GOOGLE_APIKEY', ''), 4 | 'language' => env('GEOCODE_GOOGLE_LANGUAGE', 'en'), 5 | ]; 6 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 15 | ./tests/ 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Jcf/Geocode/Exceptions/EmptyArgumentsException.php: -------------------------------------------------------------------------------- 1 | apiKey = config('geocode.apikey'); 15 | $this->language = config('geocode.language'); 16 | } 17 | 18 | public static function make() 19 | { 20 | return new static(); 21 | } 22 | 23 | public function address($address, $params = []) 24 | { 25 | 26 | if (empty($address)) { 27 | throw new Exceptions\EmptyArgumentsException('Empty arguments.'); 28 | } 29 | $client = new \GuzzleHttp\Client(); 30 | $params = array_merge($params, ['address' => $address]); 31 | if (!empty($this->apiKey)) { 32 | $params['key'] = $this->apiKey; 33 | } 34 | if (!empty($this->language)) { 35 | $params['language'] = $this->language; 36 | } 37 | $response = json_decode($client->get('https://maps.googleapis.com/maps/api/geocode/json', [ 38 | 'query' => $params 39 | ])->getBody()); 40 | 41 | # check for status in the response 42 | switch( $response->status ) 43 | { 44 | 45 | case "ZERO_RESULTS": # indicates that the geocode was successful but returned no results. This may occur if the geocoder was passed a non-existent address. 46 | case "OVER_QUERY_LIMIT": # indicates that you are over your quota. 47 | case "REQUEST_DENIED": # indicates that your request was denied. 48 | case "INVALID_REQUEST": # generally indicates that the query (address, components or latlng) is missing. 49 | case "UNKNOWN_ERROR": 50 | return false; 51 | 52 | case "OK": # indicates that no errors occurred; the address was successfully parsed and at least one geocode was returned. 53 | return new Response($response); 54 | } 55 | 56 | } 57 | 58 | public function latLng($lat, $lng) 59 | { 60 | 61 | if (empty($lat) || empty($lng)) { 62 | throw new Exceptions\EmptyArgumentsException('Empty arguments.'); 63 | } 64 | 65 | $params = ['latlng' => $lat . ',' . $lng]; 66 | if (!empty($this->apiKey)) { 67 | $params['key'] = $this->apiKey; 68 | } 69 | if (!empty($this->language)) { 70 | $params['language'] = $this->language; 71 | } 72 | 73 | $client = new \GuzzleHttp\Client(); 74 | $response = json_decode($client->get('https://maps.googleapis.com/maps/api/geocode/json', [ 75 | 'query' => $params 76 | ])->getBody()); 77 | 78 | # check for status in the response 79 | switch( $response->status ) 80 | { 81 | 82 | case "ZERO_RESULTS": # indicates that the geocode was successful but returned no results. This may occur if the geocoder was passed a non-existent address. 83 | case "OVER_QUERY_LIMIT": # indicates that you are over your quota. 84 | case "REQUEST_DENIED": # indicates that your request was denied. 85 | case "INVALID_REQUEST": # generally indicates that the query (address, components or latlng) is missing. 86 | case "UNKNOWN_ERROR": 87 | return false; 88 | 89 | case "OK": # indicates that no errors occurred; the address was successfully parsed and at least one geocode was returned. 90 | return new Response($response); 91 | } 92 | 93 | } 94 | 95 | public function placeId($id) 96 | { 97 | if (empty($id)) { 98 | throw new Exceptions\EmptyArgumentsException('Empty arguments.'); 99 | } 100 | 101 | $params = ['place_id' => $id]; 102 | 103 | if (!empty($this->apiKey)) { 104 | $params['key'] = $this->apiKey; 105 | } 106 | 107 | if (!empty($this->language)) { 108 | $params['language'] = $this->language; 109 | } 110 | 111 | $client = new \GuzzleHttp\Client(); 112 | $response = json_decode($client->get('https://maps.googleapis.com/maps/api/geocode/json', [ 113 | 'query' => $params 114 | ])->getBody()); 115 | 116 | # check for status in the response 117 | switch( $response->status ) 118 | { 119 | 120 | case "ZERO_RESULTS": # indicates that the geocode was successful but returned no results. This may occur if the geocoder was passed a non-existent address. 121 | case "OVER_QUERY_LIMIT": # indicates that you are over your quota. 122 | case "REQUEST_DENIED": # indicates that your request was denied. 123 | case "INVALID_REQUEST": # generally indicates that the query (address, components or latlng) is missing. 124 | case "UNKNOWN_ERROR": 125 | return false; 126 | 127 | case "OK": # indicates that no errors occurred; the address was successfully parsed and at least one geocode was returned. 128 | return new Response($response); 129 | } 130 | } 131 | 132 | } 133 | -------------------------------------------------------------------------------- /src/Jcf/Geocode/GeocodeServiceProvider.php: -------------------------------------------------------------------------------- 1 | app instanceof LaravelApplication && $this->app->runningInConsole()) { 23 | $this->publishes([$source => config_path('geocode.php')]); 24 | } elseif ($this->app instanceof LumenApplication) { 25 | $this->app->configure('geocode'); 26 | } 27 | $this->mergeConfigFrom($source, 'geocode'); 28 | } 29 | 30 | /** 31 | * Register the service provider. 32 | * 33 | * @return void 34 | */ 35 | public function register() 36 | { 37 | $this->app->singleton('geocode',function($app) 38 | { 39 | return new \Jcf\Geocode\Geocode; 40 | }); 41 | 42 | if ($this->app instanceof LaravelApplication) { 43 | $this->app->booting(function () 44 | { 45 | $loader = \Illuminate\Foundation\AliasLoader::getInstance(); 46 | $loader->alias('Geocode', 'Jcf\Geocode\Facades\Geocode'); 47 | }); 48 | } 49 | } 50 | 51 | /** 52 | * Get the services provided by the provider. 53 | * 54 | * @return array 55 | */ 56 | public function provides() 57 | { 58 | return array(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/Jcf/Geocode/Response.php: -------------------------------------------------------------------------------- 1 | response = $response->results[0]; 9 | } 10 | 11 | public function raw() 12 | { 13 | return (object) $this->response; 14 | } 15 | 16 | public function formattedAddress() 17 | { 18 | return $this->response->formatted_address; 19 | } 20 | 21 | public function latitude() 22 | { 23 | return $this->response->geometry->location->lat; 24 | } 25 | 26 | public function longitude() 27 | { 28 | return $this->response->geometry->location->lng; 29 | } 30 | 31 | public function locationType() 32 | { 33 | return $this->response->geometry->location_type; 34 | } 35 | 36 | public function postalCode() 37 | { 38 | foreach ($this->response->address_components as $component) { 39 | if (isset($component->types) && in_array('postal_code', $component->types)) { 40 | return $component->long_name; 41 | } 42 | } 43 | 44 | return false; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jotafurtado/geocode/d598f618ea485333e972a04c0ccd263f0884c933/tests/.gitkeep --------------------------------------------------------------------------------