Geocoding with PHP and the Google Maps API
Creating the Placemark Class
We will now implement the Placemark class, which is used to hold information about a single location. Rather than storing all of the separate address parts that are returned from the geocoder, we will simplify matters by storing only three items of data:
- The latitude and longitude of the placemark (using the Point class, which we will implement later in this article).
- The formatted address as returned by the geocoder.
- The accuracy of the location (that is, whether the location is a specific street address, a region, country or otherwise). The different accuracies were covered earlier in this article.
To implement this class, we will create functions to set and get each of these items. That is, we will implement setPoint(), getPoint(), setAddress(), getAddress(), setAccuracy() and getAccuracy(). We will also implement the static FromSimpleXml() method that is used by the Geocoder class.
The code for this class should reside in a file called Placemark.php. The complete file is available from the article file downloads section.
Listing 11 shows the beginning of the Placemark class, in which we define constants for the different accuracy levels. While we will not be using these values in the class, including them allows you to determine the kind of placemark. For example, to determine whether or not a placemark refers to a country, you could use if ($placemark->getAccuracy() == Placemark::ACCURACY_COUNTRY) { ... } (where $placemark is an instance of Placemark).
When initializing this class we also create properties for the point, address and accuracy value. We define these as protected, allowing you to access these values using the corresponding get and set methods.
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; // other code }
Next we define the methods to manage the address value. Listing 12 shows the setAddress() and getAddress() methods. Additionally, I have defined the __toString() method (which simply returns the return value from getAddress()), thereby allowing you to echo a placemark easily (that is, you can use echo $placemark;, rather than needing to use echo $placemark->getAddress();).
Also note that we cast the $address variable to a string in setAddress(). This is done because in our code it will be passed in from SimpleXML, meaning technically its type will not be a string.
class Placemark { // other code public function setAddress($address) { $this->_address = (string) $address; } public function getAddress() { return $this->_address; } public function __toString() { return $this->getAddress(); } // other code }
Next we implement the setPoint() and getPoint() methods, as shown in Listing 13. The setPoint() method accepts a Point object, while getPoint() returns that object. We will implement the Point class shortly.
class Placemark { // other code public function setPoint(Point $point) { $this->_point = $point; } public function getPoint() { return $this->_point; } // other code }
We now add the setAccuracy() and getAccuracy() methods, which are used to manage the accuracy value returned from the geocoder response. These are shown in Listing 14.
class Placemark { // other code public function setAccuracy($accuracy) { $this->_accuracy = (int) $accuracy; } public function getAccuracy() { return $this->_accuracy; } // other code }
Finally we can implement the FromSimpleXml() method, which is a static factory method that constructs an instance of Placemark based on the SimpleXMLElement object passed to it. Listing 15 shows the code for FromSimpleXml(), which begins by creating an instance of Point based on the coordinates supplied by the geocoder response.
The point, address and accuracy are then set accordingly on the newly created Placemark object, which is then returned. We will cover the creation of the Point class and its Create() method in the next section. For now, all we need to know is that Create() returns an instance of Point.
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; } }
This now completes the Placemark class, which can all be used as is except for the FromSimpleXml() method, which still requires the Point class.


