如何在Postgres中查询指定经纬度2km半径范围内的空间数据
Postgres POINT类型2km半径范围查询方案
数据类型选型结论
- 存储单点经纬度用
POINT类型是完全正确的选型,不需要替换为POLYGON。POLYGON是面状数据的存储类型,用来存单点属于类型错配,这也是你之前尝试POLYGON方案拿不到正确结果的核心原因。 - 你提到的"GTS函数"为笔误,空间查询依赖PostGIS扩展提供的计算能力,使用前先确认扩展已启用,执行语句:
CREATE EXTENSION IF NOT EXISTS postgis;
前置优化
- 给POINT类型字段创建GIST空间索引,能把范围查询速度提升几个量级,替换语句里的表名、字段名为你的实际业务值即可:
CREATE INDEX idx_your_table_location ON your_table USING GIST(your_point_column);
2km半径查询可直接执行语句
以下语句适配WGS84坐标系(即普通GPS采集的经纬度,SRID编码4326),自动按地球球面计算真实距离,单位为米,不需要手动做经纬度到米的单位换算:
SELECT * FROM your_table WHERE ST_DWithin( -- 把字段转为geography类型,按球面距离计算 your_point_column::geography, -- 替换括号内的经度、纬度为你的目标中心点坐标 ST_SetSRID(ST_MakePoint(目标中心点经度, 目标中心点纬度), 4326)::geography, -- 半径值,单位为米,2000即2km 2000 );
注意:如果你的POINT字段在建表时已经通过
ST_SetSRID绑定了4326坐标系,不需要加::geography强制转换,直接写字段名即可。
关于POLYGON方案的说明
网上提到的POLYGON方案,本质是先绘制一个半径2km的圆形/外接矩形面,再判断点是否落在面内,属于范围查询的另一种实现逻辑,但POLYGON本身是用来存面数据的,强行用它存储单点经纬度会带来额外存储开销,查询效率也低于POINT类型存储方案,不推荐使用。
内容的提问来源于stack exchange,提问作者Achaius
相关产品推荐
相关产品推荐

