[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