How to find distance between two addresses? (Java server side)

Eran Medan picture Eran Medan · Jan 24, 2011 · Viewed 10.7k times · Source

I have a "social" geographic aware application I'm developing, and the million dollar question is how do I list a set of items that are "within X miles" of "my location" since there are million applications that do that, I was surprised to find that only Google Maps API has a free web service for that, and worse, it is only supported if used within a Google Map. So do I have to develop my own distance calculator? is there any free / paid service that will allow me to at least transform an address to a XY coordinate?

I'm sure there is an industry standard solution (either free or commercial) but I'm yet to find it

Answer

Someone Somewhere picture Someone Somewhere · Jan 24, 2011

if you're using SQL (you didn't say)... I think I copied this from the NerdDinner project:

ALTER FUNCTION [dbo].[DistanceBetween] (@Lat1 as real,
                @Long1 as real, @Lat2 as real, @Long2 as real)
RETURNS real
AS
BEGIN

DECLARE @dLat1InRad as float(53);
SET @dLat1InRad = @Lat1 * (PI()/180.0);
DECLARE @dLong1InRad as float(53);
SET @dLong1InRad = @Long1 * (PI()/180.0);
DECLARE @dLat2InRad as float(53);
SET @dLat2InRad = @Lat2 * (PI()/180.0);
DECLARE @dLong2InRad as float(53);
SET @dLong2InRad = @Long2 * (PI()/180.0);

DECLARE @dLongitude as float(53);
SET @dLongitude = @dLong2InRad - @dLong1InRad;
DECLARE @dLatitude as float(53);
SET @dLatitude = @dLat2InRad - @dLat1InRad;
/* Intermediate result a. */
DECLARE @a as float(53);
SET @a = SQUARE (SIN (@dLatitude / 2.0)) + COS (@dLat1InRad)
                 * COS (@dLat2InRad)
                 * SQUARE(SIN (@dLongitude / 2.0));
/* Intermediate result c (great circle distance in Radians). */
DECLARE @c as real;
SET @c = 2.0 * ATN2 (SQRT (@a), SQRT (1.0 - @a));
DECLARE @kEarthRadius as real;
/* SET kEarthRadius = 3956.0 miles */
SET @kEarthRadius = 6376.5;        /* kms */

DECLARE @dDistance as real;
SET @dDistance = @kEarthRadius * @c;
return (@dDistance);
END


ALTER FUNCTION [dbo].[NearestPeople]
    (
    @lat real,
    @long real,
    @maxdist real
    )
RETURNS  TABLE
AS
    RETURN
    SELECT     Person.ID
    FROM       Person
    WHERE dbo.DistanceBetween(@lat, @long, Latitude, Longitude) < @maxdist

I then use these SQL functions from the server like this in C#:

public IQueryable<Person> FindNearbyPeople(float latitude, float longitude, float maxdistance)
{
    var people = from person in FindAllPeople()
                 join i in db.NearestPeople(latitude, longitude, maxdistance)
                 on person.ID equals i.ID
                 select person;

    return people;
}

that tells me who (in this case, people) is close to me within a maximum distance.

this is the free version. I think SQL Server 2008 can perform this with a Geographic package