在asp.net core 2和entity framework core 2中查询表中的附近位置

kg7wmglp  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(371)

我正在尝试进行一个查询,在这个查询中,我可以在给定的经度和纬度点的范围内(比如说50英里)找到sql数据库中的所有位置。
我填充了一些post,在post表中有两列,在创建post时存储经度和纬度。以下是table的外观:

我浏览了很多关于如何实现这一点的例子,但似乎它们都不起作用。通过研究我知道asp.net核心不支持 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...
}

这就是我现在如何在前端的谷歌Map上显示点的查询方式:

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);
    }       
}

有人知道如何实现这样的查询吗?

tyg4sfes

tyg4sfes1#

如果您从数据库中提取适合您所需距离圆的正方形的数据,然后在客户端微调到圆中的贴子,怎么样?
根据你最初的数据

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;

然后你可以在数据库中查询广场上的那些帖子,把它们带到客户机上,只保留圈中的那些帖子

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;
}

我用球余弦定律来计算距离,我假设这个距离足够解决这个问题。如果你需要更高的准确度,你可以将公式升级到更复杂的东西,比如哈弗森或文森蒂。

ikfrs5lh

ikfrs5lh2#

他们引入了实体框架核心2.2版的空间数据支持。
你可以看看这个答案。

相关问题