[postgis-users] Infinite loop in st_intersects - because of incorrect data out of st_transform?
Mark Cave-Ayland
mark.cave-ayland at siriusit.co.uk
Mon Feb 28 07:35:35 PST 2011
On 28/02/11 15:18, Magnus Hagander wrote:
> Hi!
>
> Running the following query locks up postgis completely (in
> geos::algorithm::RobustDeterminant):
>
> SELECT st_intersects(somegeometry,
> '0103000020E61000000100000005000000737979F3DDCC2CC0F92154F9E7534540000000000000F07F000000000000F07F8F806E993F7E55C0304B29FFEA8554400634E8D1DD424540B5FEE6A37FCD4540737979F3DDCC2CC0F92154F9E7534540'::geometry)
>
> I believe this is because there are infinite values in that geometry:
>
> # select ST_AsText('0103000020E61000000100000005000000737979F3DDCC2CC0F92154F9E7534540000000000000F07F000000000000F07F8F806E993F7E55C0304B29FFEA8554400634E8D1DD424540B5FEE6A37FCD4540737979F3DDCC2CC0F92154F9E7534540'::geometry);
>
> st_astext
> ---------------------------------------------------------------------------------------------------------------------------------------------------------------
> POLYGON((-14.4001308522972 42.6555167828373,inf inf,-85.9726317957995
> 82.0924680617579,42.5223944076352 43.6054577711015,-14.4001308522972
> 42.6555167828373))
> (1 row)
>
>
> ISTM that this should either be rejected as an invalid geometry, or at
> least not hang....
Hi Magnus,
Hmmmm - I can definitely reproduce this on trunk with GEOS 3.2 series.
The backtrace from inside GEOS looks like this:
(gdb) bt
#0 0x00007fb17c672525 in
geos::algorithm::RobustDeterminant::signOfDet2x2
(x1=-nan(0x8000000000000), y1=-nan(0x8000000000000),
x2=-nan(0x8000000000000), y2=-nan(0x8000000000000))
at RobustDeterminant.cpp:175
#1 0x00007fb17c6670a0 in geos::algorithm::CGAlgorithms::isCCW
(ring=<value optimized out>) at CGAlgorithms.cpp:163
#2 0x00007fb17c6a0dae in geos::geomgraph::GeometryGraph::addPolygonRing
(this=0x1a27970, lr=0x1a26560, cwLeft=2, cwRight=0) at GeometryGraph.cpp:262
#3 0x00007fb17c6a0f8e in geos::geomgraph::GeometryGraph::addPolygon
(this=0x1a27970, p=0x1a265e0) at GeometryGraph.cpp:288
#4 0x00007fb17c6a16b5 in geos::geomgraph::GeometryGraph::add
(this=0x1a27970, g=0x1a265e0) at GeometryGraph.cpp:183
#5 0x00007fb17c6a1a54 in GeometryGraph (this=0x1a27970, newArgIndex=1,
newParentGeom=0x1a265e0, bnr=...) at GeometryGraph.cpp:522
#6 0x00007fb17c6d74bb in GeometryGraphOperation (this=<value optimized
out>, g0=0x1a26480, g1=0x1a265e0) at GeometryGraphOperation.cpp:59
#7 0x00007fb17c701e16 in RelateOp (this=0xfff80000, g0=0xfff80000,
g1=0x400) at RelateOp.cpp:56
#8 0x00007fb17c701e7f in geos::operation::relate::RelateOp::relate
(a=<value optimized out>, b=<value optimized out>) at RelateOp.cpp:42
#9 0x00007fb17c67e549 in geos::geom::Geometry::intersects
(this=0x1a26480, g=0x1a265e0) at Geometry.cpp:371
#10 0x00007fb17cefa047 in GEOSIntersects_r (extHandle=0x1a1d480,
g1=0x7ff, g2=0x400) at geos_ts_c.cpp:284
Obviously the robust determinant is not as robust as it's name would
suggest ;) AFAICT taking a quick look at the GEOS code, I don't think
it is able to detect the NaNs within x1/y1/x2/y2 as an exit condition
for the main loop, but someone more familiar with the GEOS code should
verify this.
> Now, this geometry actually comes back as the result of st_transform,
> which suggests to me that there is *also* a bug in st_transform, which
> should never output an invalid geometry. It is the result of:
>
> st_transform('0103000020CD0B0000010000000500000099E6673CA2FC2DC1AD7BF5ED45CC534199E6673CA2FC2DC1D7BDFAF6D28960415A06E670D7E94B41D7BDFAF6D28960415A06E670D7E94B41AD7BF5ED45CC534199E6673CA2FC2DC1AD7BF5ED45CC5341',
> 4326)
>
> And that geometry is valid before it goes into st_transform, from what
> I can tell:
> # select st_astext('0103000020CD0B0000010000000500000099E6673CA2FC2DC1AD7BF5ED45CC534199E6673CA2FC2DC1D7BDFAF6D28960415A06E670D7E94B41D7BDFAF6D28960415A06E670D7E94B41AD7BF5ED45CC534199E6673CA2FC2DC1AD7BF5ED45CC5341'::geometry);
>
> st_astext
>
> ----------------------------------------------------------------------------------------------------------------------------------
> ------------------------------------------
> POLYGON((-982609.1179802 5189911.7181081,-982609.1179802
> 8670871.7181081,3658670.8820198 8670871.7181081,3658670.8820198
> 5189911.
> 7181081,-982609.1179802 5189911.7181081))
> (1 row)
>
>
>
> To me this looks like bugs "below" postgis - it's certainly below the
> PostgreSQL level that I know well :-) Not sure if it can be worked
> around/fixed at the postgis level or if it needs to be done in the
> lower level libraries, but either way it shouldn't behave this way :-)
Yeah. The second question here is how did the (Inf Inf) point get into
PostGIS anyway, which I think is a separate bug related to this.
Looking here
(http://trac.osgeo.org/postgis/browser/trunk/postgis/lwgeom_transform.c)
at transform_point(), if PROJ.4 returns an error then *pj_errno_ref
should be set to non-zero but even though the projection result is a
point at infinity, the error code is still returning success.
I think the key thing to knowing whether this part is a PROJ.4 bug or a
PostGIS bug would be to clarify whether PROJ.4's *pj_errno_ref should be
non-zero if a projected point appears at infinity - if yes, it's a
PROJ.4 bug and if no, it's a PostGIS bug because we should detect this
condition and fail the transformation with a suitable error. Frank -
what's your take on this?
ATB,
Mark.
--
Mark Cave-Ayland - Senior Technical Architect
PostgreSQL - PostGIS
Sirius Corporation plc - control through freedom
http://www.siriusit.co.uk
t: +44 870 608 0063
Sirius Labs: http://www.siriusit.co.uk/labs
More information about the postgis-users
mailing list