# Wednesday, February 14, 2007

This is a free SQL Server 2000/2005 function that will calculate the distance in miles between 2 latitude/longitude points

The latitude/longitude points are input as decimal degrees, e.g.: 36.098217314. For those that are interested, it uses (a derivation of) the Haversine formula using the Great Circle Sphere earth radius. It can easily be adjusted to return kilometers or any other distance conversion.  Its intended use is to enable geographic (e.g.: zip, address) radius/proximty search by evaluating distance in a query WHERE statement on the table contains latitude and longitude columns.

But, I need code for .NET, not T-SQL!

For the .NETers among you, this can also easily be converted to .NET code -- just remember to use the Math namespace for all the math/trig functions (e.g.: Math.Asin(), Math.Round(), etc.).

CREATE FUNCTION [dbo].[LatLonRadiusDistance] 
(
	@lat1Degrees decimal(15,12),
	@lon1Degrees decimal(15,12),
	@lat2Degrees decimal(15,12),
	@lon2Degrees decimal(15,12)
)
RETURNS decimal(9,4)
AS
BEGIN

	DECLARE @earthSphereRadiusKilometers as decimal(10,6)
	DECLARE @kilometerConversionToMilesFactor as decimal(7,6)
	SELECT @earthSphereRadiusKilometers = 6366.707019
	SELECT @kilometerConversionToMilesFactor = .621371

	-- convert degrees to radians
	DECLARE @lat1Radians decimal(15,12)
	DECLARE @lon1Radians decimal(15,12)
	DECLARE @lat2Radians decimal(15,12)
	DECLARE @lon2Radians decimal(15,12)
	SELECT @lat1Radians = (@lat1Degrees / 180) * PI()
	SELECT @lon1Radians = (@lon1Degrees / 180) * PI()
	SELECT @lat2Radians = (@lat2Degrees / 180) * PI()
	SELECT @lon2Radians = (@lon2Degrees / 180) * PI()

	-- formula for distance from [lat1,lon1] to [lat2,lon2]
	RETURN ROUND(2 * ASIN(SQRT(POWER(SIN((@lat1Radians - @lat2Radians) / 2) ,2)
        + COS(@lat1Radians) * COS(@lat2Radians) * POWER(SIN((@lon1Radians - @lon2Radians) / 2), 2)))
        * (@earthSphereRadiusKilometers * @kilometerConversionToMilesFactor), 4)

END

Sunday, December 30, 2007 1:14:04 PM (Central Standard Time, UTC-06:00)
This looks great. However, have you ever run into any performance problems?
Wednesday, January 02, 2008 11:12:46 AM (Central Standard Time, UTC-06:00)
Nothing noticable for my particular uses.

It is worth noting, however, that if you are running the function inline (inside a query), I would recommend "geographically boxing" the dataset, i.e.: narrowing the WHERE statement with the min/max latitude and longitude. This prevents evaluating the _entire_ dataset where logically there is no chance the latitude/longitude falls within the particular radius.

I created another SQL function to determine this min/max latitude longitude to "box" given the central lat/lon and the radius. If you'd like me to post that function, I'll see if I can dig it up from my archives (was a project for a past employer).

- Troy
Thursday, January 17, 2008 4:48:13 PM (Central Standard Time, UTC-06:00)

Linked this article from my own blog. Very useful function Troy!

http://geekswithblogs.net/TheNinja/archive/2008/01/17/how_to_calculate_the_distance_in_calculate_the_distance_in_miles_between_2_latitude_longitude_points.aspx

The Ninja
Friday, January 18, 2008 1:14:47 PM (Central Standard Time, UTC-06:00)
Thanks! Glad you found it useful.
Troy DeMonbreun
Thursday, April 03, 2008 11:16:54 AM (Central Daylight Time, UTC-05:00)
Awesome function! Saved me a ton of time. Thanks a lot!
Tuesday, May 06, 2008 8:07:45 PM (Central Daylight Time, UTC-05:00)
Thank you. This is a big help. You mentioned that you had a complimentary "box" routine that you might be willing to post. Would be grateful. Best regards.
Tuesday, September 09, 2008 4:52:23 AM (Central Daylight Time, UTC-05:00)
Nice piece of code, thanks.

One nitpick:

SELECT @earthSphereRadiusNauticalMiles = 6366.707019

Those are not nautical miles, but kilometers. That also explains the conversion factor, as a nautical mile is about 1.15 land miles.
Jeroen Kruis
All comments require the approval of the site owner before being displayed.
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: b, blockquote@cite, em, i, strike, strong, sub, sup, u) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview