i have a client who wants me to calculate the distance in miles between cities. I am doing project in PHP, javascript , i have been reading about some long/ lat database but still not able to find where to start and what to use for it. Is there any web service i can query by passing two city names and it can return me the distance in miles or km? please help
问题:
回答1:
http://code.google.com/apis/maps/documentation/javascript/geometry.html#Distance
Distance and Area Functions The distance between two points is the length of the shortest path between them. This shortest path is called a geodesic. On a sphere all geodesics are segments of a great circle. To compute this distance, call computeDistanceBetween(), passing it two LatLng objects.
You may instead use computeLength() to calculate the length of a given path if you have several locations.
To compute the area of polygonal area, call computeArea(), passing the array of LatLng objects defining a closed loop.
If you do not want to maintain a GEO db that maintains the lat/long to a place/city, then you can also use the Google API to retrieve the coordinates for an "address": http://code.google.com/apis/maps/documentation/javascript/services.html#GeocodingRequests
Another option is to use a variation of the Great Circle Calculator implemented in Javascript if you aren't a google fan: http://williams.best.vwh.net/gccalc.htm
回答2:
The non-API solution. This has the advantage you're not reliant on any third-party, which may go down, or cost you, or be rate-limited, slow with responses etc etc.
First convert your locations to lat/longs. You will need a db of cities and co-ords for this, but I imagine this can be found pretty easily. In the UK this data is available from various govt agencies for free. Then with the co-ords you can calculate the distance between them. The below is in java, but should be straight forward to port to javascript (or php):
public static double R_EARTH_EQUATORIAL = 6378137.0;
public static double R_EARTH_POLAR = 6356752.3;
// The shortest dist between two points on a globe. Lat/lngs are in RADIANS
public static double greatCircleDistance(double lat_1, double lng_1, double lat_2, double lng_2) {
double d_lat = lat_1 - lat_2;
double d_lng = lng_1 - lng_2;
double lat_ave = (lat_1 + lat_2) / 2;
double h = haversin(d_lat) + Math.cos(lat_1) * Math.cos(lat_2) * haversin(d_lng);
return 2 * R_EARTH(lat_ave) * Math.asin(Math.pow(h, 0.5));
}
public static double haversin(Double x) {
return Math.pow(Math.sin(x/2),2);
}
// Returns radius of earth at a given latitude
public static double R_EARTH(double latitude) {
double a = R_EARTH_EQUATORIAL;
double b = R_EARTH_POLAR;
double x = latitude;
double p = Math.pow((Math.pow(a,2) * Math.cos(x)),2);
double q = Math.pow((Math.pow(b,2) * Math.sin(x)),2);
double r = Math.pow(a * Math.cos(x),2);
double s = Math.pow(b * Math.sin(x),2);
return Math.pow(((p + q) / (r + s)), 0.5);
}