如何查询PostGIS数据库,提取指定多边形内的所有用户坐标?
问题解决:PostGIS中筛选多边形内的用户坐标
核心问题分析
- 类型不匹配:你的
user_coordinates.user_coor是PostgreSQL原生point类型,而PostGIS的ST_Contains/ST_Within函数要求两个参数都是PostGIS的geometry类型,因为没有适配原生point的函数重载,所以会提示“函数不存在”。 - SQL语法错误:原语句中
ST_GeomFromText('SRID=4326;POINT(u.user_coor)))是错误的——你把列名u.user_coor写在了字符串常量里,数据库会把它当成字面量文本,而非引用列值,同时还存在引号和括号闭合错误。
解决方案
方案1:修改表结构(推荐,支持空间索引,查询更高效)
把原生point列转换为PostGIS标准的geometry(Point, 4326)类型,并创建空间索引:
-- 添加临时列存储转换后的PostGIS点 ALTER TABLE public.user_coordinates ADD COLUMN user_coor_geom geometry(Point, 4326); -- 将原生point转换为4326坐标系的PostGIS geometry UPDATE public.user_coordinates SET user_coor_geom = ST_SetSRID(ST_MakePoint(user_coor[0], user_coor[1]), 4326); -- (可选)替换原列,统一用PostGIS类型 ALTER TABLE public.user_coordinates DROP COLUMN user_coor; ALTER TABLE public.user_coordinates RENAME COLUMN user_coor_geom TO user_coor; -- 创建空间索引,加速空间查询 CREATE INDEX idx_user_coordinates_user_coor ON public.user_coordinates USING GIST (user_coor);
修改完成后,使用标准空间查询语句:
SELECT u.user_id FROM electorial_boundries e JOIN user_coordinates u ON ST_Contains(e.geom, u.user_coor) WHERE e.id = 595; -- 注意:原语句中的e.org_id在表结构中不存在,请替换为实际存在的列(如e.id/e.data_id)
方案2:查询时实时转换(无需修改表,适合临时查询)
如果不想修改表结构,可在查询中把原生point实时转换为PostGIS geometry:
SELECT u.user_id FROM electorial_boundries e JOIN user_coordinates u ON ST_Contains(e.geom, ST_SetSRID(ST_MakePoint(u.user_coor[0], u.user_coor[1]), 4326)) WHERE e.id = 595; -- 同样注意替换为实际存在的筛选列
额外注意点
- 原语句中的
e.org_id在你提供的electorial_boundries表结构中不存在,需要替换为表中实际存在的列(比如e.id或e.data_id)才能正确筛选指定多边形。 - 当你用实际坐标测试时能得到部分结果但不正确,是因为当时传入的是合法PostGIS geometry类型,但可能存在坐标系不匹配(你的多边形是4326坐标系,需确保测试坐标也用4326)或者逻辑错误。
内容的提问来源于stack exchange,提问作者Ian
相关产品推荐
相关产品推荐

