查找经度和纬度最近的位置

我正在处理我需要到达附近位置的应用程序,我的Web服务将收到2个参数(十进制经度,十进制纬度)

我有一个表,其中的位置保存在数据库中的经度和纬度字段,

我想找回最近的位置。

有人可以帮忙吗?

这是我的代码:

var locations = from l in locations select l 

以下是有关此内容的更多详细信息:我在数据库表中有2个字段(十进制(18,2)null)1个纬度,2个经度,

我有一个方法

 public List GetLocation(decimal? Long, decimal? lat) { var Loc = from l in Locations //// now here is how to get nearest location ? how to query? //// i have also tried Math.Abs(l.Lat - lat) its giving error about nullable decimal always hence i have seted decimal to nullable or converted to nullable //// also i have tried where (l.lat - Lat) * (l.lon - Long) this is also giving error about can not convert decimal to bool return Loc.ToList(); } 

您可以先将数据库中的位置数据转换为System.Device.Location.GeoCoordinate ,然后使用LINQ查找最近的数据。

 var coord = new GeoCoordinate(latitude, longitude); var nearest = locations.Select(x => new GeoCoordinate(x.Latitude, x.Longitude)) .OrderBy(x => x.GetDistanceTo(coord)) .First(); 

这是解决方案

 var constValue = 57.2957795130823D var constValue2 = 3958.75586574D; var searchWithin = 20; double latitude = ConversionHelper.SafeConvertToDoubleCultureInd(Latitude, 0), longitude = ConversionHelper.SafeConvertToDoubleCultureInd(Longitude, 0); var loc = (from l in DB.locations let temp = Math.Sin(Convert.ToDouble(l.Latitude) / constValue) * Math.Sin(Convert.ToDouble(latitude) / constValue) + Math.Cos(Convert.ToDouble(l.Latitude) / constValue) * Math.Cos(Convert.ToDouble(latitude) / constValue) * Math.Cos((Convert.ToDouble(longitude) / constValue) - (Convert.ToDouble(l.Longitude) / constValue)) let calMiles = (constValue2 * 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 loc .ToList(); 

要详细说明@Fung的注释,如果您正在使用Entity Framework / LINQ to Entities,如果您尝试在LINQ查询中使用GeoCoordinate.GetDistanceTo方法,您将获得带有消息的运行时NotSupportedException:

LINQ to Entities无法识别方法’Double GetDistanceTo(System.Device.Location.GeoCoordinate)’方法,并且此方法无法转换为商店表达式。

使用Entity Framework版本5或6,另一种方法是使用System.Data.Spatial.DbGeography类。 例如:

 DbGeography searchLocation = DbGeography.FromText(String.Format("POINT({0} {1})", longitude, latitude)); var nearbyLocations = (from location in _context.Locations where // (Additional filtering criteria here...) select new { LocationID = location.ID, Address1 = location.Address1, City = location.City, State = location.State, Zip = location.Zip, Latitude = location.Latitude, Longitude = location.Longitude, Distance = searchLocation.Distance( DbGeography.FromText("POINT(" + location.Longitude + " " + location.Latitude + ")")) }) .OrderBy(location => location.Distance) .ToList(); 

此示例中的_context是您以前实例化的DbContext实例。

虽然它目前在MSDN中没有记录,但DbGeography.Distance方法返回的单位似乎是米。 请参阅: System.Data.Spatial DbGeography.Distance单位?

你有一个有效的范围,除此之外“命中”并不真正相关吗? 如果是这样,请使用

 from l in locations where ((l.lat - point.lat) * (l.lat - point.lat)) + ((l.lng - point.lng) * (l.lng - point.lng)) < (range * range) select l 

然后在这些结果的循环内找到具有最小平方距离值的命中。

 var objAllListing = (from listing in _listingWithLanguageRepository.GetAll().Where(z => z.IsActive == true) let distance = 12742 * SqlFunctions.Asin(SqlFunctions.SquareRoot(SqlFunctions.Sin(((SqlFunctions.Pi() / 180) * (listing.Listings.Latitude - sourceLatitude)) / 2) * SqlFunctions.Sin(((SqlFunctions.Pi() / 180) * (listing.Listings.Latitude - sourceLatitude)) / 2) + SqlFunctions.Cos((SqlFunctions.Pi() / 180) * sourceLatitude) * SqlFunctions.Cos((SqlFunctions.Pi() / 180) * (listing.Listings.Latitude)) * SqlFunctions.Sin(((SqlFunctions.Pi() / 180) * (listing.Listings.Longitude - sourceLongitude)) / 2) * SqlFunctions.Sin(((SqlFunctions.Pi() / 180) * (listing.Listings.Longitude - sourceLongitude)) / 2))) where distance <= input.Distance select new ListingFinalResult { ListingDetail = listing, Distance = distance }).ToList();//.Take(5).OrderBy(x => x.distance).ToList();