![](/img/trans.png)
[英]PostGIS - Count Points in Polygons (and average their features within the boundaries)
[英]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.