Opened 5 years ago

Closed 4 years ago

#4636 closed defect (fixed)

ST_Subdivide degrade data

Reported by: sirsosp Owned by: strk
Priority: high Milestone: PostGIS GEOS
Component: postgis Version: 2.5.x -- EOL
Keywords: Cc:

Description

I use the ST_Subdivide function very often without problem but for a dataset, I get a completely unexpected degraded result.

Attachments (5)

st_subdivide_bug.PNG (105.3 KB ) - added by sirsosp 5 years ago.
test2_for_stsubdivide_202002071354.sql.zip (4.9 MB ) - added by sirsosp 5 years ago.
input data
test_for_stsubdivide_processed_202002071356.sql.zip (2.6 MB ) - added by sirsosp 5 years ago.
output data
comparison.png (284.8 KB ) - added by strk 4 years ago.
Comparing old and new generation GEOS Overlay outputs
test_for_stsubdivide_processed_overlayng.sql.gz (4.8 MB ) - added by strk 4 years ago.
Processing output with OverlayNG

Change History (22)

by sirsosp, 5 years ago

Attachment: st_subdivide_bug.PNG added

by sirsosp, 5 years ago

input data

by sirsosp, 5 years ago

output data

comment:1 by sirsosp, 5 years ago

here is the SQL Query to reproduce the issue :

DROP TABLE IF EXISTS data_olivier.test_for_stsubdivide_processed;

CREATE TABLE data_olivier.test_for_stsubdivide_processed AS
SELECT  
  ST_Multi(ST_Subdivide(geom,500))::geometry(MultiPolygon , 2154) AS geom,
  cod19niv4,
  cod19niv5
FROM data_olivier.test2_for_stsubdivide
;

comment:2 by strk, 5 years ago

I'm afraid ST_Subdivide uses intersection heavily, which is an algorithm that does not avoid creating new vertices, which in turn is prone to degradation/collapses.

Ideally we'd have an algorithm to only split at vertices, such functionality is currently completely missing from PostGIS core (C implmentation).

comment:3 by sirsosp, 5 years ago

Did you see the screenshot st_subdivide_bug.PNG in attached file ? It seems that there is a kind of snaptogrid.

comment:4 by strk, 5 years ago

Kind of snaptogrid is what you get when floating precision operation can't complete due to some robustness issue (lines almost parallel that intersect, usually).

Even if the problem occurs on a very small portion of the geometry, precision reduction is applied to the whole geometry, incrementally, until the operation succeeds.

in reply to:  2 comment:5 by ledocteur, 5 years ago

Hi, Perhaps our company could help and fund this feature, just let me know how contact. Thx !

Replying to strk:

Ideally we'd have an algorithm to only split at vertices, such functionality is currently completely missing from PostGIS core (C implmentation).

comment:6 by pramsey, 5 years ago

Milestone: PostGIS 2.5.4PostGIS 2.5.5

comment:7 by strk, 5 years ago

I've ticketed #4683 for a ST_SafeSubdivide

comment:8 by pramsey, 5 years ago

The new JTS overlay code is almost complete and will be ready to port shortly. This might provide the reliable intersection required.

comment:9 by robe, 4 years ago

Milestone: PostGIS 2.5.5PostGIS 3.1.0

comment:10 by strk, 4 years ago

Great news. Trying the OverlayNG implementation not only returns a non-degraded output but also does so in 13 seconds rather than 9 minutes !

I'm attaching the resulting subdivided data. And an image comparing old and new generation overlay outputs in a random spot.

by strk, 4 years ago

Attachment: comparison.png added

Comparing old and new generation GEOS Overlay outputs

by strk, 4 years ago

Processing output with OverlayNG

comment:11 by strk, 4 years ago

Owner: changed from pramsey to strk
Status: newassigned

I've enabled debugging of BinaryOp in GEOS to find out what was going on and I found that in one of the recursive intersection cases all the heuristics fail until geometry precision reduction step is entered. The precision reduction starts with a grid of 1e-16 and grows the grid by 10 everytime the intersection fails with a topology exception. The biggest grid eventually succeeding is 1, which is visible in the output as a grid.

This also explains the time difference, as it basically takes 16 attempts only in the precision reduction step, not counting earlier attempts with snapping and common-bits removal...

More stats: precision reduction is engaged 26 times. Of these, 2 times we have to get down to 1 as a grid size (I guess this is due to using the same middle-line for the binary subdivision of the same input polygon). All the other 24 cases work at the very first 1e-16 grid size.

comment:12 by strk, 4 years ago

Interesting enough (Martin, are you reading this?) the OverlayNG code also requires (in a single case) multiple iterations over the precision reduction loop, but succeeds earlier (succeeds at 1e-10).

comment:13 by strk, 4 years ago

The OverlayNGSnapIfNeeded instead succeeds after the first snapping, never entering precision reduction

comment:14 by mdavis, 4 years ago

@strk: good news that OverlayNGSnapIfNeeded works first time. The new snapping heuristic works very well. How does performance compare?

What is the final resolution of this? Are you working on a new ST_Subdivide that will use OverlayNG?

comment:15 by strk, 4 years ago

Performance is great, but it's comparing to the performance of entering the GEOS heuristic so not sure it is a valid comparison.

I'm working on exposing an ST_Subdivide taking a gridSize parameter to opt-in for the OverlayNG (it's an opt-in because of the Z drop)

comment:16 by komzpa, 4 years ago

Milestone: PostGIS 3.1.0PostGIS GEOS

Moving to GEOS milestone as it is expected that 3.9 will fix the issue.

comment:17 by pramsey, 4 years ago

Resolution: fixed
Status: assignedclosed

GEOS 3.9 is released

Note: See TracTickets for help on using tickets.