Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New feature: ST_Segmentize #1755

Open
umartin opened this issue Jan 14, 2025 · 2 comments
Open

New feature: ST_Segmentize #1755

umartin opened this issue Jan 14, 2025 · 2 comments

Comments

@umartin
Copy link
Contributor

umartin commented Jan 14, 2025

It would be nice to have something like https://postgis.net/docs/ST_Segmentize.html to break up large geometries for better partitioning and indexing.

Unfortunately I'm swamped so I won't have time work on this myself in the immediate future.

@jiayuasu
Copy link
Member

@umartin
Copy link
Contributor Author

umartin commented Jan 16, 2025

Since ST_SubDivideExplode splits on vertices it doesn't work on long lines with few vertices. If ST_SubDivideExplode is combined with ST_Segmentize it works better. ST_Segmentize introduces more vertices that ST_SubDivideExplode can split on.

But what I really want is something similar to subdivide but using length instead of max vertices. As described here in the example using a cross lateral join: https://postgis.net/docs/ST_LineSubstring.html

I was able to translate the query to sedona/spark but it's not pretty.

with line as (
    select col1 as id, col2 as sublen, ST_GeomFromWKT(col3) as geom
    from values (1, 50, 'LINESTRING (0 0, 99 99, 100 101)'), -- Length > sublen
                (2, 500, 'LINESTRING (0 0, 0 500)'), -- Length = sublen
                (3, 500, 'LINESTRING (0 0, 100 100)') -- Length < sublen
)
, line_seq as (
    select *, ST_Length(geom) as len, explode(sequence(0, floor(ST_Length(geom) / sublen))) as segment
    from line
)
select id, st_linesubstring(geom, segment * sublen / len, (segment +1) * sublen / len)
from line_seq
-- skip last segment if line length is exact multiple of sublen
where sublen * segment / len != 1.0
1,"LINESTRING (0 0, 35.35533905932738 35.35533905932738)"
1,"LINESTRING (35.35533905932738 35.35533905932738, 70.71067811865476 70.71067811865476)"
1,"LINESTRING (70.71067811865476 70.71067811865476, 99 99, 100 101)"
2,"LINESTRING (0 0, 0 500)"
3,"LINESTRING (0 0, 100 100)"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants