How to best calculate the distance between two cit

2020-07-25 06:45发布

问题:

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);
}