How to find distance between two addresses? (Java server side)
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
Actually, Google does have web services you can use on the server side to achieve this.
First you'll want to use the Geocoding API to translate addresses into latitude/longitude coordinate pairs. You can then use those however you see fit (i.e. against your own database if you are storing those)
If the nearby items you want to find are actual places in the world that Google probably already knows about, you can try Google's new Places API which can give you results within a certain radius.
You should note that the translation from latitude/longitude coordinates to distances does require some math, but I think it is best done locally (on the server your application is running on) rather than being farmed out to some external server since it's only math. Googling produced this.
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
If you are lucky and you are using mysql or postgresql which both are spatial enabled databases you can execute spatial queries against them.For mysql there are spatial extensions and for postgresql there is postgis.
If you decide to go manual please take look at this question for heads up.Also i don't understand how the google places api can help you since you are looking your data within a radius and not google places.
Cheers
Do you want the "As The Crow Flies" (straight line) distance, or driving distance/time?
Mapquest's API seems to be easier as you can just use a query string.
Another option is geocoder.us (or .ca if Canadian)
精彩评论