Geocoding with PHP
In my last post I mentioned geocoding using the Yahoo Geocoding API , so I thought I’d post some code to do exactly that.
For the purposes of this example, assume that we have a very simple MySQL database table with this structure:
CREATE TABLE addresses (
id int(11) NOT NULL auto_increment,
street varchar(255) default NULL,
city varchar(255) default NULL,
state varchar(2) default NULL,
zip varchar(9) default NULL,
lat float(10,6) default NULL,
lon float(10,6) default NULL,
PRIMARY KEY (id)
)
Here’s the script:
<?php
// Geocode addresses using the Yahoo Geocoding API
// Turning on track_errors stores the latest PHP error in $php_errormsg.
// This allows for more elegant display of the error messages without having to
// code a php error handler, which would be overkill for such a simple script.
ini_set('track_errors',TRUE);
mysql_connect('localhost', 'user', 'password');
mysql_select_db('database_name');
// Setup variables to be used later
$geocode_url = "http://local.yahooapis.com/MapsService/V1/geocode";
// Enter your custom appid here
$appid ='sample_appid';
// Get the addresses that have not been geocoded
$address_result = mysql_query("SELECT id, street, city, state, zip FROM addresses WHERE lat IS NULL OR lon IS NULL");
// If the MySQL query returned any rows, loop through them
if(mysql_num_rows($address_result) > 0){
while ($row = mysql_fetch_assoc($address_result)){
// appid is required for each call to the yahoo geocode API
$row['appid'] = $appid;
// output can be either xml or php
$row['output'] = 'php';
// Store the row id for updating the database and remove from $row array
$id = $row['id'];
unset($row['id']);
// Build the query string for sending the request to yahoo
$query_string = http_build_query($row, '', '&');
// Get latitute / longitude
$response = @file_get_contents($geocode_url.'?'.$query_string);
if($response == false){
// If the call to the yahoo api failed, display an error message
echo 'ERROR: '.$php_errormsg;
}
else{
// Get the results of the api call and update the database records
$response_array = unserialize($response);
$lat = mysql_real_escape_string($response_array['ResultSet']['Result']['Latitude']);
$lon = mysql_real_escape_string($response_array['ResultSet']['Result']['Longitude']);
$update_result = mysql_query("UPDATE addresses SET lat = '$lat', lon = $lon WHERE id = $id");
// For each record, let the user know if the update was successful. If not, display the mysql error message generated.
if($update_result == TRUE){
echo "Added lattitude and longitude for {$row['street']} {$row['city']}, {$row['state']} {$row['zip']}.";
}
else{
echo "Unable to add lattitude and longitude for {$row['street']} {$row['city']}, {$row['state']} {$row['zip']}
MySQL Error: ".mysql_error();
}
}
echo '<br />';
}
}
else{
echo "Nothing to do.";
}
?>
The code is documented pretty well so I’ll just point out a couple things:
- The Yahoo Geocoding API can return either XML or PHP serialized objects. I chose PHP serialized objects because it’s easier to deal with for what I’m trying to do.
- http_build_query does not exist in PHP4. To use this code with PHP4 you could use the PHP_COMPAT Pear Package .
Read other posts