Server-Side Geocoding and Caching
Google Maps API provides geocoding services to convert addresses (“Singapore 208539”) into geographic coordinates (1.311403, 103.85662). There are two approaches:
- Client-side geocoding, which uses JavaScript API to send requests and receive responses.
- HTTP server-side geocoding, which uses HTTP requests to directly query Google’s servers.
Server-side geocoding has a quota of 2,500 requests per IP per day limited by the Geocoding Web Service. Client-side geocoding is distributed across all users. Whenever possible, client-side geocoding is preferred and it doesn’t overload the server.
However, server-side geocoding and caching is helpful if the application repeatedly looks up the same address. When a geocoding request is processed, the server will first check the cache to see if it was geocoded, and if not, the server will send a request to Google, and cache the result.
In the following we use MySQL database to set up a geocoding cache, and use PHP to process geocoding requests.
Geocoding Cache
The following SQL creates a table mapping address strings to its geographical location.
CREATE TABLE location ( addr varchar(128) NOT NULL, faddr varchar(256) NOT NULL, lat double NOT NULL, lng double NOT NULL, updated_time timestamp NOT NULL default CURRENT_TIMESTAMP, PRIMARY KEY (addr) );
The field addr
is the search key, and faddr
represents the formatted address returned from Google’s geocoding service. A simple select query finds the result:
SELECT * FROM location WHERE addr = 'singapore 208539';
Use Google Geocoding Service
The following PHP code retrieves geocodes from Google. It constructs a request URL like
http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=singapore+208539
function google_geocoding($addr) { $url = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=". urlencode($addr); $json_txt = file_get_contents($url); if (! $json_txt) return FALSE; $json_arr = json_decode($json_txt, TRUE); if ($json_arr["status"] != "OK") return FALSE; $result = $json_arr["results"][0]; $ret = array( "addr" => $addr, "faddr" => $result["formatted_address"], "lat" => $result["geometry"]["location"]["lat"], "lng" => $result["geometry"]["location"]["lng"] ); return $ret; }
Search and Update the Cache
When the application needs the geocode for an address, we do the following:
- Search the cache for the geocode of the address.
- If found, return the result.
- If not, use Google’s geocoding service, and then save and return the result.
function my_geocoding($addr) { $addr = trim(strtolower($addr)); connect_db(); // Search the cache $query = sprintf("select addr, faddr, lat, lng from location where addr like '%s'", mysql_real_escape_string($addr) ); $result = mysql_query($query); if ($result && $ret = mysql_fetch_assoc($result)) return $ret; // Search through Google and update the cache $ret = google_geocoding($addr); $query = sprintf("replace into location(addr, faddr, lat, lng) values('%s', '%s', %f, %f)", mysql_real_escape_string($addr), mysql_real_escape_string($ret['faddr']), $ret['lat'], $ret['lng'] ); mysql_query($query); return $ret; } function connect_db() { $hostname = '00.00.000.000'; $username = $dbname = 'xxxx'; $password = 'xxxx'; mysql_connect($hostname, $username, $password) or die('Unable to connect to database! Please try again later.'); mysql_select_db($dbname); mysql_set_charset('utf8'); }
To use this code, simple write as below:
$addr = "..."; $result = my_geocoding($addr); $faddr = $result['faddr']; $lat = $result['lat']; $lng = $result['lng'];
There are several rules by the Google Maps API Terms of Service: (1) Geocoding results are only allowed to be used on Google Maps or Earth, and cannot be redistributed. (2) Caching is only allowed for a limited time. Actually, geocoding results may be updated over time.