我可以查询并获得离客户端最近的位置,度数为:
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));
应该工作
在大多数空间数据库中,空间数据有两种不同的数据类型:
-
几何:表示平面笛卡尔平面中的数据。这种类型适用于空间特征位于平面上的场景,如平面图、小规模地图等。当您使用
GEOMETRY
类型执行距离计算时,返回的单位通常为";空间单位";该平面可以是取决于空间参考系统的任意单元。在大多数情况下,它可能是度,尤其是当您错误地将它用于lat-long值时。 -
地理:表示圆形地球表面(球体(上的数据。这种类型是为涉及较大地理区域(如地球上的位置(的场景而设计的。当您使用
GEOGRAPHY
类型执行距离计算时,它自然会了解地球的曲率,并将返回以米为单位的距离。
从您的问题陈述中,您的一些数据点似乎使用GEOMETRY
类型存储,而其他数据点则使用GEOGRAPHY
类型存储。解决方案是确保表示地球上位置的所有空间数据都应使用GEOGRAPHY
类型存储。通过这样做,距离计算将始终返回以米为单位的值。