Dav*_*vid 2 c# asp.net entity-framework geocoding asp.net-core-2.0
我正在尝试进行查询,在其中可以找到 SQL 数据库中给定经度和纬度点(比方说 50 英里)内的所有位置。
我填充了一些帖子,在帖子表中我有两列,用于在创建帖子时存储经度和纬度。该表的外观如下:
我浏览了许多如何尝试实现这一点的示例,但似乎它们不起作用。通过研究我知道 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...
}
Run Code Online (Sandbox Code Playgroud)
这就是我现在执行查询以在前端的 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);
}
}
Run Code Online (Sandbox Code Playgroud)
有谁对如何实现这样的查询有任何见解?
如果您从数据库中提取适合所需距离圆周围的正方形的数据,然后在客户端微调到仅圆中的帖子,怎么样?
给定您的初始数据
var myLat = 25.05;
var myLon = -80.3;
var radiusInMile = 50;
Run Code Online (Sandbox Code Playgroud)
您可以计算包含该圆的正方形的边界
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;
Run Code Online (Sandbox Code Playgroud)
然后,您可以在数据库中查询正方形内的帖子,将它们带到客户端并仅保留圆圈内的帖子
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);
Run Code Online (Sandbox Code Playgroud)
其中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;
}
Run Code Online (Sandbox Code Playgroud)
我使用余弦球面定律来计算距离,我认为这足以解决这个问题。如果您需要更高的准确性,您可以将公式升级为更复杂的公式,例如半正矢或文森蒂。
| 归档时间: |
|
| 查看次数: |
3432 次 |
| 最近记录: |