views:

76

answers:

1

Hey,

I have just been developing a postcode distance calculator for my Dads company, where all our customers are kept on file and every time a new potential customer makes an enquiry the system will check against all other customers' postcodes. The problem is that it doesn't yet do the distance calculation. Typing in a DT1 postcode with the distance set to 5 miles says that DT1, 2 and 3 are close by. DT2 says DT1 and 2, DT3 says DT1, 3 and 4. This doesn't make any sense. Yet if I put in BH2 with a distance of 50 miles it will bring back Bournemouth, Dorchester, Portsmouth, Bath, Southampton and a couple of other towns. These are all correct - however I do not know what is going on with the DT postcodes. DT11 doesn't bring back any (under 5 miles), nor does DT10 (except for themselves).

I first of all used the root of (x * x + y * y) - I believe this is called Pythagoras' theorem.. not sure since it have been years since I used that term!!

I have also tried the following:

  $sinstuff = sin(deg2rad($latitude))*sin(deg2rad($latitude2));
  $cosstuff = cos(deg2rad($latitude))*cos(deg2rad($latitude2))*cos(deg2rad($longitude-$longitude2));
  $sumstuff = $sinstuff + $cosstuff;
  $acosstuff = rad2deg(acos($sumstuff));
  $distance = $acosstuff*60*1.1515; //dunno what the 60 and 1.1515 is all about - I got this formula off a website.

This is the formula which seems to be bringing up the weird results. I also notice that the exact distance between DT11 and DT11 is something like +/- 0.00000989{and lots of other numbers}. This also seems a bit odd since, surely, the distance between DT11 and itself is 0...

Has anyone ever done anything like this successfully before?

I do have a massive batch of files - about 158MB in total - containing every UK postcode in full, with its corresponding latitude and longitude. My aim is, rather than comparing the specified full postcode to every other full postcode, to work out which area codes are less than a certain distance away then compare the specified postcode to all the full postcodes which are within these areas. Is this efficient? Is there a more efficient way?

Any help with this would be greatly appreciated.

Regards,

Richard

PS I know there are some sites out there which tell you how to work out distances but I dont seem to be able to get any of them working correctly (as you can tell from above).

PPS I know I can use the Google API for this - but this is not an option since this is going to be an offline application running on a local installation of wamp server. It is for use at trade shows where we cannot guarantee an internet connection.

+1  A: 

You're use the haversine formula:

$l1 ==> latitude1
$o1 ==> longitude1
$l2 ==> latitude2
$o2 ==> longitude2

(taken from http://www.go4expert.com/forums/showthread.php?t=339)

function haversine ($l1, $o1, $l2, $o2)
{
$l1 = deg2rad ($l1);
$sinl1 = sin ($l1);
$l2 = deg2rad ($l2);
$o1 = deg2rad ($o1);
$o2 = deg2rad ($o2);
return (7926 - 26 * $sinl1) * asin (min (1, 0.707106781186548 * sqrt ((1 - (sin ($l2) * $sinl1) - cos ($l1) * cos ($l2) * cos ($o2 - $o1)))));
}

That should give you the distance between both points.

m1ke
It seems this may have been exactly what I was using, but in a different format. It comes up with the exact same results - DT1 => DT1, 2, 3; DT2 => DT1, 2; DT3 => DT1, 3, 4 etc etc.
ClarkeyBoy
Come to think of it, surely using the root of x * x + y * y should work, shouldnt it? I mean by taking lat1 from lat2 and long1 from long2 you are creating two distances. Using those as two sides of a triangle should give a right angled triangle which you can then use pythags theorem to work out the hypotenuse... Although I suppose there is the conversion of units to consider. Is Lat / Long in metres, per chance? If so then you can just divide by 1000 to get the km or ~1680 to get miles.
ClarkeyBoy
Well I have come up with my own formula - converting lat / long to metres, then doing pythags theorem, then dividing by the number of metres in a mile. It still comes up with exact same result. I am wondering if its the code which decided what results to output which is causing this..
ClarkeyBoy
Hmm I just had a thought... lets suppose DT2 is to the left of DT1, and DT3 is to the right of DT1. This way 2 and 3 would be within 5 miles of 1 but neither 2 nor 3 would be within 5 miles of each other and both would be within 5 miles of 1. I figure this has probably been correct all along...
ClarkeyBoy
Sorry - meant to mark this as the answer ages ago...
ClarkeyBoy