Как я могу подключить наименьшее значение int к правильному имени в моей БД, Xamarin Forms

#c# #xamarin #xamarin.forms

#c# #xamarin #xamarin.forms

Вопрос:

В настоящее время я работаю с широтой, lng между разными местоположениями и собираю расстояние между двумя разными точками. Я успешно определяю расстояние между разными точками, где я в настоящее время сортирую их по ближайшему расстоянию (в километре).

Однако я борюсь с тем, чтобы получить правильное имя на правильном расстоянии (которое составляется из двух разных lat, lngs, которые находятся в той же строке, что и имя).

Итак, одна строка в БД выглядит следующим образом (у меня около 10 разных строк с разными местоположениями с их правильной широтой, длиной):

Lat ———— Спг ——— Наименование

45.032 —14.323112—— Исландия

Затем я беру это значение широты, Lng и с помощью приведенного ниже кода получаю текущее положение пользователя в широте, lng, а затем сравниваю расстояние между текущим значением широты пользователя, положением lng, и из него у меня есть значение int, равное километру до ближайшего расстояния.

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

     string thename;

    string areaLat;
    string areaLng;

    double storeLat;
    double storeLng;

    double thedistancebetweenobjects;      

    async void loadareas()
    {
        var locator = CrossGeolocator.Current;
        locator.DesiredAccuracy = 50;
        var position = await CrossGeolocator.Current.GetPositionAsync(10000); //using a plugin that gives me the users current lat, lng. 

        List <int> theInts = new List<int>();

        var getarea = await phpApi.getAreas(); //my db-callout

        foreach (var myitems in getarea["results"])
        {
            thename = myitems["Name"].ToString();

            areaLat = myitems["Lat"].ToString();
            areaLng = myitems["Lng"].ToString();
            storeLat = Double.Parse(areaLat, CultureInfo.InvariantCulture);
            storeLng = Double.Parse(areaLng, CultureInfo.InvariantCulture);

            thedistancebetweenobjects = distance(position.Latitude, position.Longitude,storeLat, storeLng, 'K'); //so the users current position lat   lng, and then the lat (storelat), and lng (storelng) i get from the db.

            int someOtherInt = Convert.ToInt32(thedistancebetweenobjects); //converting double to int

            theInts.Add(someOtherInt);
        }

        int TheSmallestInt = theInts.Min();
        System.Diagnostics.Debug.WriteLine(TheSmallestInt);
        //I succesfully get the smallest int out. But how do I connect this int with the correct name from the db?
    }
  

И это функция, которая принимает два разных значения lat, lng и дает мне результат расстояния в километре:

 private double distance(double lat1, double lon1, double lat2, double lon2, char unit)
    {
        double theta = lon1 - lon2;
        double dist = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2))  
        Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(deg2rad(theta));
        dist = Math.Acos(dist);
        dist = rad2deg(dist);
        dist = dist * 60 * 1.1515;
        if (unit == 'K')
        {
            dist = dist * 1.609344;
        }
        else if (unit == 'N')
        {
            dist = dist * 0.8684;
        }
        return (dist);
    }

    private double deg2rad(double deg)
    {
        return (deg * Math.PI / 180.0);
    }

    private double rad2deg(double rad)
    {
        return (rad / Math.PI * 180.0);
    }
  

Ответ №1:

 string closest = string.Empty;
int dist = int.MaxValue;

foreach (var myitems in getarea["results"])
{
  thename = myitems["Name"].ToString();

  // do all of your calcs here

  int someOtherInt = Convert.ToInt32(thedistancebetweenobjects); 

  // for every loc, check if it is closer than the previous loc
  // if it is, save it's name.  
  if (someOtherInt < dist) {
    dist = someOtherInt;
    closest = thename;
  }

  theInts.Add(someOtherInt);
}
  

Ответ №2:

Я вижу, что вы используете формулу Haversine, которая в данном случае является правильным способом, которым я бы это сделал.

Что я бы сделал, так это перебирал ваш список местоположений, пока вы не дойдете до ближайшего

 List<double> distList = new List<double>(); //Create a list to store distance values
List<cityLocations> locList = new List<cityLocations>();
distList.Add(50000000); // default huge distance to compare against
foreach (var city in cityList)
{
    //diff between longitudes
    double theta = (double)ci.longitude - (double)ll.longitude;
    //harversine implimentation
    double dist = Math.Sin(Utils.deg2rad(ci.latitude)) * Math.Sin(Utils.deg2rad((double)ll.latitude))   Math.Cos(Utils.deg2rad(ci.latitude)) * Math.Cos(Utils.deg2rad((double)ll.latitude)) * Math.Cos(Utils.deg2rad(theta));
    dist = Math.Acos(dist);
    dist = Utils.rad2deg(dist);
    dist = dist * 60 * 1.1515;
    if (dist < distList[0])
    {
        //always keep 1 record in list
        distList.RemoveAt(0);
        distList.Add(dist);
        if (locList.Count > 0)
        {
            locList.RemoveAt(0);
        }
        locList.Add(new cityLocations { cityName = ll.cityName, latitude = ll.latitude, longitude = ll.longitude, country = ll.country });
    }
}
  

Не самый красивый или эффективный способ сделать это любыми способами

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

1. Я заставил это работать с решением Джейсона! Похоже, это тоже работает хорошо!