<?php
    
class Maps {
        private 
$lat;
        private 
$long;
        private 
$postCode;

        private 
$domain;
        private 
$apiKey;

        public function 
__construct($apiKey$domain false) {
            
$this->apiKey $apiKey;
            if (!
$domain) {
                
$this->domain '.co.uk';
            } else {
                
$this->domain $domain;
            }
        }

        public function 
getLatitude() {
            if (!
$this->lat) {
                return 
false;
            }
            return 
$this->lat;
        }

        public function 
getLong() {
            if (!
$this->long) {
                return 
false;
            }
            return 
$this->long;
        }

        public function 
getPostCode() {
            if (!
$this->postCode) {
                return 
false;
            }
            return 
$this->postCode;
        }

        public function 
setPostCode($postCode) {
            
$this->postCode $this->formatPostCode($postCode);
            return 
$this->postCodeToCoords();
        }

        private function 
postCodeToCoords() {
            try {
                if (!
$this->postCode) {
                    throw new 
Exception('No postcode set!');
                }

                
$url 'http://maps.google' $this->domain '/maps/geo?q=' urlencode($this->postCode) . "&output=json&key=" $this->apiKey;
                
$json = @file_get_contents($url);
                if (!
$json) {
                    throw new 
Exception('Unable to download data from google maps.');
                }

                
$data json_decode(str_replace('&quot;''"'htmlentities($json)));

                if (
$data->Placemark[0]->Point->coordinates[1] === false) {
                    throw new 
Exception('Unable to locate coordinate data (latitude) for ' $this->postCode);
                }

                if (
$data->Placemark[0]->Point->coordinates[0] === false) {
                    throw new 
Exception('Unable to locate coordinate data (longitude) for ' $this->postCode);
                }

                
$this->long $data->Placemark[0]->Point->coordinates[0];
                
$this->lat $data->Placemark[0]->Point->coordinates[1];
                return 
true;
            } catch (
Exception $e) {
                return 
false;
            }
        }

        private function 
formatPostCode($postCode) {
            
$originalPostCode $postCode;

            
$matchGroups = array();
            
$matchGroups[] = '[a-pr-uwyz]';
            
$matchGroups[] = '[a-hk-y]';
            
$matchGroups[] = '[abd-hjlnpq-uw-z]';

            
$patterns = array();
            
$patterns[] = '/^(' $matchGroups[0] . $matchGroups[1] . '?\d{1,2})(\d' $matchGroups[2] . '{2})$/i';
            
$patterns[] = '/^(' $matchGroups[0] . '\d[a-hjkstuw])(\d' $matchGroups[2] . '{2})$/i';
            
$patterns[] = '/^(' $matchGroups[0] . $matchGroups[1] . '\d[abehmnprvwxy])(\d' $matchgroups[2] . '{2})$/i';
            
$patterns[] = '/^(gir)(0aa)$/i';
            
$patterns[] = '/^(bfpo)(\d{1,4})$/i';
            
$patterns[] = '/^(bfpo)(c\/o\d{1,3})$/i';

            
$postCode str_replace(' '''$postCode);

            foreach (
$patterns as $pattern) {
                
$matches = array();
                if (
preg_match($pattern$postCode$matches)) {
                    
$postCode strtoupper($matches[1] . ' ' $matches[2]);
                    
$postCode str_replace('C/O''c/o '$postCode);
                    return 
$postCode;
                }
            }

            return 
$originalPostCode;
        }
    }
?>