Geographical information integration is rapidly becoming an integral part of many websites. People use geographic data for a wide variety of applications. From location based content targeting, censoring information by geographic areas to analyzing website traffic by region. It is surprising how much free geographic information is available on the web. GeoNames is one such service.
GeoNames is a geographical database released under the creative commons attribution license, that contains over eight million geographical names and consists of 7 million unique features. The data is accessible free of charge through a number of web services and also as a downloadable database, which is updated on a daily basis.
GeoNames integrates geographical data such as names of places in various languages, elevation, population and other geographical information from various sources around the world.
In this post we will see how we can access the GeoNames API with PHP.
GeoNames API is available as a PEAR package, so we will be using the PEAR installer. Run the following command from your console window.
pear install Services_GeoNames-1.0.0 |
If the installer doexn’t work you can manually download the package from Services_GeoNames and install it in your PHP includes folder.
Now that we have installed the PEAR library, we will start with a small example that will get a list of places by the name ‘London’ and the country where the place is located. You will be surprised how many places the world over are named ‘London’.
<?php require_once 'Services/GeoNames.php'; $geo = new Services_GeoNames(); // Search for all cities named 'London' $cities = $geo->search(array('name_equals' => "London")); foreach ($cities as $city) { // 'name' and 'countryName' are not the only properties // available. Do a 'var_dump' on the $city variable to // get other properties. printf(" - %s (%s)\n", $city->name, $city->countryName); } ?> |
Below is a partial output listing for the above code:
- London (United Kingdom) - London (Canada) - London (United States) - London (United States) - City of London (United Kingdom) - London (South Africa) - London (South Africa) - London (South Africa) - London (Philippines) - London (Nigeria) - London (Switzerland) . . |
Lets try another API method. The following returns a list of all the countries and its capitals.
<?php require_once 'Services/GeoNames.php'; $geo = new Services_GeoNames(); // get a list of all countries and capitals $countries = $geo->countryInfo(); foreach ($countries as $country) { printf(" - %s (%s)\n", $country->countryName, $country->capital); } ?> |
One of the interesting method in the API is ‘neighbors’, which gets a list of neighbors for a particular country.
<?php require_once 'Services/GeoNames.php'; $geo = new Services_GeoNames(); // Get a list of neighboring countries of India $array = $geo->countryInfo(array('country' => 'IN')); $cInfo = $array[0]; $neighbours = $geo->neighbours(array('geonameId' => $cInfo->geonameId)); foreach ($neighbours as $neighbor) { printf("%s\n", $neighbour->countryName); } ?> |
Which outputs the following; the neighbouring countries of ‘India’:
Bangladesh Bhutan China Myanmar Nepal Pakistan |
There are many methods available in the class for querying various type of geographic data. Below is the complete list of methods available in the API class.
array children() children(array $params) array cities() cities(array $params) stdclass countryCode() countryCode(array $params) array countryInfo() countryInfo(array $params) stdclass countrySubdivision() countrySubdivision(array $params) array earthquakes() earthquakes(array $params) array findNearby() findNearby(array $params) array findNearbyPlaceName() findNearbyPlaceName(array $params) array findNearbyPostalCodes() findNearbyPostalCodes(array $params) array findNearbyStreets() findNearbyStreets(array $params) stdclass findNearByWeather() findNearByWeather(array $params) array findNearbyWikipedia() findNearbyWikipedia(array $params) stdclass findNearestAddress() findNearestAddress(array $params) stdclass findNearestIntersection() findNearestIntersection(array $params) stdclass get() get(array $params) stdclass gtopo30() gtopo30(array $params) array hierarchy() hierarchy(array $params) stdclass neighbourhood() neighbourhood(array $params) array neighbours() neighbours(array $params) array postalCodeCountryInfo() postalCodeCountryInfo(array $params) array postalCodeLookup() postalCodeLookup(array $params) array postalCodeSearch() postalCodeSearch(array $params) array search() search(array $params) array siblings() siblings(array $params) array weather() weather(array $params) stdclass weatherIcao() weatherIcao(array $params) stdclass srtm3() srtm3(array $params) stdclass timezone() timezone(array $params) array wikipediaBoundingBox() wikipediaBoundingBox(array $params) array wikipediaSearch() wikipediaSearch(array $params) |
The API provides a general name search which can be helpful if you need to perform some broad query for a search term. Lets take the following example. We use the ‘search’ method to query for the keyword ‘los angeles’. The method takes an array with the query term and the number of results to return. Note that the parameter ‘q’ searches over all attributes of a place : place name, country name, continent, admin codes etc. There are more parameter options besides ‘q’ and ‘maxRows’ which you can use while performing search.
<?php require_once 'Services/GeoNames.php'; $geo = new Services_GeoNames(); $results = $geo->search( array('q' => "los angeles", 'maxRows' => 10) ); print_r($results); ?> |
Below is the first result for the search term ‘los angeles’.
[countryName] => United States [adminCode1] => CA [fclName] => city, village,... [countryCode] => US [lng] => -118.2436849 [fcodeName] => populated place [fcl] => P [name] => Los Angeles [fcode] => PPL [geonameId] => 5368361 [lat] => 34.0522342 [population] => 3694820 [adminName1] => California |
Although the API provides a free service, if your are planning to use it in a critical web application, the company provides a commercial option for the same. The advantage of the commercial option is that the web services have higher up-time and fail-over in case of hardware defects or software bugs.
The API allows a limit of 50000 web access per day-per IP, which should be quite enough for most personal projects. Check the limit information here for further details.
All the information you can gather from the API is also available for download from GeoNames servers in text format. This can be useful if you would like to create your own database for hosting on your servers for data lookup. But bear in mind that the data is frequently updated, so your custom created database will quickly become outdated, which does not happen with the online API. And also you will have to write your own queries for the created database.
As an aside you can use the following example code to access the API web-service from javascript using jQuery.
<!DOCTYPE html> <html> <head> <script src="http://code.jquery.com/jquery-latest.js"></script> </head> <body> <div id="data"></div> <script> /* Searches for the keyword 'london', returning a maximum of 5 rows. More information can be found here: http://www.geonames.org/export/geonames-search.html */ /* Note you need to append 'JSON' to the method name to get the results back in JSON format. */ var apiMethod = 'searchJSON'; var parameters = 'q=london&maxRows=5'; var result = ''; $.get('http://ws.geonames.org/' + apiMethod + '?' + parameters, function(data) { $.each(data['geonames'], function(i,item){ $.each(item, function(j, field){ result += "(" + j + ") : " + field + "<br/>"; }); result += "<br />"; }); $('#data').html(result); }); </script> </body> </html> |
This site is a digital habitat of Sameer Borate, a freelance web developer working in PHP, MySQL and WordPress. I also provide web scraping services, website design and development and integration of various Open Source API's. Contact me at metapix[at]gmail.com for any new project requirements and price quotes.
2 Responses
1
jack bellow
April 17th, 2010 at 9:51 am
nice post!
2
Danis
April 21st, 2010 at 12:50 am
Hello,
Iwas going through ur http://www.codediesel.com/php/web-scraping-in-php-tutorial/ and i like that tooo … but have seen http://www.index4fun.com/ibm/ on net its prity cool it get image and all data it self from imbd.com ….. i was wondring if this type script can be made for http://www.bollywoodhungama.com …..so i can get all info and image from there ….. i dont have ur email …. so just putting in comments … u can contact me on danisrocky@gmail.com
thx
danis