首页 > 解决方案 > NetTopologySuite Distance 在 .net Core 3 中返回奇怪的结果

问题描述

在我的 .Net Core 3 API 中,我设置了这样的用户位置:

userDetails.Location = new Point(userDetails.latitude, userDetails.longitude)
{
   SRID = 4326
};

当我尝试让用户进入给定的半径时

double radiusMeters = userSettings.Radius;
var usersWithinRadius = Context.UserDetails.Where(ud => ud.Location.Distance(userDetails.Location) <= radiusMeters).ToList();

例如,当我将半径设置为 75000 米时,用户位置为 (32.600248, 35.1225),它返回一个距离超过 90 公里的点 (31.78562 , 35.115335)

我究竟做错了什么?

标签: c#asp.net-core.net-core-3.0nettopologysuite

解决方案


它返回一个超过 90 公里距离的点

请注意,您传入的参数是纬度和经度,其单位是度数。因此,返回的值不是Meters中的长度。您可能会发现,方法之间的距离(35.1225, 32.600248)(35.115335,31.78562)返回的距离Distance()0.81465950900299355。基本上,它等于:

Math.sqrt((35.1225 -35.115335)*(35.1225 -35.115335) + (32.600248 - 31.78562)*(32.600248 - 31.78562))

如果两点足够接近,则可以将其单位大致视为弧度:

在此处输入图像描述

假设地球是一个完美的球体地球周长40,075.017 km

根据1 度有多远

弧长

我们可以大致计算距离如下:

distance = Circumference * d /360 
    = 40,075.017 km * 0.81465950900299355 / 360 
    = 90.69km

由于Where()条件0.81465950900299355 < 75000true,你会得到一个超过 90 公里距离的点。

请注意,我们假设这两点在这里足够接近。为了计算准确的距离,我们需要在调用该方法(lon,lat)之前将坐标转换为投影坐标系。Distance()

引用自空间数据-EF Core

这意味着,如果您根据经度和纬度指定坐标,一些客户评估的值(例如距离、长度和面积)将以度为单位,而不是米。对于更有意义的值,您首先需要使用 ProjNet4GeoAPI 之类的库将坐标投影到另一个坐标系,然后再计算这些值。


推荐阅读