vineri, 26 aprilie 2013

Find all points within radius from latitude and longitude given (from given point)

I had to use these formulas for a few times now, and the DB performance has to suffer when doing these kinds of searches.
However, i've just recently found a less accurate method, which has a great performance improvement on the database searches, the errors (unwanted results, or false positives) are neglectable in my case.

The SQL:
SELECT * FROM interest locations WHERE latitude BETWEEN @minLatitude AND @maxLatitude AND longitude BETWEEN @minLongitude AND @maxLongitude

The idea is to create a box, or, thinking planar - a square. Imagining the earth be plane (a plane map), the query above searches for all points (latitudes and longitudes) within the square the circumscribes our given radius cirlce.

The minimum and maximum latitudes, we calculate as starting (center) latitude plus/minus result of given radius divided by 111 (111 is the distance of one degree of latitude in Km):
@minLatitude = givenLatitude - givenRadius / 111

The minimum and maximum longitudes, we calculate as starting (center) longitude plus/minus result of given radius divided by 78, or if you want to be more exact, the corresponding DeltaLongitude depending on the given Latitude (0 => 111.320, 15 => 107.551, 30 => 96.486, 45 => 78.847, 60 => 55.800, 75 => 28.902, 90 => 0.0001)
@minLongitude = givenLongitude - givenRadius / longitudesArray[floor(abs(givenLatitude)/15)*15]


The funny name that somebody gave it was: 'thinking inside the box' (more info here: http://stackoverflow.com/questions/1006654/fastest-way-to-find-distance-between-two-lat-long-points , respect to Binary Worrier :).


Surface of circumscribed square / surface of circle = 1.27 (ca. 27% more surface returned [false positives])
Greatest distance error: for 50Km - 20Km, for 100Km - 40Km, for 200Km - 82Km.


The given SQL has great performance improvments, especially because it can use indexes on the latitude or longitude columns, unlike the cosines formula, which does not allow for the database engines to use indexes.

Email subject UTF-8 encoded

I haven't encountered this yet, i've always been able to send email messages WITH utf-8 correctly encoded and displayed characters (umlauts, acutes), but i've also met this technique which renders good results too:
Set your subject's encoding (or another header directive's) like this:
'=?utf-8?B?'.base64_encode($subject).'?='

That means your subject needs to look like:
=?ENCODING?B?base64_encoded_data?=

Pretty easy

Display php email sent subject characters displayed correctly, umlauts.