前言

查询附近500米数据,第一反应是用ST_Buffer,但是ST_Buffer文档写了一句话,使用ST_DWithin效率更高。

查询附近500米的餐厅-LMLPHP

ST_Buffer (postgis.net)

ST_DWithin (postgis.net)

数据取点

        我有一种坐标系4326的表ne_10m_admin_0_boundary_lines_land,取gid=1的这条数据,geom是个线串,我们取第一个点-124.75886592699995 48.49401784300004

我们把x坐标-1度,只在这个点附近-125.75886592699995 48.49401784300004

查询附近500米的餐厅-LMLPHP

知识科普

3857坐标系单位是米。

4326坐标系单位是度。

在地球表面,线性距离的计算会受到地球的曲率影响。在赤道附近,一度的经度对应的线性距离大致为111千米。然而,随着你向极地区域移动,每度经度的线性距离会减小。在极地附近,经度线会收缩成一个点,所以在极地附近的地理坐标系下,1度经度的线性距离会变得非常小。

查询附近500米的餐厅-LMLPHP

如图所示,坐标系不同,所以单位也不同 

查询方案1

方案1用的ST_DWithin第1个构造

boolean ST_DWithin(geometry , geometry , double precision g1g2distance_of_srid)

对于几何图形:距离以几何图形的空间参考系统定义的单位指定。 为了使此函数有意义,源几何图形必须位于同一坐标系中(具有相同的 SRID)。需要把坐标系转成3857。如果用4326,他会按照度去计算。

比如-125,使用4326,最后1个参数是1,那么他会按照-125+1去处理。

如果使用3857,他会按照1度约等于110KM去处理。

--查询附近1000*120米附近的数据
SELECT gid,geom
FROM ne_10m_admin_0_boundary_lines_land nmlolp
WHERE ST_DWithin(ST_Transform(geom,3857), ST_Transform('SRID=4326;POINT(-125.75886592699995 48.49401784300004)',3857), 1000 * 120)  
ORDER by gid
limit 10

因为这张表是4326坐标系,由于插入的是几何数据,所以需要坐标系的转换。

如果使用距离<1000 * 120,是查不到这条数据。从而也验证了度和米的转换。

查询方案2

方案2用的ST_DWithin第2个构造

boolean ST_DWithin(geography , geography , double precision , boolean gg1gg2distance_metersuse_spheroid = true);

对于地理:距离测量默认为,单位为米。 为了更快地进行评估,请使用在球体上进行测量。

--查询附近500米附近的数据
select gid,geom
from ne_10m_admin_0_boundary_lines_land nmlolp 
where ST_DWithin(geom::geography,'POINT(-125.75886592699995 48.49401784300004)'::geography,500)

用地理构造的好处是,不需要进行坐标系转换,虽然强转地理类型之后是4326,但是不影响后面米的计算。

11-16 13:46