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

Ash*_*med 28 c# linq

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

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

我想找回最近的位置.

有人可以帮忙吗?

这是我的代码:

 var locations = from l in locations

     select l
Run Code Online (Sandbox Code Playgroud)

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

我有一个方法

public List<Locations>  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();
}
Run Code Online (Sandbox Code Playgroud)

Fun*_*ung 55

您可以先将数据库中的位置数据转换为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();
Run Code Online (Sandbox Code Playgroud)

  • +1很好找!我不得不添加对`System.Device`的引用,但效果很好!很好的代码谢谢! (4认同)
  • @sports不,我不认为LINQ to Entities提供程序支持类型`GeoCoordinate`和方法`GetDistanceTo`.我读到EF6现在支持空间类型,[DbGeography.Distance](http://msdn.microsoft.com/en-us/library/system.data.entity.spatial.dbgeography.distance(v = vs.113). aspx)可能就是你要找的东西. (3认同)
  • 根据[this answer](/sf/answers/2249144831/),应该在`OrderBy`之前调用`AsEnuemrable()`方法,它确实有效:D (2认同)
  • 最终使用 System.Device.Location.Portable 1.0.0 (2认同)

Jon*_*der 6

要详细说明@Fung的注释,如果您正在使用Entity Framework / LINQ to Entities,如果尝试GeoCoordinate.GetDistanceTo在LINQ查询中使用该方法,则将获得运行时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();
Run Code Online (Sandbox Code Playgroud)

_context 在此示例中,是您先前实例化的DbContext实例。

尽管MSDN中当前未记录它,但DbGeography.Distance方法返回的单位似乎是米。请参阅:System.Data.Spatial DbGeography.Distance单位?


Ash*_*med 5

这是解决方案

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();
Run Code Online (Sandbox Code Playgroud)

  • 当前上下文中不存在名称“ConversionHelper”。,怎么解决? (4认同)
  • 什么是常数值? (2认同)