查询ASP.NET Core 2和Entity Framework Core 2中表中的附近位置

我正在尝试查询我可以在我的SQL数据库中查找给定经度和纬度点内的所有位置(比如50英里)。

我填充了一些post,在Post表中我有两列,我在创建post时存储经度和纬度。 以下是该表的外观:

我的SQL Server 2012帖子表

我已经浏览了许多如何尝试实现这一点的例子,但似乎它们只是不起作用。 我知道从研究ASP.NET Core不支持DbGeography ,其他文章刚刚过时。

发现这篇文章 ,但它使用DbGeography ,因此不起作用。

在GitHub上找到了这个: 在这里我只是不知道这是否会起作用。

仅供参考,这是我的Post模型的外观:

 public class Post { public int Id { get; set; } public string Title { get; set; } public double Lat { get; set; } public double Lng { get; set; } public DateTime Created { get; set; } public Category Category { get; set; } public int CategoryId { get; set; } // Other navigation properties... } 

这就是我现在的查询方式,即在前端的Google地图上显示点:

 public class HomeController : Controller { private readonly ApplicationDbContext _context; public HomeController(ApplicationDbContext context) { _context = context; } [HttpGet] public JsonResult GetGalleryLocations() { var data = _context.Posts .Include(c => c.Category) .ToList(); return Json(data); } } 

有没有人对如何实现这样的查询有任何见解?

如果你从数据库中提取适合你所需距离的广场周围的数据,然后在客户端微调到圆圈中的post怎么样?

鉴于您的初始数据

 var myLat = 25.05; var myLon = -80.3; var radiusInMile = 50; 

您可以计算包含该圆的正方形的边界

 var minMilePerLat = 68.703; var milePerLon = Math.Cos(myLat) * 69.172; var minLat = myLat - radiusInMile / minMilePerLat; var maxLat = myLat + radiusInMile / minMilePerLat; var minLon = myLon - radiusInMile / milePerLon; var maxLon = myLon + radiusInMile / milePerLon; 

然后,您可以在数据库中查询广场内的那些post,将它们带到客户端并保留在圈子中的那些post

 var data = _context.Posts .Where(p => (minLat <= p.Lat && p.Lat <= maxLat) && (minLon <= p.Lng && p.Lng <= maxLon)) .AsEnumerable() .Select(p => new { p, Dist = distanceInMiles(myLon, myLat, p.Lng, p.Lat) }) .Where(p => p.Dist <= radiusInMile); 

distanceInMiles函数定义为

 public double ToRadians(double degrees) => degrees * Math.PI / 180.0; public double distanceInMiles(double lon1d, double lat1d, double lon2d, double lat2d) { var lon1 = ToRadians(lon1d); var lat1 = ToRadians(lat1d); var lon2 = ToRadians(lon2d); var lat2 = ToRadians(lat2d); var deltaLon = lon2 - lon1; var c = Math.Acos(Math.Sin(lat1) * Math.Sin(lat2) + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(deltaLon)); var earthRadius = 3958.76; var distInMiles = earthRadius * c; return distInMiles; } 

我使用余弦的球面定律来计算距离,我认为这足以解决这个问题。 如果您需要更高的准确度,可以将公式升级为更复杂的东西,如hasrsine或Vincenty。