优化PostGIS中ST_Buffer层交叉的查询

时间:2017-11-05 18:32:11

标签: postgresql postgis intersection

我在PostGIS中存储了两个表: 1.多面体矢量,具有约590000行(layerA)和 2.单个多部分(1行)矢量图层(layerB)

我希望在layerA和layerB中找到每个多边形缓冲区之间的交集区域。到目前为止,我的查询是

SELECT ST_Area(ST_Intersection(a.geom, b.geom)) AS myarea, a.gid AS mygid FROM 
(SELECT ST_Buffer(geom, 500) AS geom, gid FROM layerA) AS a, 
layerB AS b

到目前为止,我可以看到我的查询工作,但我计算它需要17个小时才能完成(使用我的电脑)。有没有其他方法可以更有效,更快地执行此查询?

2 个答案:

答案 0 :(得分:3)

如果在交叉和面积计算之前检查重叠区域的交叉点,可能会缩短时间。

SELECT ST_Area(ST_Intersection(a.geom, b.geom)) AS myarea, a.gid AS mygid FROM 
(SELECT ST_Buffer(geom, 500) AS geom, gid FROM layerA) AS a, 
layerB AS b WHERE ST_intersects(a.geom, b.geom)

答案 1 :(得分:1)

您可能会在gis.stackexchange.com获得更多答案。

你可以做几件事。

你应该确保首先过滤多边形实际上与索引的帮助相交。

在具有许多几何图形的表上放置一个gist索引,并在缓冲的几何图形上使用st_dwithin(geom,500)而不是st_intersects。这是因为缓冲的几何不能使用在未缓冲的几何上计算的索引。

另外,你说你有多个多边形。如果在构建索引之前首先将多边形分割为单个多边形,则每个多面体中实际上有多个多边形可能会获得更快的速度。这将使.index在工作中发挥更大的作用。

由于同样的原因,postgis中实际上有一个函数可以将单个多边形分成更小的部分。 ST_SubDivide

首先使用ST_Dump获取单个多边形:

CREATE table a_singles AS 
SELECT id, (ST_Dump(geom)).geom geom FROM a;

然后创建索引:

CREATE INDEX idx_a_s_geom 
ON a_singles 
USING gist(geom);

最后查询,如

SELECT ST_Area(ST_Intersection(ST_Buffer(a_s.geom,500), b.geom)) 
FROM a_singles AS a_s 
INNER JOIN b 
on ST_DWithin(a_s.geom,b.geom,500);

如果仍然很慢,你可以开始玩ST_SubDivide。

还有一件事。如果表b中的单个多面包含许多几何,也可以将它们拆分并在那里放置一个索引。

在所有这些事情发生后,它可能会很慢。这取决于实际相交的分割多边形中有多少个顶点(对于st_dwithin,还有多边形边界点有重叠边界框的多边形点)

但现在你没有任何索引可以帮助你,所以这应该会让它快得多。