Opened 9 years ago

Last modified 5 years ago

#2429 new defect

Curve lost in conversion

Reported by: strk Owned by: strk
Priority: medium Milestone: PostGIS Fund Me
Component: postgis Version: 2.0.x
Keywords: curves Cc:


with inp as ( SELECT 'CIRCULARSTRING(706817.662 115873.071,706816.112 115870.167,706815.419 115866.95)'::geometry g ) select st_hasarc(st_curvetoline(st_linetocurve(g))) from inp;

The curve is lost when going to line and back to curve. Affected all versions from 1.5 to 2.2.0dev

Attachments (2)

bug2329.png (5.3 KB ) - added by strk 9 years ago.
2429.patch (1.8 KB ) - added by pramsey 7 years ago.
looser tolerance, even segments

Download all attachments as: .zip

Change History (11)

by strk, 9 years ago

Attachment: bug2329.png added

comment:2 by strk, 9 years ago

Keywords: curves added

comment:3 by strk, 9 years ago

The problem here is that the distance computer doesn't consider distance-from-center close enough to be considered the same:

NOTICE:  [lwsegmentize.c:lwline_desegmentize:750] lwline_desegmentize called.
NOTICE:  [lwsegmentize.c:pta_desegmentize:638] i=0, j=3
NOTICE:  [lwsegmentize.c:pt_continues_arc:518] circle_radius=11.872, b_distance=11.872, diff=5.67682e-06, percentage=4.78167e-07
NOTICE:  [lwsegmentize.c:pta_desegmentize:652] pt_continues_arc = false
NOTICE:  [lwsegmentize.c:pta_desegmentize:638] i=1, j=4
NOTICE:  [lwsegmentize.c:pt_continues_arc:518] circle_radius=11.8739, b_distance=11.8739, diff=1.67959e-06, percentage=1.41453e-07
NOTICE:  [lwsegmentize.c:pta_desegmentize:652] pt_continues_arc = false
NOTICE:  [lwsegmentize.c:pta_desegmentize:638] i=2, j=5
NOTICE:  [lwsegmentize.c:pt_continues_arc:518] circle_radius=11.8735, b_distance=11.8735, diff=3.83194e-06, percentage=3.22729e-07
NOTICE:  [lwsegmentize.c:pta_desegmentize:652] pt_continues_arc = false
NOTICE:  [lwsegmentize.c:pta_desegmentize:638] i=3, j=6
NOTICE:  [lwsegmentize.c:pt_continues_arc:518] circle_radius=11.8716, b_distance=11.8716, diff=2.99755e-06, percentage=2.52498e-07
NOTICE:  [lwsegmentize.c:pta_desegmentize:652] pt_continues_arc = false
NOTICE:  [lwsegmentize.c:pta_desegmentize:638] i=4, j=7
NOTICE:  [lwsegmentize.c:pt_continues_arc:518] circle_radius=11.8729, b_distance=11.8729, diff=3.30129e-06, percentage=2.78053e-07
NOTICE:  [lwsegmentize.c:pta_desegmentize:652] pt_continues_arc = false
NOTICE:  [lwsegmentize.c:pta_desegmentize:638] i=5, j=8
NOTICE:  [lwsegmentize.c:pt_continues_arc:518] circle_radius=11.8742, b_distance=11.8742, diff=2.97092e-06, percentage=2.50199e-07
NOTICE:  [lwsegmentize.c:pta_desegmentize:652] pt_continues_arc = false
NOTICE:  [lwsegmentize.c:pta_desegmentize:638] i=6, j=9
NOTICE:  [lwsegmentize.c:pt_continues_arc:518] circle_radius=11.8723, b_distance=11.8723, diff=3.19334e-07, percentage=2.68975e-08
NOTICE:  [lwsegmentize.c:pta_desegmentize:652] pt_continues_arc = false
NOTICE:  [lwsegmentize.c:pta_desegmentize:638] i=7, j=10
NOTICE:  [lwsegmentize.c:pt_continues_arc:518] circle_radius=11.8731, b_distance=11.8731, diff=2.5845e-07, percentage=2.17677e-08
NOTICE:  [lwsegmentize.c:pta_desegmentize:652] pt_continues_arc = false
NOTICE:  [lwsegmentize.c:pta_desegmentize:638] i=8, j=11
NOTICE:  [lwsegmentize.c:pt_continues_arc:518] circle_radius=11.8733, b_distance=11.8733, diff=2.81833e-06, percentage=2.37367e-07
NOTICE:  [lwsegmentize.c:pta_desegmentize:652] pt_continues_arc = false

So, either ST_CurveToLine is too loose or ST_LineToCurve is too picky. Your call, pramsey ?

comment:4 by strk, 9 years ago

Many "flag" curves seems to be affected by this. I think we could really relax the "distance from center" check to consider the difference in the distance in relation to the actual distance (is that the "percentage"?). Tolerating an error of 0.000001% would have made this linearization happily recognized as a curve. Do you think anyone would be disapponted by that ?

comment:5 by robe, 9 years ago

Owner: changed from pramsey to strk

comment:6 by pramsey, 7 years ago

By loosening up the tolerances in pt_continues_arc, I got the following back from the stroke/unstroke round-trip:

COMPOUNDCURVE(CIRCULARSTRING(706817.662 115873.071,706816.251539425 115870.529386906,706815.434658177 115867.142253836),(706815.434658177 115867.142253836,706815.419 115866.95))

Not exactly what you wanted, but a pretty standard result, I think. The angle check in pt_continues_arc will cause the smaller "stubby bits" of a linearization to fail, as they don't have the same regular angle pattern as the identically sized segments that precede them. Trying to figure out a way to make all the segments equal length in a linearization would remove the problem while retaining the check. Or we could remove the check. Depends on if we want to unstroke linearizations that are generated by software other than ourselves.

by pramsey, 7 years ago

Attachment: 2429.patch added

looser tolerance, even segments

comment:7 by pramsey, 7 years ago

The patch above both loosens the tolerances a bit as you suggest and also evens up the output segments produced during stroking, to reduce the variability of radius and angle in the output (allowing the unstroke to succeed more often).

comment:8 by strk, 7 years ago

Milestone: PostGIS 2.2.0PostGIS Future

comment:9 by robe, 5 years ago

Milestone: PostGIS FuturePostGIS Fund Me

Milestone renamed

Note: See TracTickets for help on using tickets.