我有近10,000个相同大小的圆圈,我用它来根据重叠圆圈的数量创建热图。
我有两个版本的第2步正在运行。一个比另一个更有效吗?我应该尝试不同的方法吗?
以下是我试图完成此任务的方法:
获取圈子的轮廓(跑得很快)
create table circle_outlines as SELECT distinct ST_ExteriorRing(the_circle) AS the_geom FROM circle_list; create index idx_geom_circle_outlines on circle_outlines using gist (the_geom); select distinct geometrytype(the_geom) from circle_outlines ; -- LINESTRING
QGIS中此表的输出: 比例为1:38,167,029 - [oi60.tinypic.com/23uwytv.jpg] [2] 以1:234,378的比例进入东北密集区 - [oi59.tinypic.com/96i4xt.jpg][2]
将这些行组合在一起(请参阅帖子的结尾,了解正在考虑的两种方法)
一个。检查创建的geom类型,如果感兴趣(应该是GEOMETRYCOLLECTION)
湾合并边框的多边形化(ST_Dump((ST_Polygonize(the_geom)))
使用ST_PointOnSurface(polygonized_geoms)在内部添加点
计算num_overlaps
我正在尝试的两个步骤:
create table noded_circles as
SELECT ST_Node(ST_Collect(the_geom)) AS the_geom FROM circle_outlines;
-- been running 7 hours - 100% cpu - 2199 MB (24%) memory
和
create table noded_circles as
SELECT ST_Union(the_geom) AS the_geom FROM circle_outlines;
-- been running 43 hours - 100% cpu - 4086 MB (48%) memory
因此,为了“展平”相同大小的交叉圆的线串,st_union()和st_node(st_collect())之间的性能是否存在差异?还有更好的方法吗?
- 更新:由于内存不足,两个查询都被终止了。
答案 0 :(得分:0)
我使用以下内容在10,000乘10,000网格上创建一个10,000点的随机集合,点半径为500.
drop table circles;
create table circles as select g as id,
st_buffer(st_makepoint(random()*10000, random()*10000), 500) as geom
from generate_series(1, 10000) g;
create index ix_spatial_circles on circles using gist(geom);
使用它,我想出了以下查询,该查询生成原始多边形ID列表,与此相交的其他多边形的数量,交叉点和区域。对于10,000个网格上10,000个半径为500的圆形网格,此查询在我们的一个服务器上运行大约20分钟。我不确定是否值得进入硬件细节,因为我怀疑计算的复杂性非常依赖于网格的密度,圆的半径等,因此设置与您的环境完全相同的环境是有问题的。
select id, max(total_intersected) as "total intersected", st_area(st_union(geom)) as area
from
(select a.id as id, array_agg(b.id) as b_int,
sum(case when st_intersects(a.geom, b.geom)='t' then 1 else 0 end) as total_intersected,
array_agg(b.geom) as geom
from
circles a, circles b
where st_intersects(a.geom, b.geom) group by a.id) agg
where id=any(b_int) group by id, geom order by max(total_intersected) desc;
子查询中的主要思想是找到与所有其他多边形相交的所有多边形(通过ID)(使用空间自连接)并构建这些ID的数组(array_agg(b.id)
,作为查找两个多边形是否相交,比找到它们的实际交点更快;然后,在外部查询中,找到实际的交点,但只考虑那些已知为每个输入多边形相交的多边形,即where id=any(b_int)
部分我怀疑这可能比尝试使用ST_Collect或ST_Union一次性结合所有圆(多边形)更快,因为您在已知交叉的多边形上操作,而不是在一个巨大交叉点中的所有多边形。
对于它的价值,我对比较ST_Union(geom)和ST_Node(ST_Collect(geom))的随机点集进行了一些测试,整体上ST_Union的速度略快,但我认为有太多的自由变量这是一个非常科学的发现。
答案 1 :(得分:0)
我最终采用的方法是QGIS中的HeatMap插件。 http://www.qgistutorials.com/en/docs/creating_heatmaps.html 我使用Uniform内核来允许我按栅格的值对重叠的数量进行分类。