Advertisement
jeitnier

Laravel sample

Dec 29th, 2022
1,375
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 4.59 KB | Source Code | 0 0
  1. <?php
  2.  
  3. namespace App\Support\Geocoders;
  4.  
  5. use App\Support\MapInformationAbstract;
  6. use Illuminate\Support\Facades\Cache;
  7. use Excel;
  8.  
  9. /**
  10.  * United States Census Bureau Free Geocoder.
  11.  * @see https://geocoding.geo.census.gov/geocoder/
  12.  */
  13. class USCB extends MapInformationAbstract implements GeocoderInterface
  14. {
  15.     /**
  16.      * Methods:
  17.      * - 'address'        parse by array parts
  18.      * - 'onelineaddress' parse by a one-line address string
  19.      *
  20.      * @var string
  21.      */
  22.     protected $method = 'address';
  23.  
  24.     /**
  25.      * Max rows of batch file.
  26.      *
  27.      * @var int
  28.      */
  29.     protected const BATCH_SIZE = 600;
  30.  
  31.     /**
  32.      * Geocode an address.
  33.      *
  34.      * @param  array|string $address
  35.      * @return array
  36.      */
  37.     public function process($address)
  38.     {
  39.         if (is_array($address)) {
  40.             $address = [
  41.                 'street' => $address['address1'] . ' ' . $address['address2'],
  42.                 'city'   => $address['city'],
  43.                 'state'  => $address['state'],
  44.                 'zip'    => $address['zip'],
  45.             ];
  46.             $address_string = implode(' ', $address);
  47.  
  48.             $query = $address;
  49.         } elseif (is_string($address)) {
  50.             $address_string = $address;
  51.  
  52.             $this->method = 'onelineaddress';
  53.  
  54.             $query = ['address' => $address];
  55.         }
  56.  
  57.         if (Cache::has('geo:address:' . snake_case($address_string))) {
  58.             return Cache::get('geo:address:' . snake_case($address_string));
  59.         }
  60.  
  61.         $query['format']    = 'json';
  62.         $query['benchmark'] = 'Public_AR_Current';
  63.  
  64.         // make API request
  65.         $response = (new \GuzzleHttp\Client())->request(
  66.             'GET',
  67.             "https://geocoding.geo.census.gov/geocoder/locations/$this->method",
  68.             ['query' => $query]
  69.         );
  70.  
  71.         $geocoder = json_decode($response->getBody()->getContents())->result;
  72.  
  73.         if (isset($geocoder->addressMatches) && count($geocoder->addressMatches)) {
  74.             $coordinates    = $geocoder->addressMatches[0]->coordinates;
  75.             $address_string = $geocoder->addressMatches[0]->matchedAddress;
  76.  
  77.             $params = [
  78.                 'coords'         => ['x' => $coordinates->x, 'y' => $coordinates->y],
  79.                 'address_string' => $address_string,
  80.             ];
  81.  
  82.             Cache::put('geo:address:' . snake_case($address_string), $params, $this->cache);
  83.  
  84.             return $params;
  85.         }
  86.  
  87.         return [];
  88.     }
  89.  
  90.     /**
  91.      * Geocode a batch of addresses.
  92.      *
  93.      * @param  array $addresses
  94.      * @return array
  95.      */
  96.     public function batch($addresses)
  97.     {
  98.         $output_path = storage_path('tmp/Output.csv');
  99.  
  100.         // if (!file_exists($output_path)) {
  101.         $addresses = collect($addresses)->unique(0)->values()->chunk(self::BATCH_SIZE);
  102.  
  103.         if (!$addresses->count()) {
  104.             return [];
  105.         }
  106.  
  107.         $addresses->each(function ($address_set, $key) use ($output_path) {
  108.             $filename = 'Addresses';
  109.             Excel::create($filename, function ($excel) use ($address_set) {
  110.                 $excel->sheet('Sheet1', function ($sheet) use ($address_set) {
  111.                     $sheet->fromArray($address_set, null, 'A1', false, false);
  112.                 });
  113.             })->store('csv', storage_path('tmp'));
  114.  
  115.             // make API request
  116.             $response = (new \GuzzleHttp\Client())->request(
  117.                 'POST',
  118.                 'https://geocoding.geo.census.gov/geocoder/locations/addressbatch',
  119.                 [
  120.                     'multipart' => [
  121.                         [
  122.                             'name'     => 'benchmark',
  123.                             'contents' => 'Public_AR_Current',
  124.                         ],
  125.                         [
  126.                             'name'     => 'addressFile',
  127.                             'contents' => fopen(storage_path('tmp/' . $filename . '.csv'), 'r'),
  128.                         ],
  129.                     ],
  130.                     'sink' => fopen($output_path, 'a'),
  131.                 ]
  132.             );
  133.  
  134.             sleep(3);
  135.         });
  136.         // }
  137.  
  138.         $items = Excel::load($output_path, function ($reader) {
  139.             return $reader->noHeading();
  140.         })->toArray();
  141.  
  142.         return $items;
  143.     }
  144. }
  145.  
  146. ?>
  147. <?php
  148.  
  149. namespace App\Support\Geocoders;
  150.  
  151. use Illuminate\Support\Collection;
  152.  
  153. interface GeocoderInterface
  154. {
  155.     /**
  156.      * Geocode an address
  157.      * @param Collection $original_address
  158.      * @return Collection
  159.      */
  160.     public function process($original_address): Collection;
  161. }
  162. ?>
  163.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement