EF核心空间数据:以米为单位查询和获取距离



我可以查询并获得离客户端最近的位置,度数为:

serviceQuery = serviceQuery.Where(s => s.Location.Distance(currentLocation) < <degree>)
.OrderBy(s => s.Location.Distance(currentLocation));

位置是C#中的NetTopologySuite.Geometries.Point类型,在SQL Server中为geography类型。

如何在查询中提供米而不是度,并获得米距离而不是度?可以在客户端将结果度数转换为仪表。

我发现了这个问题。

PostgreSQL(我们现在正在使用(和其他数据库可能有两种类型的空间数据:Geometry和Geography。

有关详细信息,可以参考这些链接(链接1、链接2(。

长话短说,如果你使用地球的纬度/经度,并且你希望你的计算使用米单位,你需要使用地理类型。

属性:

[Column(TypeName="geography (point)")]
public Point Location { get; set; }

流利的API:

builder.Entity<YourEntity>()
.Property(e => e.Location)
.HasColumnType("geography (point)");

如果您没有指定,默认值将是用于笛卡尔坐标的"几何体"。

顺便说一下,数据库数据的SRID必须与用于查询的位置相同。

据我所知,插入地理坐标时使用哪个SRID(空间参考系统(很重要。此文档有些帮助:https://learn.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://learn.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));

应该工作

在大多数空间数据库中,空间数据有两种不同的数据类型:

  1. 几何:表示平面笛卡尔平面中的数据。这种类型适用于空间特征位于平面上的场景,如平面图、小规模地图等。当您使用GEOMETRY类型执行距离计算时,返回的单位通常为";空间单位";该平面可以是取决于空间参考系统的任意单元。在大多数情况下,它可能是度,尤其是当您错误地将它用于lat-long值时。

  2. 地理:表示圆形地球表面(球体(上的数据。这种类型是为涉及较大地理区域(如地球上的位置(的场景而设计的。当您使用GEOGRAPHY类型执行距离计算时,它自然会了解地球的曲率,并将返回以米为单位的距离。

从您的问题陈述中,您的一些数据点似乎使用GEOMETRY类型存储,而其他数据点则使用GEOGRAPHY类型存储。解决方案是确保表示地球上位置的所有空间数据都应使用GEOGRAPHY类型存储。通过这样做,距离计算将始终返回以米为单位的值。

最新更新