-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 009f562
Showing
6 changed files
with
310 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# United States Zipcode Lookup database | ||
|
||
This is a Laravel 5 package for easy and simple lookup for geographic data by U.S. zipcode. While there are a few nice solutions like http://zippopotam.us for online lookup, sometimes i might be preferable to have all the data locally. | ||
|
||
The package using the data from http://federalgovernmentzipcodes.us/ . There is an Artisan command implemented to perform automatic update of the data. | ||
|
||
## Installation | ||
|
||
### Step 1 | ||
|
||
Add this to your `composer.json` | ||
|
||
{ | ||
"require": { | ||
"dpovshed/zipus": "1.*" | ||
} | ||
} | ||
|
||
then install package as usual. | ||
|
||
### Step 2 | ||
|
||
Run the following command: | ||
|
||
php artisan zipus-import | ||
|
||
If everything is fine, as a result in your cache directory you'll have JSONed arrays with the data. | ||
|
||
If your application is in debug mode, i.e. APP_DEBUG is set to true in the .env file, you may visit | ||
http://example.com/zipus-test to check the lookup process. | ||
|
||
## Usage | ||
|
||
Lookup functionality is provided as a service, so use construction like | ||
|
||
$city = app()->make('zipcode')->getCity('10282'); | ||
|
||
to get city name for a particular zipcode. Result is a string with a city name. | ||
To get the all data available please use function named getData: | ||
|
||
$city = app()->make('zipcode')->getData('10282'); | ||
|
||
You will get a result like: | ||
[ | ||
'ZipCodeType' => string 'STANDARD' (length=8) | ||
'City' => string 'NEW YORK' (length=8) | ||
'State' => string 'NY' (length=2) | ||
'LocationType' => string 'PRIMARY' (length=7) | ||
'Lat' => string '40.71' (length=5) | ||
... | ||
]; | ||
|
||
All the elements of an array would be named exactly as a column in original CSV file form http://federalgovernmentzipcodes.us . Please note that package used a database where a patricular zipcode is resolved only to one primary address. | ||
|
||
In case passed string is not a valid U.S. zipcode, as a result you will get unchanged zipcode with getCity() and an empty array with getData(). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "dpovshed/zipus", | ||
"description": "US zipcode static database.", | ||
"type": "library", | ||
"keywords": ["zip code","usa","geodata"], | ||
"homepage": "https://github.com/dpovshed/zipus", | ||
"license": "MIT", | ||
"authors": [ | ||
{ | ||
"name": "Dennis Povshedny", | ||
"email": "basturma@gmail.com" | ||
} | ||
], | ||
"require": { | ||
"php": ">=5.6.3", | ||
"illuminate/console": "~5.2" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"Dpovshed\\Zipus\\": "src/" | ||
} | ||
}, | ||
"minimum-stability": "dev" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?php | ||
|
||
namespace Dpovshed\Zipus\Console\Commands; | ||
|
||
use Illuminate\Console\Command; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use League\Flysystem\Exception; | ||
|
||
class ZipusImport extends Command | ||
{ | ||
const CSVFILE = "http://federalgovernmentzipcodes.us/free-zipcode-database-Primary.csv"; | ||
|
||
/** | ||
* The name and signature of the console command. | ||
* | ||
* @var string | ||
*/ | ||
protected $signature = 'zipus-import {--filename=}'; | ||
|
||
/** | ||
* The console command description. | ||
* | ||
* @var string | ||
*/ | ||
protected $description = 'Import the primary locations only CSV file from federalgovernmentzipcodes.us'; | ||
|
||
/** | ||
* Execute the console command. | ||
* | ||
* @return mixed | ||
*/ | ||
public function handle() | ||
{ | ||
$filename = (($this->option('filename')) ?: self::CSVFILE); | ||
try { | ||
$lines = file($filename); | ||
$headers = explode(',', trim($lines[0])); | ||
$headers = str_replace('"', '', $headers); | ||
$countColumns = count($headers); | ||
$countMalformed = 0; | ||
$zipusCity = []; | ||
$zipusAll = []; | ||
$this->comment("Columns found: $countColumns" . PHP_EOL, OutputInterface::VERBOSITY_VERBOSE); | ||
// Skip first line and first column. | ||
unset($lines[0]); | ||
unset($headers[0]); | ||
foreach ($lines as $line) { | ||
$item = explode(',', trim($line)); | ||
$item = str_replace('"', '', $item); | ||
if (count($item) != $countColumns) { | ||
$this->comment("Malformed row, bad number of columns: $line", OutputInterface::VERBOSITY_VERY_VERBOSE); | ||
$countMalformed++; | ||
continue; | ||
} | ||
$zipcode = str_replace('"', '', $item[0]); | ||
$zipusCity[$zipcode] = ucwords(strtolower(str_replace('"', '', $item[2]))); | ||
$itemNamed = []; | ||
foreach ($headers as $i => $header) { | ||
$itemNamed[$header] = $item[$i]; | ||
} | ||
$zipusAll[$zipcode] = $itemNamed; | ||
} | ||
$filenameCity = storage_path('framework/cache/zipus_city.json'); | ||
$filenameAll = storage_path('framework/cache/zipus_all.json'); | ||
$jsonCity = json_encode($zipusCity); | ||
$jsonAll = json_encode($zipusAll); | ||
file_put_contents($filenameCity, $jsonCity); | ||
file_put_contents($filenameAll, $jsonAll); | ||
$count = count($lines) - $countMalformed; | ||
$this->comment("Zip data cached locally, $count items."); | ||
} | ||
catch (Exception $e) { | ||
$this->comment(PHP_EOL . 'Import error: ' . $e->getMessage()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
if (config('app.debug')) { | ||
Route::get('/zipus-test', function() { | ||
$zipcode = '10282'; | ||
$city = app()->make('zipcode')->getCity($zipcode); | ||
echo "Lookup for \"ucword'ed\" City name for zipcode $zipcode: "; | ||
var_dump($city); | ||
echo PHP_EOL; | ||
|
||
$data = app()->make('zipcode')->getData($zipcode); | ||
echo "Lookup for all data for zipcode $zipcode: "; | ||
var_dump($data); | ||
echo PHP_EOL; | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php | ||
|
||
namespace Dpovshed\Zipus\Providers; | ||
|
||
use Illuminate\Support\ServiceProvider; | ||
use Illuminate\Routing\Router; | ||
use Dpovshed\Zipus\Console\Commands\ZipusImport; | ||
use Dpovshed\Zipus\ZipCityLookup; | ||
|
||
class ZipServiceProvider extends ServiceProvider | ||
{ | ||
/** | ||
* Create a new service provider instance. | ||
* | ||
* @param \Illuminate\Contracts\Foundation\Application $app | ||
*/ | ||
public function __construct($app) | ||
{ | ||
$this->defer = !config('app.debug'); | ||
parent::__construct($app); | ||
} | ||
|
||
/** | ||
* Boot and configure the application paths | ||
* | ||
* @return void | ||
*/ | ||
public function boot() | ||
{ | ||
$this->setupRoutes($this->app->router); | ||
|
||
// Register commands | ||
$this->commands('command.zipus.import'); | ||
} | ||
|
||
/** | ||
* Register the application services. | ||
* | ||
* @return void | ||
*/ | ||
public function register() | ||
{ | ||
$this->app->singleton('zipcode', function ($app) { | ||
return new ZipCityLookup; | ||
}); | ||
|
||
$this->app->singleton('command.zipus.import', function ($app) { | ||
return new ZipusImport; | ||
}); | ||
} | ||
|
||
/** | ||
* Get the services provided by the provider. | ||
* | ||
* @return array | ||
*/ | ||
public function provides() | ||
{ | ||
return ['zipcode', 'command.zipus.import']; | ||
} | ||
|
||
|
||
/** | ||
* Define the routes for the application. | ||
* | ||
* @param \Illuminate\Routing\Router $router | ||
* | ||
* @return void | ||
*/ | ||
protected function setupRoutes(Router $router) | ||
{ | ||
$router->group( | ||
['namespace' => 'Dpovshed\Zipus\Http\Controllers'], | ||
function ($router) { | ||
include __DIR__.'/../Http/routes.php'; | ||
} | ||
); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?php | ||
|
||
namespace Dpovshed\Zipus; | ||
|
||
use Log; | ||
|
||
class ZipCityLookup | ||
{ | ||
|
||
/** | ||
* @var array $data | ||
* | ||
* All the details for zipcode. | ||
*/ | ||
static protected $data = false; | ||
|
||
/** | ||
* @var array $cities | ||
* | ||
* Mapping zipcode to city name. | ||
*/ | ||
static protected $cities = false; | ||
|
||
/** | ||
* @param string $zip | ||
* Zip code to lookup. | ||
* | ||
* @return string | ||
* City name if found, original zipcode otherwise. | ||
*/ | ||
public function getCity($zip) | ||
{ | ||
if (empty(self::$cities)) { | ||
self::$cities = json_decode(file_get_contents(storage_path('framework/cache/zipus_city.json')), true); | ||
} | ||
if (isset(self::$cities[$zip])) { | ||
return self::$cities[$zip]; | ||
} | ||
return $zip; | ||
} | ||
|
||
/** | ||
* @param string $zip | ||
* Zip code to lookup. | ||
* | ||
* @return array | ||
* If zipcode is known, return all the data. Otherwise return empty array. | ||
*/ | ||
public function getData($zip) | ||
{ | ||
if (empty(self::$data)) { | ||
self::$data = json_decode(file_get_contents(storage_path('framework/cache/zipus_all.json')), true); | ||
} | ||
if (isset(self::$data[$zip])) { | ||
return self::$data[$zip]; | ||
} | ||
return []; | ||
} | ||
} |