Я пытаюсь записать что-то, что определит расстояние между к наборам координат 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, не существует в текущем контексте..." Что я делаю неправильно?
Вы можете использовать следующий класс 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
Вы можете написать функцию toRadians
следующим образом:
double ToRadians(double degrees) { return degrees * Math.PI / 180; }
Вы можете написать функцию toDegrees
следующим образом:
double ToDegrees(double radians) { return radians * 180 / Math.PI; }
Вы должны заменить sin
и cos
на Math. Грех
и Математика.Кос
.
Это выглядит как 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;
Вам нужно немного адаптировать этот код.
Как говорит SLaks, вам нужно будет определить свой собственный метод toRadians()
, так как .NET не имеет родной версии.
Вам также нужно будет изменить вызовы на cos() и sin(), чтобы быть: Math.Cos() и Math.Sin()
.