#4031 closed defect (fixed)
ST_CurveToLine with small tolerance sometimes causes invalid memory alloc request size
Reported by: | kkgeodk | Owned by: | strk |
---|---|---|---|
Priority: | medium | Milestone: | PostGIS 2.4.5 |
Component: | postgis | Version: | 2.4.x |
Keywords: | ST_CurveToLine | Cc: |
Description
ST_CurveToLine([geometry], 0.01, 1, 1) causes ERROR: invalid memory alloc request size 1073741824
Same ERROR with:
ST_CurveToLine([geometry], 0.05, 1, 1)
ST_CurveToLine([geometry], 0.1, 1, 1)
ST_CurveToLine([geometry], 1, 1, 1)
With ST_CurveToLine([geometry], 32, 0, 1), this ERROR cannot be reproduced.
Shared memory segment in bytes has been increased. This did not solve our issue:
# Maximum size of a single shared memory segment in bytes
#kernel.shmmax = 33554432
kernel.shmmax = 3055017984
Find test data attached. object t_id= 1727145 seems to be the issue.
System:
Ubuntu 14.04.5 LTS
PostgreSQL 9.3
PostGIS 2.2 with ST_CurveToLine backport from https://github.com/strk/postgis/tree/svn-2.2-curve-to-line-extended
Attachments (2)
Change History (17)
by , 7 years ago
Attachment: | npl_export added |
---|
comment:1 by , 7 years ago
comment:2 by , 7 years ago
Setting ST_CurveToLine([geometry], 0.01, 1, 1) ist needed due to accuracy requirements of data (cadastral surveying). Optimizations / Fixes in memory allocation possible?
comment:3 by , 7 years ago
Possibly, you could look at the code and see if there's any over-aggressive memory allocation going on
comment:4 by , 7 years ago
Milestone: | PostGIS 2.4.4 → PostGIS 2.5.0 |
---|
comment:5 by , 7 years ago
So the input geometry is a CompoundCurve composed by 39 elements being alternating LineString and CircularString objects. Total length of CompoundCurve is about 180 units. Curves has mostly 3 control points and linestrings 2, with 2 exceptions being a LineString and a CircularString of 13 vertices each.
I confirm running ST_CurveToLine([geometry], 1, 1, 1) as of r16530 fails about invalid memory alloc.
The problem seems to be with the 15th arc, for which PostGIS seems to be unable to compute an angle:
DEBUG: [lwstroke.c:lwarc_linearize:218] lwarc_linearize: maxDiff:1, radius:0.191861, halfAngle:nan, increment:nan (nan degrees)
comment:6 by , 7 years ago
Reduced testcase:
select ST_CurveToLine('CIRCULARSTRING (2730145.49367034 1278364.50230843, 2730145.54567269 1278364.69930594, 2730145.59567509 1278364.89730345, 2730145.59567514 1278364.90030341, 2730145.59667517 1278364.90330337, 2730145.64567761 1278365.10230086, 2730145.6916793 1278365.30129822 )'::geometry, 1, 1, 1);
NOT requesting symmetric output quickly returns a result.
comment:7 by , 7 years ago
It looks like ST_CurveToLine is uninterruptible too, which is something we should look at (maybe in a separate ticket).
Smallest reduction (single-arc):
select ST_CurveToLine('CIRCULARSTRING ( 2730145.59567509 1278364.89730345, 2730145.59567514 1278364.90030341, 2730145.59667517 1278364.90330337 )'::geometry, 1, 1, 1);
by , 7 years ago
comment:9 by , 7 years ago
Ok I know what's happening here. The arc radius is 0.191861, so the sagitta (max distance between arc and cord) can be at most .383722. We're doing the computation using a distance of 1 instead (the tolerance) which results in 1-tolerance/radius to give an invalid input value for acos. This should be fixed by limiting the used value to always be at most the max possible error (arc diameter).
comment:11 by , 7 years ago
@kkgeodk can you confirm r16553 fixes the problem for you ? In the specific case you reported even 0.01 tolerance was too big for that specific arc in the set of curves (there was a very tiny curve in the set). The patch in r16553 would allow you to still use 0.01 (or even 1) as a max deviance w/out that ever being a problem against smaller curves.
Once confirmed, the patch should be backported to all supported branches.
comment:12 by , 7 years ago
by the way, the unguarded code was ported from QGIS, so this bug should still be present there. In case anyone wants to verify and file a ticket on that side too...
comment:13 by , 7 years ago
comment:15 by , 6 years ago
Milestone: | PostGIS 2.5.0 → PostGIS 2.4.5 |
---|---|
Version: | 2.2.x → 2.4.x |
Thanks for testing, backported now to 2.4 branch too
The smaller error tolerance, the higher number of segments will be required to approximate the line. It may of course be too many. How do you suggest to deal with this ? Similar issue exists with ST_Segmentize (for example).