如何准确存储地理位置数据,在半径范围内进行过滤,并计算距离



我用写新位置

ST_SetSrid(ST_MakePoint(:longitude, :latitude), 4326)

它们保存在"profile".location:下

SRID=4326;POINT(-75.1234 35.1234)

我试图过滤一些:radius内的配置文件(以米为单位),其中:ownLocation是由一组数字组成的位置字符串:

ST_DWithin("profile".location, :ownLocation::geometry, :radius)

然后,当我得到结果并计算它们的距离时:ST_Distance( ST_Transform("profile".location::geometry, 3857::int), ST_Transform(:ownLocation::geometry, 3857::int) ) as distance

将距离从米转换为英里,我的结果有点偏离。假设我将最大半径设置在10英里以内——我返回的距离似乎在0-23英里之间(预计为0-10英里)。

我想知道我在哪里出了问题,有一种感觉,这可能与投影有关,或者我错误地使用了函数。


解决方案后更新:存储为4326,显示距离为3857

存储为4326:

ST_SetSrid(ST_MakePoint(:longitude, :latitude), 4326)

使用geography类型的过滤器,因此它可以接受用户将通过的过滤器半径为米:

ST_DWithin("profile".location::geography, :ownLocation::geography, :radiusInMeters)

显示43263857米的距离(带校正)(https://postgis.net/docs/ST_Distance.html):

ST_Distance(
ST_Transform("profile".location::geometry, 3857),
ST_Transform(:ownLocation::geometry, 3857)
) * cosd(42.3521) as distance

3857不适合计算距离,因为当你离开赤道时,它会引入重要的失真。

相反,您可以使用geography数据类型的ST_Distance

ST_Distance("profile".location::geography,:ownLocation::geography) as distance

关于st_dwithin,它使用的投影单位是度,而不是米。您也可以在此处使用geography数据类型。

EPSG 4326的单位是度,而EPSG 3857的单位是米。

ST_DWithin("profile".location,:ownLocation::geometry,:radius)将以度作为半径,而不是米或英里。

将"profile".location和:ownLocation::geometry转换为3857应该可以工作;

最新更新