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

Я пытаюсь записать что-то, что определит расстояние между к наборам координат 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; 
} 

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

10
задан Cœur 5 December 2018 в 06:12
поделиться

4 ответа

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

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

Источник: Крис Питчман - Расчет расстояния между Geocodes на C# и JavaScript

26
ответ дан 3 December 2019 в 14:11
поделиться

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

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

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

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

Вы должны заменить sin и cos на Math. Грех и Математика.Кос.

.
5
ответ дан 3 December 2019 в 14:11
поделиться

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

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

Что это такое? Где определены широта , долгота , 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;
2
ответ дан 3 December 2019 в 14:11
поделиться

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

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

Вам также нужно будет изменить вызовы на cos() и sin(), чтобы быть: Math.Cos() и Math.Sin()

.
0
ответ дан 3 December 2019 в 14:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: