[postgis-devel] URGENT BUGFIX (was: two different geometries with the same Astext)
strk at refractions.net
strk at refractions.net
Mon Jul 25 15:22:20 PDT 2005
Thanks to Miguel de la Fuente I've found and killed a severe
bug in bounding box computation.
EVERY BOUNDING BOX computed by postgis 1.x and cached in
the geometry value is possibly CORRUPTED.
The corruption is due to a precision reduction which could
make the cached bounding box smaller then the associated geometry.
This example shows the problem:
query: SELECT box2d(GeomFromText('MULTIPOINT(5256301.4 6014563.13)'));
result: BOX(5256301.5 6014563,5256301.5 6014563)
As you can see the box is horizontally contained-in the multipoint.
Not all geometry constructors are affected, but many.
GeometryFromText() is an exellent positive.
Version 1.0.3 will be out soon for a fix.
A patch is attached.
NOTE that a simple library-only upgrade WILL NOT fix the cached
bounding boxes.
To fix cached bounding boxes you should either dump/reload your db
OR select addbbox(dropbbox(g)) on EVERY geometry column of EVERY spatial
table, REINDEX every spatial index and run vacuum analyze or
select geometry_stats() depending on pgsql version.
--strk;
-------------- next part --------------
Index: lwgeom/ptarray.c
===================================================================
RCS file: /home/cvs/postgis/postgis/lwgeom/ptarray.c,v
retrieving revision 1.15
diff -U2 -r1.15 ptarray.c
--- lwgeom/ptarray.c 9 Jun 2005 16:01:22 -0000 1.15
+++ lwgeom/ptarray.c 25 Jul 2005 22:19:42 -0000
@@ -126,4 +126,5 @@
int t;
POINT2D pt;
+ BOX3D box;
if (pa->npoints == 0) return 0;
@@ -131,18 +132,20 @@
getPoint2d_p(pa, 0, &pt);
- result->xmin = pt.x;
- result->xmax = pt.x;
- result->ymin = pt.y;
- result->ymax = pt.y;
+ box.xmin = pt.x;
+ box.xmax = pt.x;
+ box.ymin = pt.y;
+ box.ymax = pt.y;
for (t=1; t<pa->npoints; t++)
{
getPoint2d_p(pa, t, &pt);
- if (pt.x < result->xmin) result->xmin = pt.x;
- if (pt.y < result->ymin) result->ymin = pt.y;
- if (pt.x > result->xmax) result->xmax = pt.x;
- if (pt.y > result->ymax) result->ymax = pt.y;
+ if (pt.x < box.xmin) box.xmin = pt.x;
+ if (pt.y < box.ymin) box.ymin = pt.y;
+ if (pt.x > box.xmax) box.xmax = pt.x;
+ if (pt.y > box.ymax) box.ymax = pt.y;
}
+ box3d_to_box2df_p(&box, result);
+
return 1;
}
More information about the postgis-devel
mailing list