Как определить расстояние между двумя наборами координат широты/долготы?

Я пытаюсь написать что-то, что определит расстояние между наборами координат lat/lon.

Я использую следующий код, который я нашел на этом сайте:

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

Моя проблема заключается в том, что я сталкиваюсь с ошибкой компиляции: "Имя" toRadians "/" cos "/" sin/"toDegrees не существует в текущем контексте..." Что я делаю неправильно?

Ответ 1

Вы можете использовать следующий класс С#:

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
}

Использование:

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

Источник: Chris Pietschmann - Рассчитайте расстояние между геокодами на С# и JavaScript

Ответ 2

Вы можете написать функцию toRadians следующим образом:

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

Вы можете написать функцию toDegrees следующим образом:

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

Вы должны заменить sin и cos на Math.Sin и Math.Cos.

Ответ 3

Это выглядит как С#.

Сначала вам нужно определить toRadians и 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;
}

Затем, чтобы использовать тригонометрические функции, вам нужно использовать Math.Sin, Math.Cos и т.д.

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

и

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

Комментарии:

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

Что это? Где определены latitude, longitude, destlat и destlon? Кроме того, похоже, что у вас есть lat1, lon1 lat2 и lon2 в качестве параметров этого метода, так что вы не можете определить локали здесь с тем же именем.

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

Это плохой стиль. Если lat1 представляет широту в градусах, гораздо лучше вычислить эквивалентное радиан значение lat1 следующим образом:

double lat1Radians = toRadians(lat1);

Таким образом, замените выше:

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

Наконец:

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

Это тоже плохой стиль. Первая формула и вторая формула не могут оба представить расстояние, которое вы пытаетесь вычислить. Вы должны присвоить результат первой формулы переменной с более значимым именем. В худшем случае, по крайней мере, выполните следующие действия:

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

Я знаю, что этот вопрос действительно старый, но если кто-то наткнется на него, используйте GeoCoordinate из System.Device:

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

Ответ 5

Вычисление расстояния между точками широты и долготы...

double Lat1 = Convert.ToDouble(широта);

    double Long1 = Convert.ToDouble(longitude);

    double Lat2 = 30.678;
    double Long2 = 45.786;
    double circumference = 40000.0; // Earth 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

Вам нужно немного адаптировать этот код.

Как говорит SLaks, вам нужно будет определить свой собственный метод toRadians(), потому что .NET не имеет родной версии.

Вам также необходимо будет изменить вызовы на cos() и sin() следующим образом: Math.Cos() и Math.Sin()