2010-01-06 16 views
10

J'essaye d'écrire quelque chose qui déterminera la distance entre les ensembles de coordonnées lat/lon.Comment puis-je déterminer la distance entre deux ensembles de coordonnées lattitude/longitude?

J'utilise le code suivant que j'ai trouvé sur 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; 
} 

Mon problème est que je suis en cours d'exécution dans l'erreur de compilation « Le nom « toRadians »/ « cos »/ « sin/» toDegrees 'n'existe pas dans le contexte actuel ... " Qu'est-ce que je fais mal ???

+0

Il utilise probablement C#. – SLaks

+2

Pourquoi appelez-vous 'Convert.ToDouble' sur un' double'? – SLaks

+0

@SLaks: D'accord, j'ai juste remarqué le 'Convert.ToDouble'. – jason

Répondre

24

Vous pouvez utiliser les éléments suivants classe 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 
} 

Utilisation:

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

5

Vous pouvez écrire une fonction toRadians comme ceci:

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

Vous pouvez écrire une fonction toDegrees comme ceci:

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

Vous devez remplacer sin et cos avec Math.Sin et Math.Cos.

+0

Si vous appelez cette fonction souvent, créez deux constantes pour PI/180 et 180/PI si votre code est lent. –

2

Cela ressemble à C#.

D'abord, vous devez définir toRadians et 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; 
} 

Ensuite, pour utiliser les fonctions trigonométriques, vous devez utiliser Math.Sin, Math.Cos, etc.

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

et

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

Commentaires:

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

Qu'est ce que c'est? Où sont latitude, longitude, destlat et destlon définis? En outre, il semble que vous ayez lat1, lon1lat2 et lon2 en tant que paramètres de cette méthode, de sorte que vous ne pouvez pas définir ici des locals avec le même nom.

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

Ceci est de mauvais style. Si lat1 représente une latitude en degrés, il est préférable de calculer une valeur de lat1 comme radians équivalent ceci:

double lat1Radians = toRadians(lat1); 

Par conséquent, remplacez ci-dessus avec:

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

Enfin:

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

C'est aussi un mauvais style. La première formule et la deuxième formule ne peuvent pas représenter la distance que vous essayez de calculer. Vous devez affecter le résultat de la première formule à une variable avec un nom plus significatif.Dans le pire des cas, au moins procédez comme suit:

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; 
+0

Vous n'avez probablement pas besoin de le limiter à moins de 2π. – SLaks

+0

Presque définitivement n'ont pas besoin d'effectuer l'emballage - la latitude et la longitude ont tendance à avoir des gammes décentes =) –

+0

@Jason, vous pourriez sortir avec le temps avec 'double deg = 180 * radians/Mapth.Pi; return (deg% 360) + (deg - Math.Truncate (deg)); ' –

0

Vous allez avoir besoin d'adapter ce code un peu. Comme SLaks, dit, vous devrez définir votre propre méthode toRadians() car .NET n'a pas de version native.

Vous aurez aussi besoin de changer les appels à cos() et sin() être: Math.cos() et Math.sin()

2

Je sais cette quête ion est vraiment vieux, mais au cas où quelqu'un d'autre trébuche à travers cela, utilisez GeoCoordinate de System.Device:

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

Calcul Distance entre Latitude et Longitude ... les 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;