Opened 10 months ago

Closed 9 months ago

#5663 closed defect (duplicate)

ST_GeometryN cannot access sections of CompoundCurve

Reported by: dbaston Owned by: pramsey
Priority: medium Milestone: PostGIS 3.4.3
Component: postgis Version: 3.4.x
Keywords: Cc:

Description (last modified by dbaston)

ST_NumGeometries reports that the following curve has two sub-geometries:

 SELECT ST_NumGeometries('COMPOUNDCURVE (CIRCULARSTRING (0 0, 1 1, 1 0), (1 0, 0 1))'::geometry);
 st_numgeometries 
------------------
                2

However, attempting to access the first section of the curve with ST_GeometryN returns the entire CompoundCurve:

SELECT ST_AsText(ST_GeometryN('COMPOUNDCURVE (CIRCULARSTRING (0 0, 1 1, 1 0), (1 0, 0 1))'::geometry, 1));
                      st_astext                       
------------------------------------------------------
 COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))

This behavior differs from OGR:

from osgeo import ogr
g = ogr.CreateGeometryFromWkt('COMPOUNDCURVE (CIRCULARSTRING (0 0, 1 1, 1 0), (1 0, 0 1))')
g.GetGeometryCount()
# 2
g.GetGeometryRef(1).ExportToWkt()
# LINESTRING (1 0,0 1)

I can see an argument that ST_GeometryN is not intended to return sections of a curve (that must be what #220 proposes to implement), but ST_NumGeometries and ST_GeometryN should at least be consistent.

Change History (9)

comment:1 by dbaston, 10 months ago

Description: modified (diff)

comment:2 by robe, 10 months ago

BTW I complained about this on #5361 when I was working on curved support for ST_AsSVG.

comment:3 by robe, 10 months ago

I hadn't noticed the #220 you dug up. Hah I've been asking for ST_NumCurves and ST_CurveN for 15 years? I feel so old.

comment:4 by pramsey, 9 months ago

Milestone: PostGIS 3.4.2PostGIS 3.4.3

comment:5 by pramsey, 9 months ago

So much yearning for this change! Can I suggest a quick document that lists all the relevant functions and their current and desired behaviour, because it seems like there's a lot of interlocking stuff necessary to make a consistent fix. In addition to ST_GeometryN and ST_NumGeometries, also ST_Dump needs to be harmonious. Are there others?

comment:6 by robe, 9 months ago

@pramsey, I think I documented most of the affected on #5361

I'm thinking though the best thing to do is not bother trying to change existing behavior just yet, at least not backport such change, but introduce an ST_CurveN and ST_NumCurves as that's pretty clear what those should return.

comment:7 by pramsey, 9 months ago

Ack, how "user resistant" should these be… like, ST_NumCurves(linestring) should be 1. And ST_NumCurves(polygon) … should be equal to ST_NumRings(polygon) ? The narrowest version of this would only return an answer for CompoundCurve inputs, but it seems like it's not impossible to say that ST_CurvePolygon could return an ST_NumCurves answer, if we wanted (sum of subparts of all rings).

comment:8 by dbaston, 9 months ago

ST_NumCurves(linestring) should be 1

NumCurves is actually more like NumSegments. Here are some examples from MS SQL (which I assume is following ISO)

"SELECT geometry::Parse('LINESTRING (0 0, 1 1, 2 2)').STNumCurves()"

           
-----------
          2

"SELECT geometry::Parse('CIRCULARSTRING (0 0, 1 1, 2 2)').STNumCurves()"

           
-----------
          1

And corresponding ST_CurveN calls:

"SELECT geometry::Parse('LINESTRING (0 0, 1 1, 2 2)').STCurveN(2).ToString()"

                                                                                                                                                                                                                                                                
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
LINESTRING (1 1, 2 2)                                                                                                                                                                                            
"SELECT geometry::Parse('CIRCULARSTRING (0 0, 1 1, 2 2)').STCurveN(1).ToString()"

                                                                                                                                                                                                                                                                
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
CIRCULARSTRING (0 0, 1 1, 2 2)    
Last edited 9 months ago by dbaston (previous) (diff)

comment:9 by robe, 9 months ago

Resolution: duplicate
Status: newclosed

I'm going to close this out as a duplicate of #5361 but I'll take the mention of ST_NumCurves out of that as it's already a ticket item in #220 (I've pushed that one to 3.5 from fund me), we can push back if we don't get to it.

Note: See TracTickets for help on using tickets.