[postgis-tickets] [PostGIS] #3719: Error: Invalid number of points in LinearRing

PostGIS trac at osgeo.org
Fri Mar 24 10:56:56 PDT 2017


#3719: Error: Invalid number of points in LinearRing
-------------------------+---------------------------
  Reporter:  tiiipponen  |      Owner:  pramsey
      Type:  defect      |     Status:  new
  Priority:  medium      |  Milestone:  PostGIS 2.3.3
 Component:  postgis     |    Version:  2.3.x
Resolution:              |   Keywords:
-------------------------+---------------------------

Comment (by tiiipponen):

 I tried to look this a bit more just by looking code, but couldn't find
 anything clear.
 I noticed, that even ST_Intersects does not return error for hole part, it
 actually returns false, which is not right answer. I noticed also, that
 validation shows problem for hole too, so I created simpler example:

 select ST_IsValidDetail(
   ST_GeomFromText(
     'CURVEPOLYGON(
       COMPOUNDCURVE(
         CIRCULARSTRING(
           1.0441 2.9312,1.3959388 2.93601515,1.7478 2.9333
         ), (
           1.7478 2.9333,1.0441 2.9312
         )
       )
     )'
   )
 );

 Result:

 "(f,"IllegalArgumentException: Invalid number of points in LinearRing
 found 3 - must be 0 or >= 4",)"

 I tried to look code and only thing that makes me suspicious is this:
 liblwgeom/lwgeom_geos.c ->
 -> LWGEOM2GEOS(const LWGEOM *lwgeom, int autofix)
 -> LWGEOM *lwgeom_stroked = lwgeom_stroke(lwgeom, 32);
 -> liblwgeom/lwstroke.c -> lwgeom_stroke(const LWGEOM *geom, uint32_t
 perQuad)

 I don't know the stroking value perQuad, but if it is default PostGIS
 value 32, it leads to arc length 0.78 m, which is more than length of
 actual arc 0.71m. That would create straight line as a stroking result of
 that arc and that can give the error message "Invalid number of
 points...".
 I adjusted example coordinates a little so that arc was longer and error
 message disappeared.

 If this is the reason, then this problem is not so easy to fix. We can
 have very short arcs in our data and using same absolute stroking length
 means troubles.
 I would think more, if things could do completely without stroking.
 At least I would use relative stroking compared to arc length.
 As a stroking method, I like most the tolerance method. Tolerance means
 maximum difference between original arc an stroked line.
 I created following code with Python for you to copy (and test!) freely:
 User can give parameters accuracy "tolerance" or number of "vertices" in
 resulting stroked line.

     # If user gave the stroking tolerance, we calculate maximum angle of
 one stroke sector.
     # from equation: cos(angle / 2) = (radius - tolerance) / radius
     # We calculate also minimum count of vertices for whole arc that
 satisfies tolerance.
     if tolerance > 0.0:
         StrokingTolerance = tolerance
         if StrokingTolerance > 2 * r:
             StrokingTolerance = 2 * r
         angleSectorFromTolerance = 2 * math.acos((r - StrokingTolerance) /
 r)
         toleranceVertices = int(abs(angleArc / angleSectorFromTolerance))

     # If user gave exact amount of vertices to use,
     # we use it or we use vertice count calculated from tolerance,
     # which ever is bigger so meaning more accurate
     if vertices > toleranceVertices:
         verticesCount = vertices
     else:
         verticesCount = toleranceVertices

     # Now calculate exact angle of one stroke sector from count of
 vertices
     angleSector = angleArc / (verticesCount + 1)

     if (p1z == p2z) and (p1z == p3z):
         calculateZ = False
         newPointZ = p1z
     else:
         calculateZ = True

     # Calculate vertice points and create line from them
     pointList = [(p1x, p1y)]

     for i in range(1, verticesCount + 1):
         currentAngle = a1 + i * angleSector
         newPointX = cx + r * math.cos(currentAngle)
         newPointY = cy + r * math.sin(currentAngle)
         pointList.append((newPointX, newPointY))

     pointList.append((p3x, p3y))


 Ok. Lots of text and actual error can lie completely somewhere else.
 I wish good luck for solving this, because function ST_Intersects is
 widely used in QGIS, Openlayers, etc. and this error results missing
 geometries and error messages in data that holds arcs.

--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/3719#comment:1>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.


More information about the postgis-tickets mailing list