【问题标题】:EF Core Spatial Data: Query and get distances in metersEF Core 空间数据:以米为单位查询和获取距离
【发布时间】:2020-08-10 14:50:51
【问题描述】:
我可以通过度数查询并获取离客户最近的位置:
serviceQuery = serviceQuery.Where(s => s.Location.Distance(currentLocation) < <degree>)
.OrderBy(s => s.Location.Distance(currentLocation));
位置在 C# 中是 NetTopologySuite.Geometries.Point,在 SQL Server 中是 geography。
如何在查询中提供米而不是度数,并获得米距而不是度数?
在客户端将结果度数转换为米是可以接受的。
【问题讨论】:
标签:
sql-server
asp.net-core
entity-framework-core
spatial
【解决方案1】:
我发现了问题。
PostgreSQL(我们现在正在使用)和可能的其他数据库有两种空间数据类型:几何和地理。
您可以参考这些链接了解更多信息(Link 1、Link 2)。
长话短说,如果您使用地球的纬度/经度,并且您希望计算使用米单位,则需要使用地理类型。
属性:
[Column(TypeName="geography (point)")]
public Point Location { get; set; }
流畅的 API:
builder.Entity<YourEntity>()
.Property(e => e.Location)
.HasColumnType("geography (point)");
如果您不指定,则默认为适用于笛卡尔坐标的 Geometry。
顺便说一下,数据库数据的SRID必须和你用来查询的位置一致。
【解决方案2】:
据我了解,在插入地理坐标时使用哪个 SRID(空间参考系统)很重要。该文档有些帮助:https://docs.microsoft.com/en-us/ef/core/modeling/spatial
我正在将此代码用于 SRID 4326:
public static Point CreatePoint(double latitude, double longitude)
{
// 4326 is most common coordinate system used by GPS/Maps
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
// see https://docs.microsoft.com/en-us/ef/core/modeling/spatial
// Longitude and Latitude
var newLocation = geometryFactory.CreatePoint(new Coordinate(longitude, latitude));
return newLocation;
}
假设您也在 SRID 4326 中创建 currentLocation:
var currentLocation = CreatePoint(...
那么,
var meters = 500;
serviceQuery = serviceQuery
.Where(s => s.Location.Distance(currentLocation) < meters )
.OrderBy(s => s.Location.Distance(currentLocation));
应该工作