How can I determine the distance between two sets

2019-04-05 17:13发布

问题:

I am trying to write something that will determine the distance between to sets of lat/lon coordinates.

I am using the following code which I found on this site:

public static double distance (double lat1, double lon1, double lat2, double lon2) { 
    double lat1 = Convert.ToDouble(latitude);
    double lon1 = Convert.ToDouble(longitude);
    double lat2 = Convert.ToDouble(destlat);
    double lon2 = Convert.ToDouble(destlon);

    double theta = toRadians(lon1-lon2); 
    lat1 = toRadians(lat1); 
    lon1 = toRadians(lon1); 
    lat2 = toRadians(lat2); 
    lon2 = toRadians(lon2); 

    double dist = sin(lat1)*sin(lat2) + cos(lat1)*cos(lat2)*cos(theta); 
    dist = toDegrees(acos(dist)) * 60 * 1.1515 * 1.609344 * 1000; 

    return dist; 
} 

My problem is that I am running into the compile error "The name 'toRadians'/'cos'/'sin/'toDegrees' does not exist in the current context..." What am I doing wrong?

回答1:

You may want to use the following C# class:

public static class GeoCodeCalc
{
    public const double EarthRadiusInMiles = 3956.0;
    public const double EarthRadiusInKilometers = 6367.0;

    public static double ToRadian(double val) { return val * (Math.PI / 180); }
    public static double DiffRadian(double val1, double val2) { return ToRadian(val2) - ToRadian(val1); }

    public static double CalcDistance(double lat1, double lng1, double lat2, double lng2) 
    {
        return CalcDistance(lat1, lng1, lat2, lng2, GeoCodeCalcMeasurement.Miles);
    }

    public static double CalcDistance(double lat1, double lng1, double lat2, double lng2, GeoCodeCalcMeasurement m) 
    {
        double radius = GeoCodeCalc.EarthRadiusInMiles;

        if (m == GeoCodeCalcMeasurement.Kilometers) { radius = GeoCodeCalc.EarthRadiusInKilometers; }
        return radius * 2 * Math.Asin( Math.Min(1, Math.Sqrt( ( Math.Pow(Math.Sin((DiffRadian(lat1, lat2)) / 2.0), 2.0) + Math.Cos(ToRadian(lat1)) * Math.Cos(ToRadian(lat2)) * Math.Pow(Math.Sin((DiffRadian(lng1, lng2)) / 2.0), 2.0) ) ) ) );
    }
}

public enum GeoCodeCalcMeasurement : int
{
    Miles = 0,
    Kilometers = 1
}

Usage:

// Calculate Distance in Miles
GeoCodeCalc.CalcDistance(47.8131545175277, -122.783203125, 42.0982224111897, -87.890625);

// Calculate Distance in Kilometers
GeoCodeCalc.CalcDistance(47.8131545175277, -122.783203125, 42.0982224111897, -87.890625, GeoCodeCalcMeasurement.Kilometers);

Source: Chris Pietschmann - Calculate Distance Between Geocodes in C# and JavaScript



回答2:

You can write a toRadians function like this:

double ToRadians(double degrees) { return degrees * Math.PI / 180; }

You can write a toDegrees function like this:

double ToDegrees(double radians) { return radians * 180 / Math.PI; }

You should replace sin and cos with Math.Sin and Math.Cos.



回答3:

This looks like C#.

First you need to define toRadians and toDegrees:

double toRadians(double degrees) {
    double sign = Math.Sign(degrees);
    while(Math.Abs(degrees) > 360) {
        degrees -= sign * 360;
    }
    return Math.PI * degrees / 180;
}

double toDegrees(double radians) {
    double sign = Math.Sign(radians);
    while(Math.Abs(radians) > 2 * Math.PI) {
        radians -= sign * 2 * Math.PI;
    }
    return 180 * radians / Math.PI;
}

Then, to use the trigonometric functions you need to use Math.Sin, Math.Cos, etc.

double dist = Math.Sin(lat1) * Math.Sin(lat2)
                + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(theta);

and

dist = toDegrees(Math.Acos(dist)) * 60 * 1.1515 * 1.609344 * 1000; 

Comments:

public static double distance (double lat1, double lon1, double lat2, double lon2) { 
double lat1 = Convert.ToDouble(latitude);
double lon1 = Convert.ToDouble(longitude);
double lat2 = Convert.ToDouble(destlat);
double lon2 = Convert.ToDouble(destlon);

What is this? Where are latitude, longitude, destlat and destlon defined? Further, it appears you have lat1, lon1 lat2 and lon2 as parameters to this method so that you can not define locals here with the same name.

double theta = toRadians(lon1-lon2); 
lat1 = toRadians(lat1); 
lon1 = toRadians(lon1); 
lat2 = toRadians(lat2); 
lon2 = toRadians(lon2); 

This is bad style. If lat1 represents a latitude in degrees it is far better to compute a radians-equivalent value of lat1 like this:

double lat1Radians = toRadians(lat1);

Thus replace the above with:

double theta = toRadians(lon1-lon2); 
double lat1Radians = toRadians(lat1); 
double lon1Radians = toRadians(lon1); 
double lat2Radians = toRadians(lat2); 
double lon2Radians = toRadians(lon2);

Lastly:

double dist = sin(lat1) * sin(lat2)
                + cos(lat1) * cos(lat2) * cos(theta); 
dist = toDegrees(acos(dist)) * 60 * 1.1515 * 1.609344 * 1000; 

This is bad style too. The first formula and the second formula can not both possibly represent the distance that you are trying to calculate. You should assign the result of the first formula to a variable with a more meaningful name. As a worst case, at least do the following:

double temp = Math.Sin(lat1) * Math.Sin(lat2)
                + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(theta);
double dist = toDegrees(Math.Acos(dist)) * 60 * 1.1515 * 1.609344 * 1000; 

return dist;


回答4:

I know this question is really old, but in case anyone else stumbles across this, use GeoCoordinate from System.Device:

var distanceInMeters = new GeoCoordinate(lat1, lon1)
    .GetDistanceTo(new GeoCoordinate(lat2, lon2));


回答5:

Calculating Distance between Latitude and Longitude points...

double Lat1 = Convert.ToDouble(latitude);

    double Long1 = Convert.ToDouble(longitude);

    double Lat2 = 30.678;
    double Long2 = 45.786;
    double circumference = 40000.0; // Earth's circumference at the equator in km
    double distance = 0.0;
    double latitude1Rad = DegreesToRadians(Lat1);
    double latititude2Rad = DegreesToRadians(Lat2);
    double longitude1Rad = DegreesToRadians(Long1);
    double longitude2Rad = DegreesToRadians(Long2);
    double logitudeDiff = Math.Abs(longitude1Rad - longitude2Rad);
    if (logitudeDiff > Math.PI)
    {
        logitudeDiff = 2.0 * Math.PI - logitudeDiff;
    }
    double angleCalculation =
        Math.Acos(
          Math.Sin(latititude2Rad) * Math.Sin(latitude1Rad) +
          Math.Cos(latititude2Rad) * Math.Cos(latitude1Rad) * Math.Cos(logitudeDiff));
    distance = circumference * angleCalculation / (2.0 * Math.PI);
    return distance;


回答6:

You're going to need to adapt this code a bit.

As SLaks, says, you will need to define your own toRadians() method because .NET does not have a native version.

You will also need to change the calls to cos() and sin() to be: Math.Cos() and Math.Sin()