Oct
30
2008

Finding geographical distances between two points in MySQL 5

For a project I’m working on I needed to find the distances between two points to be able to let users ask the application questions like: “How many points of type X (coworkers, jobs, gas stations, donutshops) are within a radius of point y (my home, my office, my previous donut shop). Or what is the nearest point x from point y.

I solved this problem with a stored procedure. Below the click are two stored procedures that achieve the same goal.

In each of these procedures change “TABLE_WITH_POINTS alias” with the table (and it’s alias) that has your geopgraphical points in them. Change “alias.” with the tables alias.

This first one returnes all points y from the initial point x. As indicated by the latitude and longtitude input parameters ordered by distance (in kilometers).

CREATE PROCEDURE distance(IN startlat double, IN startlon double)
BEGIN
	SELECT
	alias.*,
	(
		(
			(acos( sin((startlat*pi()/180))*sin((alias.lat*pi()/180))
				+
			cos((startlat*pi()/180))*cos((alias.lat*pi()/180))
				*
			cos(((startlon - alias.lon)*pi()/180))))*180/pi()
		)*60*1.1515*1.609344
	) as distance
	FROM TABLE_WITH_POINTS alias
	WHERE
		alias.lat IS NOT NULL
	AND
		alias.lon IS NOT NULL
	AND
		alias.lat != ''
	AND
		alias.lon != ''
	ORDER BY distance ASC;
END
$$

The second procedure only gives you the points within the given distance in kilometers

CREATE PROCEDURE distance(IN startlat double, IN startlon double, IN dist int)
BEGIN
	SELECT
	alias.*,
	(
		(
			(acos( sin((startlat*pi()/180))*sin((alias.lat*pi()/180))
				+
			cos((startlat*pi()/180))*cos((alias.lat*pi()/180))
				*
			cos(((startlon - alias.lon)*pi()/180))))*180/pi()
		)*60*1.1515*1.609344
	) as distance
	FROM TABLE_WITH_POINTS alias
	WHERE
		alias.lat IS NOT NULL
	AND
		alias.lon IS NOT NULL
	AND
		alias.lat != ''
	AND
		alias.lon != ''
	HAVING distance < dist
	ORDER BY distance ASC;
END
$$
Written by admin in: code | Tags: , , , ,

4 Comments »

  • Finding geographical distances between two points in MySQL 5…

    [...]For a project I’m working on I needed to find the distances between two points to be able to let users ask the application questions like: “How many points of type X (coworkers, jobs, gas stations, donutshops) are within a radius of point y (m…

    Trackback | October 31, 2008
  • Dave

    Have you considered utilizing the spatial features of MySql … there is a Distance() function that would give you the same result.

    Comment | October 31, 2008
  • Yes I have, and the examples I found look promising. However for a variety of reasons this isn’t a feasibile option for the company. This meant I had to solve it the old-fashioned mathematical way :-)

    With some changes you can run this as a regular query but creating a procedure out of it and idexing the lat/lon fields increases the speed a lot. To check one point against 3000 other records takes only 0.003 seconds on my MacBook.

    Comment | October 31, 2008
  • You can also cache or pre-calculate most of these values and index these pre-calculations. This will make for a huge speed increase.

    I had to write something very similar for work not long ago, I think mines a little different, will try digging it up later and posting back if i can find it.

    Comment | October 31, 2008

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress | Aeros Theme | TheBuckmaker.com WordPress Themes