Skip to content

Instantly share code, notes, and snippets.

@robwent
Created June 16, 2017 20:07
Show Gist options
  • Save robwent/0b1b898cbb9db154b1b50a88d33c6d57 to your computer and use it in GitHub Desktop.
Save robwent/0b1b898cbb9db154b1b50a88d33c6d57 to your computer and use it in GitHub Desktop.
Geolocate Addresses From Country and Zip Columns in a CSV file and Attach Additional Location Information.
<?php
//The file to be processed
$file = 'mailing_list.csv';
//The header of the fields that contains the country/zip
$zipHeader = 'postal code';
$countryHeader = 'country';
//The file to save the results to
$resultsFile = fopen('mailing_list_location.csv', 'w');
class CSVFile extends SplFileObject
{
private $keys;
public function __construct($file)
{
parent::__construct($file);
$this->setFlags(SplFileObject::READ_CSV);
}
public function rewind()
{
parent::rewind();
$this->keys = parent::current();
parent::next();
}
public function current()
{
return array_combine($this->keys, parent::current());
}
public function getKeys()
{
return $this->keys;
}
}
// function to geocode address
function geocode($address){
// url encode the address
$address = urlencode($address);
// google map geocode api url
$url = "http://maps.google.com/maps/api/geocode/json?address={$address}";
// get the json response
$resp_json = file_get_contents($url);
// decode the json
$resp = json_decode($resp_json, true);
// response status will be 'OK', if able to geocode given address
if($resp['status']=='OK'){
// get the important data
$lat = $resp['results'][0]['geometry']['location']['lat'] ? $resp['results'][0]['geometry']['location']['lat'] : '';
$lng = $resp['results'][0]['geometry']['location']['lng'] ? $resp['results'][0]['geometry']['location']['lng'] : '';
$formatted_address = $resp['results'][0]['formatted_address'] ? $resp['results'][0]['formatted_address'] : '';
$state = '';
$city = '';
$town = '';
foreach ($resp['results'][0]['address_components'] as $add) {
if (in_array('administrative_area_level_1', $add['types'])) {
$state = $add['long_name'];
}
if (in_array('administrative_area_level_2', $add['types'])) {
$city = $add['long_name'];
}
if (in_array('locality', $add['types'])) {
$town = $add['long_name'];
}
}
// put the data in the array
$data_arr = array(
'lat' => $lat,
'lng' => $lng,
'formattedaddress' => $formatted_address,
'state' => $state,
'city' => $city,
'town' => $town
);
return $data_arr;
} else {
//No results so add blank fields
$data_arr = array('lat' => '',
'lng' => '',
'formattedaddress' => '',
'state' => '',
'city' => '',
'town' => ''
);
}
}
function toCSV($data, $outstream) {
if (count($data)) {
// get header from keys
fputcsv($outstream, array_keys($data[0]));
//
foreach ($data as $row) {
fputcsv($outstream, $row);
}
}
}
//Open the file and loop through the rows
$csv = new CSVFile($file);
$output = array();
echo '<pre>';
foreach ($csv as $line)
{
//var_dump($line);
$addressString = '';
if ($line[$countryHeader] !== '') {
$addressString .= 'country:'.$line[$countryHeader].' ';
}
if ($line[$zipHeader] !== '') {
$addressString .= 'zip:'.$line[$zipHeader].' ';
}
if ($addressString === '') {
$line = array_merge($line, array('lat' => '',
'lng' => '',
'formattedaddress' => '',
'state' => '',
'city' => '',
'town' => ''
));
} else {
$loc = geocode($addressString);
if (is_array($loc)) {
$line = array_merge($line, $loc);
} else {
$line = array_merge($line, array('lat' => '',
'lng' => '',
'formattedaddress' => '',
'state' => '',
'city' => '',
'town' => ''
));
}
}
$output[] = $line;
// sleep(1);
}
echo '</pre>';
toCSV($output, $resultsFile);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment