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

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

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

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 'не существует в текущем контексте ..." Я делаю не так?

Ответы [ 6 ]

25 голосов
/ 06 января 2010

Вы можете использовать следующий класс 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);

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

5 голосов
/ 06 января 2010

Вы можете написать 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.

2 голосов
/ 18 декабря 2014

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

var distanceInMeters = new GeoCoordinate(lat1, lon1)
    .GetDistanceTo(new GeoCoordinate(lat2, lon2));
2 голосов
/ 06 января 2010

Это похоже на 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);

Что это? Где определены 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;
1 голос
/ 17 марта 2016

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

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

    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;
0 голосов
/ 06 января 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...