This is because i haven’t reached my limit yet. But what you are saying makes sense, if i store the postcodes in a database, it will result in less requests…
The lookup of the distance, should only happen once. Not once per page load, day, summer holiday or full moon.
Once.
Create a background job to lookup all records in your database that do not have the distance between the x -> y already calculated. The job will look up the distance, if found/available/possible and update the record accordingly.
Any look ups which fail will automatically be picked back up on the next run.
If the records postcode changes, clear the distance column too and it auto-magic-tastically will be updated.
If you cannot create a cron job, cache it locally so the external call only happens once.
Bob requests the page, no distance found, look it up, save it, display page. Now, when Joe visits the page, the distance already exists and no external request is made.
[list][]Return data for a postcode
[]Return data for the nearest postcode to a point
[*]Return data for postcodes within x distance (miles) of a postcode or lat/lng[/list]
You could store returned values in a database so that before repeating a request to google, you check your local store of data first - this should reduce your requests. Alternatively, you can switch to using GClientGeocoder client side which means the limit is now applicable per visitor ip rather than server ip.
public function get_distance($from, $to){
$xml = new SimpleXMLElement(
sprintf(
'http://maps.google.com/maps/api/directions/xml?origin=%s&destination=%s&sensor=false',
urlencode($from),
urlencode($to)
)
[B]);[/B]
So basically for each review i loop through and check its postcode against the given input which in this case is “M25”. The first result is “Heaton Park” which has a postcode of “M25 2SW”… If we put this into the xml link like so:
Ok it looks quite difficult to do, but i will start from the beginning and work my way forward…
So first things first, you mentioned i need to get the long and lat values. So i understand why i need to get these values for the given postcode, however what do you mean when you say:
“The starting point is easy, you can manually find that, the second however will need to be ‘found’ by the code…”
Which starting point? And what needs to be found by the code? Once i have these values in my database, i presume i would then need to develop a method where the script calculates how far each Reviews postcode is against the given postcode…
Well, first you need to find a longitude and latitude for the given postcode. The starting point is easy, you can manually find that, the second however will need to be ‘found’ by the code.
Remember though, you’ll only need to do this the once, the long and lat ain’t gonna change so just pop 'em in your database once obtained.
For the reverse GeoCoding you can use a rather funky YQL query such as this. This will find the long and lat for you, now the math begins.
You now have 2 sets of long and lats. To calculate the distance (as the crow flies) you can apply the Great Circle Distance formula which takes into account the curvature of the earth too.
Well what i essentially need is to check the given postcode (By the user in the search box) against a series of “Reviews”… Each review has it’s own postcode so it’s quite simple to pull that out.
I visited that page you have suggested… So lets say the enters “M5 4WT” and i want to check it against “OL12 0JJ”. I would want the results in xml as i can sift through the different nodes to get what i need, such as the distance.
The top results show fine with the distance being shown. But the bottom results show an error saying “lastvalue” is undefined??
Anyway, this is my code:
public function LoadXml($origin, $destination){
$xml = simplexml_load_file("http://maps.google.com/maps/api/directions/xml?origin=".$origin."&destination=".$destination."&sensor=false");
foreach ($xml->xpath('//distance') as $distance):
$lastvalue = $distance->value;
endforeach;
$total = $lastvalue * 0.00062137119;
$total = number_format($total, 2);
return $total;
}
I had a look at code suggested by Anthony, the error i was getting when using that code was because a third parameter was missing? I viewed the link to the documents, and i found this at the very top:
An option for getting the coordinates for postcodes is a think from Ordinance Survey called Code-Point, which has coordianates for each post code, though before you use it you should contact Ordinance Survey to check on licensing, etc for your intended plans. I don’t know how much they will charge for the use of the data.
Another alternative is the Royal Mail PAF but the costs of it, licensing etc is expensive.
If you go for either option it may well pay to contact them and go through with them the relevant options for your intended use and licensing, costs, etc.
Warning: SimpleXMLElement::__construct() [simplexmlelement.–construct]: Entity: line 1: parser error : Start tag expected, ‘<’ not found in /home/migbabie/public_html/classes/PostcodeSearch.class.php on line 24
Warning: SimpleXMLElement::__construct() [simplexmlelement.–construct]: ^ in /home/migbabie/public_html/classes/PostcodeSearch.class.php on line 24
Fatal error: Uncaught exception ‘Exception’ with message ‘String could not be parsed as XML’ in /home/migbabie/public_html/classes/PostcodeSearch.class.php:24 Stack trace: #0 /home/migbabie/public_html/classes/PostcodeSearch.class.php(24): SimpleXMLElement->__construct(‘http://maps.goo…’) #1 /home/migbabie/public_html/search/index.php(36): PostcodeSearch::get_distance(‘M25’, ‘M25 2SW’) #2 {main} thrown in /home/migbabie/public_html/classes/PostcodeSearch.class.php on line 24
It’s not clear from the error message, but are you trying to create the SimpleXMLElement object without telling the class that you are providing a URL (as opposed to an XML string)? See the docs, especially the optional third parameter which defaults to false.
If you’re already doing that, can we see the PHP code?