Используя 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
}