[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