TransWikia.com

Identifying overlap between linestrings efficiently in PostGIS

Geographic Information Systems Asked by user2887053 on July 22, 2021

My goal is to clip one linestring table to a buffered version of another linestring table, and I want to make sure I’m doing it the most efficient way possible.

The steps are

  • One table is acting as the mask, the other as the table to be clipped
  • Identify rows that intersect between the clipping dataset and the mask which is buffered into a polygon
  • Group the mask rows by the clipping rows they intersect, and merge them into a single linestring group
  • Clip the original table to the buffered and merged mask

This is all done in one call, but I break it out into three variable (I’m using python f strings so you can just replace the variables with the call they represent)

# Identify all rows that intersect
overlap_query= f"""SELECT B.id as uid, A.geometry as geometry 
from mask B, to_be_clipped A 
WHERE st_isvalid(A.geometry) AND st_intersects(ST_Buffer(A.geometry, 15), B.geometry) = true"""

# Group the mask rows by the rows they intersect, collect them and merge them
grouped_query = f"""WITH overlap as ({overlap_query}) 
SELECT uid, ST_LineMerge(st_collectionhomogenize(st_collect(geometry))) as geometry 
FROM overlap GROUP BY uid"""

# Clip the original dataset to the grouped and buffered mask
query = f"""CREATE TABLE clipped AS 
with grouped as ({grouped_query})
SELECT D.uid, st_intersection(st_buffer(C.geometry, 15), D.geometry) as geometry
FROM grouped C, to_be_clipped D
WHERE C.uid = D.id"""

The final call looks like this:

CREATE TABLE clipped AS  with grouped as 
  (WITH overlap as 
    (SELECT B.id as uid, A.geometry as geometry  from mask B, to_be_clipped A  WHERE st_isvalid(A.geometry) AND st_intersects(ST_Buffer(A.geometry, 15), B.geometry) = true)

  SELECT uid, ST_LineMerge(st_collectionhomogenize(st_collect(geometry))) as geometry  FROM overlap GROUP BY uid) 

SELECT D.uid, st_intersection(st_buffer(C.geometry, 15), D.geometry) as geometry FROM grouped C, to_be_clipped D WHERE C.uid = D.id;

How can I do this better?

With a few million rows in each table, this takes about 30 minutes.

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP