Geocoding with PHP and the Google Maps API
- Transfer
Most applications on the Internet are now starting to embed terrain maps.
This article is devoted to working with maps using the Google Map API.
The following describes the principles of working with the Google API, implements the simplest classes using SimpleXML (for many it may seem that the code is extremely simple). The terms geocoding and geocoder in the article are left in English.
Introduction
Geocoding is the process of finding latitude and longitude at an entered address. Google provides free access to the developed tools, which can be accessed using both the JavaScript API and the web service ... This article shows how to access the geocoder web service using PHP.
There are a large number of applications for determining latitude and longitude, many of them are free. Here are some examples of how to use them:
When you use Google Maps to display maps on a site, the easiest way is to use the JavaScript API, but this is not always the best solution.
For example, if your application writes the coordinates to the address that the user enters, this solution will not work for those users who have JavaScript disabled. To prevent this situation, we can use the web service to redirect all requests to geocoder to the server.
This article will develop some classes that will help you get quick access to geocoder.
Getting started with Google Maps
All documentation on using the Google Maps API is located at this address.
The first thing to do to use the Google Maps API is to create an API key for your site. This key will identify all your requests to this API. You can get this key by agreeing to the terms of use and entering the website address on the page
. Currently, the maximum number of requests to geocoder is limited and amounts to 15,000 per day. But you can cache geocoder responses.
After receiving the key, you can contact geocoder. Documentation for using geocoder can be found at
Making Queries to Geocoder
When you make a request to geocoder, you can specify in what format you want to receive a response. Possible formats are: JSON, XML, KML, and CSV. This article describes the manipulation of responses in XML.
KML (Keyhole Markup Data Decryption) is an XML format developed for use by Google Earth. The response data in KML and XML from geocoder is identical.
Although JSON is commonly used with JavaScript, we can also use it in our application. To work with JSOM using PHP, see the following functions (starting with PHP 5.2.0). In this article, the SimpleXML extension is used to process XML data from geocoder .
To make a request to geocoder, an HTTP request must be sent to maps.google.com/maps/geo . The request parameters are described below:
For example, in order to get the coordinates of the White House (located at 1600 Pennsylvania Avenue, Washington, DC), you need to make the following request: maps.google.com/maps/geo?q=1600+pennsylvania+ave+washington+dc&output=xml&key = 123456
Replace 123456 with your key
The string format string that you send in the request is not critical, but there should be no ambiguity
Parse the Geocoder response
After sending the request to geocoder, you get the answer in the format you specified. For example, if the specified address is the address of the White House, then we will receive the following XML document in response:

In this answer, we highlight 3 important elements:
The first useful element that is included in each placemark element is the formatted address address. This is very important, because users can enter the same address in different ways. If you look at the example above, you can see that the string “1600 pennsylvania ave washington dc” was entered for the search, and “1600 Pennsylvania Ave NW, Washington, DC 20006, USA” was received as an answer.
The next element is AddressDetails, which uses Extensible Address Language (xAL) to provide information. This element has an Accuracy attribute, which indicates the degree of accuracy of positioning. Possible values for the Accuracy attribute:
In the example above, the attribute value is 8, which indicates the highest level of accuracy.
Other elements inside the AddressDetails element describe parts of the found location according to the xAL language specification.
Each placemark element contains a Point element. This item contains comma separated data. The first element is longitude; the second is latitude; The third argument is the altitude (not used).
Access to Geocoder data using SimpleXML
To parse the resulting XML, we will use SimpleXML, an extension that makes working with XML in PHP quite easy. SimpleXML has been built into PHP since PHP 5.
To read XML data, you need to initialize the SimpleXMLElement object by passing the XML string that we want to parse into its constructor.
By creating an object of the SimpleXMLElement class, we can access all the elements of the XML string, as if these were ordinary properties of the object. For example, you can access the response status using the following code:
It should be noted that the type $ xml-> Response-> Status-> code is SimpleXMLElement. Therefore, it is necessary to use type conversion to a string or number.
Now we know how to read XML data, but some elements contain attributes. The following example shows how to access these attributes.
Creating the Geocoder class
This article will discuss the implementation of the solution for using information from Google geocoder. The process will consider writing three classes:
Let's proceed with the implementation of the Geocoder class. This class will contain the lookup () method, the input of which will be the address for the search, the array of elements of the Placecmark class with the found places will be returned as a result.
The code below shows part of the implementation of the class. First, the geocoder address is determined. We determine the required number of constants corresponding to the return status. Using constants makes the code more readable and maintainable. For consistency, we use the same constants defined for the JavaScript API
As described above, we implement the lookup () method, which returns an array of objects of type Placemark. To get a response from geocoder, we will write a method called performRequest ().
The performRequest () method will take an address string as the first argument and the return type as the second argument.
This method uses Curl functions to implement HTTP requests. To receive responses from the server, the CURLOPT_RETURNTRANSFER parameter must be set to true.
Now we are closely engaged in the implementation of the lookup () method. In the beginning, we will get a response from the server using the performRequest () method, create an object of the SimpleXMLELement class. Next, we read the status of the request returned by the server. The normal request will be G_GEO_SUCCESS, G_GEO_UNKNOWN_ADDRESS or G_GEO_UNAVAILABLE_ADDRESS. The last two values will show that no specified locations were found, in this case an empty array will be returned.
If the status code is G_GEO_SUCCESS, we will cycle through the found places and create Placemark objects for each ... We will write the FromSimpleXml () method to create an object of the Placemark class.
For all other status codes, we will create an exception.
This is the complete code for the Geocoder class. If you want to use the performRequest () function, you can do this, but now you need to implement the Placemark class before using the lookup () method.
Creating the Placemark Class
Now we are implementing the Placemark class, which will be used to store location information. It is preferable, of course, to save all parts of the address returned from geocoder, we restrict ourselves to saving three elements:
To implement this class, we will write the functions of setting and receiving values (the functions setPoint (), getPoint (), setAddress (), getAddress (), setAccuracy () and getAccuracy ()). We also implement the static FromSimpleXml () method, which is used in the Geocoder class.
In the Placemark class, we will define constants responsible for the accuracy of the location. For example, to determine if only a country is defined, use the following
Implementation.
The Google Maps API does not define named constants for precision.
Next is the definition of the so-called setters and getters, I skip the author's comments.
At the end, we implement the FromSimpleXml () method, which is a factory method for creating Placemark objects based on the SimpleXMLElement object.
In the example described below, the Point class and its Create () method are used, they will be described below.
Creating the Point Class
The last class that needs to be implemented for full use is the Point class. This class stores latitude and longitude. This data is transmitted in the constructor; there are also methods for obtaining latitude and longitude values.
Conclusion
This article describes the simplest algorithm for working with geocoder using Google Maps. You can also use the specified classes with JavaScript, but you should also remember that not everyone can have JavaScript enabled.
Also remember that caching geocoder responses will allow you to reduce the load and increase productivity in the future.
References
This article is devoted to working with maps using the Google Map API.
The following describes the principles of working with the Google API, implements the simplest classes using SimpleXML (for many it may seem that the code is extremely simple). The terms geocoding and geocoder in the article are left in English.
- Introduction
- Getting started with Google Maps
- Making Geocoder Queries
- Parsing a Geocoder Answer
- Access Geocoder Data Using SimpleXML
- Creating a Geocoder Class
- Creating a Placemark Class
- Creating a Point Class
- Conclusion
- References
Introduction
Geocoding is the process of finding latitude and longitude at an entered address. Google provides free access to the developed tools, which can be accessed using both the JavaScript API and the web service ... This article shows how to access the geocoder web service using PHP.
There are a large number of applications for determining latitude and longitude, many of them are free. Here are some examples of how to use them:
- Drawing the address entered by the user on the map
- Using latitude and longitude for calculations (e.g. finding distance)
- Checking the address when ordering in the online store
When you use Google Maps to display maps on a site, the easiest way is to use the JavaScript API, but this is not always the best solution.
For example, if your application writes the coordinates to the address that the user enters, this solution will not work for those users who have JavaScript disabled. To prevent this situation, we can use the web service to redirect all requests to geocoder to the server.
This article will develop some classes that will help you get quick access to geocoder.
Getting started with Google Maps
All documentation on using the Google Maps API is located at this address.
The first thing to do to use the Google Maps API is to create an API key for your site. This key will identify all your requests to this API. You can get this key by agreeing to the terms of use and entering the website address on the page
. Currently, the maximum number of requests to geocoder is limited and amounts to 15,000 per day. But you can cache geocoder responses.
After receiving the key, you can contact geocoder. Documentation for using geocoder can be found at
Making Queries to Geocoder
When you make a request to geocoder, you can specify in what format you want to receive a response. Possible formats are: JSON, XML, KML, and CSV. This article describes the manipulation of responses in XML.
KML (Keyhole Markup Data Decryption) is an XML format developed for use by Google Earth. The response data in KML and XML from geocoder is identical.
Although JSON is commonly used with JavaScript, we can also use it in our application. To work with JSOM using PHP, see the following functions (starting with PHP 5.2.0). In this article, the SimpleXML extension is used to process XML data from geocoder .
To make a request to geocoder, an HTTP request must be sent to maps.google.com/maps/geo . The request parameters are described below:
- q - address whose coordinates must be determined
- key - Google Maps API key
- output - result format (json, xml, kml or csv)
For example, in order to get the coordinates of the White House (located at 1600 Pennsylvania Avenue, Washington, DC), you need to make the following request: maps.google.com/maps/geo?q=1600+pennsylvania+ave+washington+dc&output=xml&key = 123456
Replace 123456 with your key
The string format string that you send in the request is not critical, but there should be no ambiguity
Parse the Geocoder response
After sending the request to geocoder, you get the answer in the format you specified. For example, if the specified address is the address of the White House, then we will receive the following XML document in response:

In this answer, we highlight 3 important elements:
- name: The address string we pass to geocoder
- Status: The status of the response by which we can easily understand what happened. The following is a description of the various possible states:
- 200: Successful request (at least one place on the entered line was found)
- 400: Bad request (server did not understand the request)
- 500: Server error (Internal error)
- 601: Missing query. Q parameter missing or empty string passed
- 602: Unknown address. Nothing found on the entered string
- 603: Unavailable address. The address provided is missing or cannot be displayed due to legal or contractual considerations
- 610: Invalid Google Maps API Key
- 620: Too many requests were made using this key
- Placemark: If the Status field is 200, at least one Placemark element is present in the returned XML that contains information about the passed string.
The first useful element that is included in each placemark element is the formatted address address. This is very important, because users can enter the same address in different ways. If you look at the example above, you can see that the string “1600 pennsylvania ave washington dc” was entered for the search, and “1600 Pennsylvania Ave NW, Washington, DC 20006, USA” was received as an answer.
The next element is AddressDetails, which uses Extensible Address Language (xAL) to provide information. This element has an Accuracy attribute, which indicates the degree of accuracy of positioning. Possible values for the Accuracy attribute:
- 0: Unknown
- 1: Country
- 2: Region
- 3: Sub-region
- 4: Town
- 5: Postcode
- 6: Street
- 7: Intersection
- 8: Address
In the example above, the attribute value is 8, which indicates the highest level of accuracy.
Other elements inside the AddressDetails element describe parts of the found location according to the xAL language specification.
Each placemark element contains a Point element. This item contains comma separated data. The first element is longitude; the second is latitude; The third argument is the altitude (not used).
Access to Geocoder data using SimpleXML
To parse the resulting XML, we will use SimpleXML, an extension that makes working with XML in PHP quite easy. SimpleXML has been built into PHP since PHP 5.
To read XML data, you need to initialize the SimpleXMLElement object by passing the XML string that we want to parse into its constructor.
$ str = "XML string"; // sample XML file
$ xml = new SimpleXMLElement ($ str);
By creating an object of the SimpleXMLElement class, we can access all the elements of the XML string, as if these were ordinary properties of the object. For example, you can access the response status using the following code:
$ xml = new SimpleXMLElement ($ geocoderResponse);
echo $ xml-> Response-> Status-> code;
It should be noted that the type $ xml-> Response-> Status-> code is SimpleXMLElement. Therefore, it is necessary to use type conversion to a string or number.
$ xml = new SimpleXMLElement ($ geocoderResponse);
$ status = (int) $ xml-> Response-> Status-> code;
if ($ status == 200) {...}
Now we know how to read XML data, but some elements contain attributes. The following example shows how to access these attributes.
$ xml = new SimpleXMLElement ($ geocoderResponse);
foreach ($ xml-> Response-> Placemark as $ placemark) {
$ accuracy = (int) $ placemark-> AddressDetails ['Accuracy'];
($ accuracy == 8) {...}
}
Creating the Geocoder class
This article will discuss the implementation of the solution for using information from Google geocoder. The process will consider writing three classes:
- Geocoder: This class will be used to work with geocoder (sending requests, receiving and parsing responses).
- Placemark: This class will contain the places returned by geocoder.
- Point: This class will contain the coordinates of the locations found.
Let's proceed with the implementation of the Geocoder class. This class will contain the lookup () method, the input of which will be the address for the search, the array of elements of the Placecmark class with the found places will be returned as a result.
The code below shows part of the implementation of the class. First, the geocoder address is determined. We determine the required number of constants corresponding to the return status. Using constants makes the code more readable and maintainable. For consistency, we use the same constants defined for the JavaScript API
class Geocoder
{
public static $ url = 'http://maps.google.com/maps/geo';
const G_GEO_SUCCESS = 200;
const G_GEO_BAD_REQUEST = 400;
const G_GEO_SERVER_ERROR = 500;
const G_GEO_MISSING_QUERY = 601;
const G_GEO_MISSING_ADDRESS = 601;
const G_GEO_UNKNOWN_ADDRESS = 602;
const G_GEO_UNAVAILABLE_ADDRESS = 603;
const G_GEO_UNKNOWN_DIRECTIONS = 604;
const G_GEO_BAD_KEY = 610;
const G_GEO_TOO_MANY_QUERIES = 620;
protected $ _apiKey;
public function __construct ($ key)
{
$ this -> _ apiKey = $ key;
}
}
As described above, we implement the lookup () method, which returns an array of objects of type Placemark. To get a response from geocoder, we will write a method called performRequest ().
The performRequest () method will take an address string as the first argument and the return type as the second argument.
This method uses Curl functions to implement HTTP requests. To receive responses from the server, the CURLOPT_RETURNTRANSFER parameter must be set to true.
class Geocoder
{
public function performRequest ($ search, $ output = 'xml')
{
$ url = sprintf ("% s? q =% s & output =% s & key =% s & oe = utf-8", self :: $ url, urlencode ($ search), $ output, $ this -> _ apiKey);
$ ch = curl_init ($ url);
curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, true);
$ response = curl_exec ($ ch);
curl_close ($ ch);
return $ response;
}
}
Now we are closely engaged in the implementation of the lookup () method. In the beginning, we will get a response from the server using the performRequest () method, create an object of the SimpleXMLELement class. Next, we read the status of the request returned by the server. The normal request will be G_GEO_SUCCESS, G_GEO_UNKNOWN_ADDRESS or G_GEO_UNAVAILABLE_ADDRESS. The last two values will show that no specified locations were found, in this case an empty array will be returned.
If the status code is G_GEO_SUCCESS, we will cycle through the found places and create Placemark objects for each ... We will write the FromSimpleXml () method to create an object of the Placemark class.
For all other status codes, we will create an exception.
class Geocoder
{
public function lookup ($ search)
{
$ response = $ this-> performRequest ($ search, "xml");
$ xml = new SimpleXMLElement ($ response);
$ status = (int) $ xml-> Response-> Status-> code;
switch ($ status)
{
case self :: G_GEO_SUCCESS:
require_once ("Placemark.php");
$ placemarks = array ();
foreach ($ xml-> Response-> Placemark as $ placemark)
$ placemarks [] = Placemark :: FromSimpleXml ($ placemark);
return $ placemarks;
case self :: G_GEO_UNKNOWN_ADDRESS:
case self :: G_GEO_UNAVAILABLE_ADDRESS:
return array ();
default:
throw new Exception (sprintf ("Google Geo error% d occurred", $ status));
}
}
}
This is the complete code for the Geocoder class. If you want to use the performRequest () function, you can do this, but now you need to implement the Placemark class before using the lookup () method.
require_once ("Geocoder.php");
$ address = "1600 Pennsylvania Ave Washington DC";
$ geocoder = new Geocoder ('your key');
$ xml = $ geocoder-> performRequest ($ address, "xml");
$ json = $ geocoder-> performRequest ($ address, "json");
$ csv = $ geocoder-> performRequest ($ address, "csv");
Creating the Placemark Class
Now we are implementing the Placemark class, which will be used to store location information. It is preferable, of course, to save all parts of the address returned from geocoder, we restrict ourselves to saving three elements:
- Latitude and longitude of the place (using the Point class)
- Formatted address returned from geocoder
- Location accuracy
To implement this class, we will write the functions of setting and receiving values (the functions setPoint (), getPoint (), setAddress (), getAddress (), setAccuracy () and getAccuracy ()). We also implement the static FromSimpleXml () method, which is used in the Geocoder class.
In the Placemark class, we will define constants responsible for the accuracy of the location. For example, to determine if only a country is defined, use the following
if ($ placemark-> getAccuracy () == Placemark :: ACCURACY_COUNTRY) {...}
Implementation.
class Placemark
{
const ACCURACY_UNKNOWN = 0;
const ACCURACY_COUNTRY = 1;
const ACCURACY_REGION = 2;
const ACCURACY_SUBREGION = 3;
const ACCURACY_TOWN = 4;
const ACCURACY_POSTCODE = 5;
const ACCURACY_STREET = 6;
const ACCURACY_INTERSECTION = 7;
const ACCURACY_ADDRESS = 8;
protected $ _point;
protected $ _address;
protected $ _accuracy;
}
The Google Maps API does not define named constants for precision.
Next is the definition of the so-called setters and getters, I skip the author's comments.
class Placemark
{
// other code
public function setAddress ($ address)
{
$ this -> _ address = (string) $ address;
}
public function getAddress ()
{
return $ this -> _ address;
}
public function __toString ()
{
return $ this-> getAddress ();
}
public function setPoint (Point $ point)
{
$ this -> _ point = $ point;
}
public function getPoint ()
{
return $ this -> _ point;
}
public function setAccuracy ($ accuracy)
{
$ this -> _ accuracy = (int) $ accuracy;
}
public function getAccuracy ()
{
return $ this -> _ accuracy;
}
// other code
}
At the end, we implement the FromSimpleXml () method, which is a factory method for creating Placemark objects based on the SimpleXMLElement object.
In the example described below, the Point class and its Create () method are used, they will be described below.
class Placemark
{
// other code
public static function FromSimpleXml ($ xml)
{
require_once ('Point.php');
$ point = Point :: Create ($ xml-> Point-> coordinates);
$ placemark = new self;
$ placemark-> setPoint ($ point);
$ placemark-> setAddress ($ xml-> address);
$ placemark-> setAccuracy ($ xml-> AddressDetails ['Accuracy']);
return $ placemark;
}
}
Creating the Point Class
The last class that needs to be implemented for full use is the Point class. This class stores latitude and longitude. This data is transmitted in the constructor; there are also methods for obtaining latitude and longitude values.
class Point
{
protected $ _lat;
protected $ _lng;
public function __construct ($ latitude, $ longitude)
{
$ this -> _ lat = $ latitude;
$ this -> _ lng = $ longitude;
}
public function getLatitude ()
{
return $ this -> _ lat;
}
public function getLongitude ()
{
return $ this -> _ lng;
}
public static function Create ($ str)
{
list ($ longitude, $ latitude, $ elevation) = explode (',', $ str, 3);
return new self ($ latitude, $ longitude);
}
}
Conclusion
This article describes the simplest algorithm for working with geocoder using Google Maps. You can also use the specified classes with JavaScript, but you should also remember that not everyone can have JavaScript enabled.
Also remember that caching geocoder responses will allow you to reduce the load and increase productivity in the future.
References