繁体   English   中英

多边形内的 postGIS 点

[英]postGIS Points within polygons

我正在使用 postgres/postGIS 我有两个表我有兴趣查询:

 table A: contains geometry values as (POINT)  such as (P1, P2,P3,...) 
 table B: contains geometry values as (POLYGON) such as (Polygon 1, polygon 2, ...)

我试图找到每个点位于哪个多边形内。 我最有可能寻找的答案列出了它包含的点和多边形,例如:

观点 多边形
P1 多边形 3
P2 多边形 1

我尝试的是以下内容:

SELECT *
FROM area, points 
WHERE st_intersects(area.polygons, points.point) ;

我收到以下错误: ERROR: ST_Intersects: Operation on mixed SRID geometries (Polygon, 4326),= (Point, 8307)

非常感谢您的帮助。

如上一个答案所述,您无法执行涉及以不同 SRS 编码的几何图形的空间操作。 换句话说,您必须使用ST_Transform ,例如

SELECT * FROM area a
JOIN points p ON ST_Contains(a.polygons, ST_Transform(p.point,4326));

关于索引的观察也很好。 但是,您不一定需要创建更多列才能在不同的 SRS 中使用空间索引。 这意味着您需要 1) 复制列,这取决于几何大小可能会变得非常昂贵,并且 2) 需要大量开销来保持两列同步。 您需要创建一个单独的索引,该索引采用先前转换的坐标,以便在查询时不需要这样做:

CREATE INDEX idx_points_geom_4326 ON points USING gist (ST_Transform(point,4326));

演示: db<>fiddle - 请注意Index Scan using idx_points_geom_4326 on points p

EXPLAIN ANALYSE
SELECT * FROM area a
JOIN points p ON ST_Contains(a.polygons, ST_Transform(p.point,4326));

                                                               QUERY PLAN                                                               
----------------------------------------------------------------------------------------------------------------------------------------
 Nested Loop  (cost=0.14..59.18 rows=1 width=64) (actual time=0.036..0.175 rows=94 loops=1)
   ->  Seq Scan on area a  (cost=0.00..1.01 rows=1 width=32) (actual time=0.004..0.005 rows=1 loops=1)
   ->  Index Scan using idx_points_geom_4326 on points p  (cost=0.14..58.16 rows=1 width=32) (actual time=0.029..0.161 rows=94 loops=1)
         Index Cond: (st_transform(point, 4326) @ a.polygons)
         Filter: st_contains(a.polygons, st_transform(point, 4326))
 Planning Time: 0.064 ms
 Execution Time: 0.193 ms

您无法比较不同空间参考系统中的几何图形,因此您需要转换其中一列以匹配另一列的 SRID。 您可以即时解决此问题:

SELECT *
FROM area, points 
WHERE st_intersects(area.polygons, st_transform(points.point,4326));
--or, dynamically: st_transform(points.point,st_srid(area.polygons))

但这将表现不佳,无法使用索引。 因此,您可以制作一个版本的point列,将点转换为 4326。

alter table points add column point_4326 geometry;
update points set point_4326=st_transform(point,4326);
create index on area using gist(polygons);
create index on points using gist(point_4326);

SELECT *
FROM area, points 
WHERE st_intersects(area.polygons, points.point_4326);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM