Используя LINQ, найдите близлежащие места из базы данных.

Мы хотим получить список близлежащих мест из базы данных, используя LINQ в ASP.NET 2012, и хотели бы получить отзывы о нашей стратегии.


Моя таблица и поддельные данные:

     PlaceId    Name       Latitude   Longitude 
       1          A          18.1        20.1
       2          B          18.2        20.2
       3          C          18.3        20.3

1) В нашем проекте текущее местоположение клиента (широта и долгота) берется в качестве входных данных

2) На стороне сервера, в зависимости от текущего местоположения клиента, нам нужно найти близлежащие места из базы данных, используя LINQ.

Вот код для SQL, который я использовал ранее, но теперь мы хотим использовать LINQ.

SELECT  name, Latitude, Longitude , 
  ( 3959 * acos( cos( radians(?) )* cos( radians( Latitude) ) * cos( radians( Longitude ) - radians(?) ) 
 + sin( radians(?) ) * sin( radians( Latitude) ) ) ) AS distance 
FROM TABLE_NAME 
HAVING distance < ? 
ORDER BY distance LIMIT 0 , 20

[Но вопрос в том, как написать такой запрос в LINQ.]

Моя работа над этим:

При поиске решения я наткнулся на этот код

        var Value1 = 57.2957795130823D;
        var Value2 = 3958.75586574D;

        var searchWithin = 20;

    double latitude = ConversionHelper.SafeConvertToDoubleCultureInd(Latitude, 0),
          longitude = ConversionHelper.SafeConvertToDoubleCultureInd(Longitude, 0);

    var location = (from l in sdbml.Places
                    let temp = Math.Sin(Convert.ToDouble(l.Latitude) / Value1) *  Math.Sin(Convert.ToDouble(latitude) / Value1) +
                             Math.Cos(Convert.ToDouble(l.Latitude) / Value1) *
                             Math.Cos(Convert.ToDouble(latitude) / Value1) *
                             Math.Cos((Convert.ToDouble(longitude) / Value1) - (Convert.ToDouble(l.Longitude) / Value1))
                         let calMiles = (Value2 * Math.Acos(temp > 1 ? 1 : (temp < -1 ? -1 : temp)))
                         where (l.Latitude > 0 && l.Longitude > 0)
                         orderby calMiles
                        select new location
                             {
                                    Name = l.name
                                });
                        return location .ToList();

Но проблема в том, как ссылаться на ConversionHelper или под каким пространством имен он идет.

Все советы приветствуются.

2 ответа

Решение

Вот код, с которым я, наконец, должен согласиться

1) Создать класс, скажем

DistanceModel.cs

public class DistanceModel
{
   public int PlaceId { get; set; }

   public string Name { get; set; }

   public double Latitute { get; set; }

   public double Longitude { get; set; }

} 

2) Затем включите приведенный ниже код в любой файл, который вы хотите, скажем,

MainPage.cs

     /*Call GetAllNearestFamousPlaces() method to get list of nearby places depending 
      upon user current location.
      Note: GetAllNearestFamousPlaces() method takes 2 parameters as input
     that is GetAllNearestFamousPlaces(user_current_Latitude,user_current_Longitude) */


   public void GetAllNearestFamousPlaces(double currentLatitude,double currentLongitude)
    {
        List<DistanceModel> Caldistance = new List<DistanceModel>();
        var query = (from c in sdbml.Places
                     select c).ToList();
        foreach (var place in query)
        {
            double distance = Distance(currentLatitude, currentLongitude, place.Latitude, place.Logitude);
            if (distance < 25)          //nearbyplaces which are within 25 kms 
            {
                DistanceModel dist = new DistanceModel();
                dist.Name = place.PlaceName;
                dist.Latitute = place.Latitude;
                dist.Longitude = place.Logitude;
                dist.PlaceId = place.PlaceId;
                Caldistance.Add(getDiff);
            }
        }                      
    }

   private double Distance(double lat1, double lon1, double lat2, double lon2)
    {
        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) / 0.6213711922;          //miles to kms
        return (dist);
    }

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

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

Это сработало для меня, надеюсь, это поможет вам.

Итак, если все, что вам нужно, это рассчитать расстояние между двумя координатами, почему бы вам не использовать Dot Net GeoCoordinate?

это идет что-то вроде

 var firstCordinate = new GeoCoordinate(latitude1, longitude1);
 var secondCordinate = new GeoCoordinate(latitude2, longitude2);

 double distance = firstCordinate.GetDistanceTo(secondCordinate);

вы можете найти его в пространстве имен System.Device.Location,

Так что это спасет вас от всех этих Math.Cos а также Math.Sin и ваш linq будет простым и понятным. (вероятно, цикл foreach подойдет)

Таким образом, весь ваш запрос может быть обобщен как:

List<Location> locations = new List<Location>();
foreach(var place in sdbml.Places)
{
   //your logic to compare various place's co-ordinates with that of
   //user's current co-ordinate
}
Другие вопросы по тегам