Saturday, 14 December 2019

postgresql - How to USE ST_difference AND ST_intersection in case of multipolygons? (PostGIS)


I'm trying to use ST_difference and ST_intersection with two layers of multipolygons.


I want something like:


enter image description here


With the input on the left and the result on the right.


MY DATA:


t1.geom contains 1000 differents polygons.



t2.geom contains 1000 differents polygons.


THE QUERIES:


I try to create (in a naive way) two queries to perform these operations


st_intersection(t1.geom, t2.geom)
from t1,t2
where st_intersects(t1.geom,t2.geom);

where explain return:


"Nested Loop  (cost=0.15..49833.44 rows=149759 width=1796)"
" -> Seq Scan on affectation_com_1 t1 (cost=0.00..1447.85 rows=13085 width=923)"

" -> Index Scan using affectation_com_geom_idx on affectation_com t2 (cost=0.15..0.83 rows=1 width=873)"
" Index Cond: (t1.geom && geom)"
" Filter: _st_intersects(t1.geom, geom)"

AND


st_difference(t1.geom, t2.geom)
from t1,t2
where st_overlaps(t1.geom,t2.geom);

where explain return:



"Nested Loop  (cost=0.15..12768.08 rows=149759 width=1796)"
" -> Seq Scan on oca1032s_affectation_com_1 t1 (cost=0.00..1447.85 rows=13085 width=923)"
" -> Index Scan using oca1032s_affectation_com_geom_idx on oca1032s_affectation_com t2 (cost=0.15..0.83 rows=1 width=873)"
" Index Cond: (t1.geom && geom)"
" Filter: _st_overlaps(t1.geom, geom)"

Unfortunately it doesn't work, or takes forever to run.


I would like a query similar to the tools erase and intersect from ArcGIS.


QUESTION:


How to perform those operations efficiently ?




Answer



I finally found an answer by myself.


For st_difference():


with temp as 
(
select b.gid, st_union(a.geom) as geom
from t1 b join t2 a on st_intersects(a.geom, b.geom)
group by b.gid
)
select st_difference(b.geom,coalesce(t.geom, 'GEOMETRYCOLLECTION EMPTY'::geometry)) as newgeom

from t1 b left join temp t on b.gid = t.gid

It works like a charm and runs fast. The query is similar for st_intersection().


In addition, some of my polygons weren't valid so I corrected the geometry with


update t1
set geom = ST_Multi(ST_CollectionExtract(ST_MakeValid(geom), 3));
update t2
set geom = ST_Multi(ST_CollectionExtract(ST_MakeValid(geom), 3));

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...