[postgis-commits] svn - r3022 - trunk/lwgeom

postgis-commits at postgis.refractions.net postgis-commits at postgis.refractions.net
Sun Sep 28 02:03:33 PDT 2008


Author: pramsey
Date: 2008-09-28 02:03:32 -0700 (Sun, 28 Sep 2008)
New Revision: 3022

Modified:
   trunk/lwgeom/lwgeom_functions_analytic.c
   trunk/lwgeom/lwgeom_geos_c.c
   trunk/lwgeom/lwgeom_rtree.c
   trunk/lwgeom/lwgeom_rtree.h
Log:
Update pip shortcut code to be less aggressive in building cache.


Modified: trunk/lwgeom/lwgeom_functions_analytic.c
===================================================================
--- trunk/lwgeom/lwgeom_functions_analytic.c	2008-09-27 08:19:18 UTC (rev 3021)
+++ trunk/lwgeom/lwgeom_functions_analytic.c	2008-09-28 09:03:32 UTC (rev 3022)
@@ -38,13 +38,12 @@
 
 double determineSide(POINT2D *seg1, POINT2D *seg2, POINT2D *point);
 int isOnSegment(POINT2D *seg1, POINT2D *seg2, POINT2D *point);
-int point_in_ring(RTREE_NODE *root, POINT2D *point);
-int point_in_ring_deprecated(POINTARRAY *pts, POINT2D *point);
-int point_in_polygon(RTREE_NODE **root, int ringCount, LWPOINT *point);
-int point_in_multipolygon(RTREE_NODE **root, int polyCount, int ringCount, LWPOINT *point);
-int point_in_polygon_deprecated(LWPOLY *polygon, LWPOINT *point);
-int point_outside_polygon(RTREE_NODE **root, int ringCount, LWPOINT *point);
-int point_outside_polygon_deprecated(LWPOLY *polygon, LWPOINT *point);
+int point_in_ring(POINTARRAY *pts, POINT2D *point);
+int point_in_polygon(LWPOLY *polygon, LWPOINT *point);
+int point_in_multipolygon(LWMPOLY *mpolygon, LWPOINT *point);
+int point_in_ring_rtree(RTREE_NODE *root, POINT2D *point);
+int point_in_polygon_rtree(RTREE_NODE **root, int ringCount, LWPOINT *point);
+int point_in_multipolygon_rtree(RTREE_NODE **root, int polyCount, int ringCount, LWPOINT *point);
 
 
 /*
@@ -1090,7 +1089,7 @@
  * return 1 iff point is inside ring pts
  * return 0 iff point is on ring pts
  */
-int point_in_ring(RTREE_NODE *root, POINT2D *point)
+int point_in_ring_rtree(RTREE_NODE *root, POINT2D *point)
 {
         int wn = 0;
         int i;
@@ -1172,7 +1171,7 @@
  * return 1 iff point is inside ring pts
  * return 0 iff point is on ring pts
  */
-int point_in_ring_deprecated(POINTARRAY *pts, POINT2D *point)
+int point_in_ring(POINTARRAY *pts, POINT2D *point)
 {
         int wn = 0;
         int i;
@@ -1248,7 +1247,7 @@
  * return 0 iff point outside polygon or on boundary
  * return 1 iff point inside polygon
  */
-int point_in_polygon(RTREE_NODE **root, int ringCount, LWPOINT *point)
+int point_in_polygon_rtree(RTREE_NODE **root, int ringCount, LWPOINT *point)
 {
         int i;
         POINT2D pt;
@@ -1258,18 +1257,18 @@
         getPoint2d_p(point->point, 0, &pt);
         /* assume bbox short-circuit has already been attempted */
         
-        if(point_in_ring(root[0], &pt) != 1) 
+        if(point_in_ring_rtree(root[0], &pt) != 1) 
         {
-                LWDEBUG(3, "point_in_polygon: outside exterior ring.");
+                LWDEBUG(3, "point_in_polygon_rtree: outside exterior ring.");
 
                 return 0;
         }
 
         for(i=1; i<ringCount; i++)
         {
-                if(point_in_ring(root[i], &pt) != -1)
+                if(point_in_ring_rtree(root[i], &pt) != -1)
                 {
-                        LWDEBUGF(3, "point_in_polygon: within hole %d.", i);
+                        LWDEBUGF(3, "point_in_polygon_rtree: within hole %d.", i);
 
                         return 0;
                 }
@@ -1288,13 +1287,13 @@
  * EIIIEIIIEIEI order (exterior/interior) and including list of exterior ring 
  * positions on the cache object.
  */
-int point_in_multipolygon(RTREE_NODE **root, int polyCount, int ringCount, LWPOINT *point)
+int point_in_multipolygon_rtree(RTREE_NODE **root, int polyCount, int ringCount, LWPOINT *point)
 {
     int i;
     POINT2D pt;
     int result = -1;
 
-    LWDEBUGF(2, "point_in_multipolygon called for %p %d %d %p.", root, polyCount, ringCount, point);
+    LWDEBUGF(2, "point_in_multipolygon_rtree called for %p %d %d %p.", root, polyCount, ringCount, point);
 
     getPoint2d_p(point->point, 0, &pt);
     /* assume bbox short-circuit has already been attempted */
@@ -1302,11 +1301,11 @@
 	/* is the point inside (not outside) any of the exterior rings? */
     for( i = 0; i < polyCount; i++ )
     {
-		int in_ring = point_in_ring(root[i], &pt);
-		LWDEBUGF(4, "point_in_multipolygon: exterior ring (%d), point_in_ring returned %d", i, in_ring);
+		int in_ring = point_in_ring_rtree(root[i], &pt);
+		LWDEBUGF(4, "point_in_multipolygon_rtree: exterior ring (%d), point_in_ring returned %d", i, in_ring);
        	if( in_ring != -1 ) /* not outside this ring */
        	{
-           	LWDEBUG(3, "point_in_multipolygon: inside exterior ring.");
+           	LWDEBUG(3, "point_in_multipolygon_rtree: inside exterior ring.");
            	result = in_ring;
            	break;
        	}
@@ -1318,11 +1317,11 @@
 	/* ok, it's in a ring, but if it's in a hole it's still outside */
     for( i = polyCount; i < ringCount; i++ )
     {
-		int in_ring = point_in_ring(root[i], &pt);
-		LWDEBUGF(4, "point_in_multipolygon: hole (%d), point_in_ring returned %d", i, in_ring);
+		int in_ring = point_in_ring_rtree(root[i], &pt);
+		LWDEBUGF(4, "point_in_multipolygon_rtree: hole (%d), point_in_ring returned %d", i, in_ring);
        	if( in_ring == 1 ) /* completely inside hole */
        	{
-          	LWDEBUGF(3, "point_in_multipolygon: within hole %d.", i);
+          	LWDEBUGF(3, "point_in_multipolygon_rtree: within hole %d.", i);
           	return -1;
        	}
 		if( in_ring == 0 ) /* on the boundary of a hole */
@@ -1335,139 +1334,109 @@
 }
 
 /*
- * return 0 iff point outside polygon or on boundary
+ * return -1 iff point outside polygon
+ * return 0 iff point on boundary
  * return 1 iff point inside polygon
  */
-int point_in_polygon_deprecated(LWPOLY *polygon, LWPOINT *point)
+int point_in_polygon(LWPOLY *polygon, LWPOINT *point)
 {
-        int i;
+        int i, result, in_ring;
         POINTARRAY *ring;
         POINT2D pt;
 
-        LWDEBUG(2, "point_in_polygon_deprecated called.");
+        LWDEBUG(2, "point_in_polygon called.");
 
         getPoint2d_p(point->point, 0, &pt);
         /* assume bbox short-circuit has already been attempted */
         
         ring = polygon->rings[0];
-        /* root = createTree(ring); */
-        /* if(point_in_ring(root, &pt) != 1)  */
-        if(point_in_ring_deprecated(polygon->rings[0], &pt) != 1)
+		in_ring = point_in_ring(polygon->rings[0], &pt);
+        if( in_ring == -1) /* outside the exterior ring */
         {
                 LWDEBUG(3, "point_in_polygon: outside exterior ring.");
-
-                return 0;
+                return -1;
         }
+		result = in_ring;
 
         for(i=1; i<polygon->nrings; i++)
         {
                 ring = polygon->rings[i];
-                /* root = createTree(ring); */
-                /* if(point_in_ring(root, &pt) != -1) */
-                if(point_in_ring_deprecated(polygon->rings[i], &pt) != -1)
+				in_ring = point_in_ring(polygon->rings[i], &pt);
+                if(in_ring == 1) /* inside a hole => outside the polygon */
                 {
-                        LWDEBUGF(3, "point_in_polygon: within hole %d.", i);
-
-                        return 0;
+                	LWDEBUGF(3, "point_in_polygon: within hole %d.", i);
+                    return -1;
                 }
+				if(in_ring == 0) /* on the edge of a hole */
+				{
+                    LWDEBUGF(3, "point_in_polygon: on edge of hole %d.", i);
+					return 0;
+				}
         }
-        return 1;
+        return result; /* -1 = outside, 0 = boundary, 1 = inside */
 }
 
 /*
- * return 0 iff point inside polygon or on boundary
- * return 1 iff point outside polygon
+ * return -1 iff point outside multipolygon
+ * return 0 iff point on multipolygon boundary
+ * return 1 iff point inside multipolygon
  */
-int point_outside_polygon(RTREE_NODE **root, int ringCount, LWPOINT *point)
+int point_in_multipolygon(LWMPOLY *mpolygon, LWPOINT *point)
 {
-        int i;
+        int i, j, result, in_ring;
+        POINTARRAY *ring;
         POINT2D pt;
 
-        LWDEBUG(2, "point_outside_polygon called.");
+        LWDEBUG(2, "point_in_polygon called.");
 
         getPoint2d_p(point->point, 0, &pt);
         /* assume bbox short-circuit has already been attempted */
-        
-        if(point_in_ring(root[0], &pt) == -1)
-        {
-                LWDEBUG(3, "point_outside_polygon: outside exterior ring.");
 
-                return 1;
-        }
+		result = -1;
 
-        for(i=1; i<ringCount; i++)
-        {
-                if(point_in_ring(root[i], &pt) == 1)
-                {
-                        LWDEBUGF(3, "point_outside_polygon: within hole %d.", i);
+		for(j = 0; j < mpolygon->ngeoms; j++ ) 
+		{
+		
+			LWPOLY *polygon = mpolygon->geoms[j];
+		   	ring = polygon->rings[0];
+			in_ring = point_in_ring(polygon->rings[0], &pt);
+       		if( in_ring == -1) /* outside the exterior ring */
+        	{
+                LWDEBUG(3, "point_in_polygon: outside exterior ring.");
+				continue;
+        	}
+			if( in_ring == 0 ) 
+			{
+				return 0;
+			}
 
-                        return 1;
-                }
-        }
-        return 0;
-}
+			result = in_ring;
 
-
-/*
- * return 0 iff point inside polygon or on boundary
- * return 1 iff point outside polygon
- */
-int point_outside_polygon_deprecated(LWPOLY *polygon, LWPOINT *point)
-{
-        int i;
-        POINTARRAY *ring;
-        POINT2D pt;
-
-        LWDEBUG(2, "point_outside_polygon_deprecated called.");
-
-        getPoint2d_p(point->point, 0, &pt);
-        /* assume bbox short-circuit has already been attempted */
-        
-        ring = polygon->rings[0];
-        /* root = createTree(ring); */
-        /* if(point_in_ring(root, &pt) == -1) */
-        if(point_in_ring_deprecated(ring, &pt) == -1)
-        {
-                LWDEBUG(3, "point_outside_polygon_deprecated: outside exterior ring.");
-
-                return 1;
-        }
-
-        for(i=1; i<polygon->nrings; i++)
-        {
+        	for(i=1; i<polygon->nrings; i++)
+        	{
                 ring = polygon->rings[i];
-                /* root = createTree(ring); */
-                /* if(point_in_ring(root, &pt) == 1)  */
-                if(point_in_ring_deprecated(ring, &pt) == 1)
+				in_ring = point_in_ring(polygon->rings[i], &pt);
+                if(in_ring == 1) /* inside a hole => outside the polygon */
                 {
-                        LWDEBUGF(3, "point_outside_polygon_deprecated: within hole %d.", i);
-
-                        return 1;
+                	LWDEBUGF(3, "point_in_polygon: within hole %d.", i);
+					result = -1;
+                    break;
                 }
-        }
-        return 0;
+				if(in_ring == 0) /* on the edge of a hole */
+				{
+                    LWDEBUGF(3, "point_in_polygon: on edge of hole %d.", i);
+					return 0;
+				}
+        	}
+        	if( result != -1) 
+			{
+				return result;
+			}
+		}
+		return result;
 }
 
 
-/*
- * return 0 iff point is outside every polygon
- */
-/* Not yet functional.
-int point_in_multipolygon(LWMPOLY *mpolygon, LWPOINT *point)
-{
-        int i;
-
-        LWDEBUG(2, "point_in_multipolygon called.");
-
-        for(i=1; i<mpolygon->ngeoms; i++)
-        {
-                if(point_in_polygon((LWPOLY *)mpolygon->geoms[i], point)!=0) return 1;
-        }
-        return 0;
-}
-*/
-
-
 /*******************************************************************************
  * End of "Fast Winding Number Inclusion of a Point in a Polygon" derivative.
  ******************************************************************************/

Modified: trunk/lwgeom/lwgeom_geos_c.c
===================================================================
--- trunk/lwgeom/lwgeom_geos_c.c	2008-09-27 08:19:18 UTC (rev 3021)
+++ trunk/lwgeom/lwgeom_geos_c.c	2008-09-28 09:03:32 UTC (rev 3022)
@@ -1378,11 +1378,10 @@
 	PG_RETURN_BOOL(result);
 }
 
-int point_in_polygon(RTREE_NODE **root, int ringCount, LWPOINT *point);
-int point_in_polygon_deprecated(LWPOLY *polygon, LWPOINT *point);
-int point_outside_polygon(RTREE_NODE **root, int ringCount, LWPOINT *point);
-int point_outside_polygon_deprecated(LWPOLY *polygon, LWPOINT *point);
-int point_in_multipolygon(RTREE_NODE **root, int polyCount, int ringCount, LWPOINT *point);
+int point_in_polygon_rtree(RTREE_NODE **root, int ringCount, LWPOINT *point);
+int point_in_multipolygon_rtree(RTREE_NODE **root, int polyCount, int ringCount, LWPOINT *point);
+int point_in_polygon(LWPOLY *polygon, LWPOINT *point);
+int point_in_multipolygon(LWMPOLY *mpolygon, LWPOINT *pont);
 
 
 PG_FUNCTION_INFO_V1(contains);
@@ -1409,6 +1408,8 @@
 	errorIfGeometryCollection(geom1,geom2);
 	errorIfSRIDMismatch(pglwgeom_getSRID(geom1), pglwgeom_getSRID(geom2));
 
+    POSTGIS_DEBUG(3, "contains called.");
+
     /*
     ** short-circuit 1: if geom2 bounding box is not completely inside
     ** geom1 bounding box we can prematurely return FALSE.
@@ -1436,7 +1437,7 @@
         lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom1));
         point = lwpoint_deserialize(SERIALIZED_FORM(geom2));
 
-        POSTGIS_DEBUGF(3, "Precall point_in_multipolygon %p, %p", lwgeom, point);
+        POSTGIS_DEBUGF(3, "Precall point_in_multipolygon_rtree %p, %p", lwgeom, point);
 
         /*
          * Switch the context to the function-scope context,
@@ -1448,7 +1449,23 @@
         fcinfo->flinfo->fn_extra = poly_cache;
         MemoryContextSwitchTo(old_context);
 
-        result = point_in_multipolygon(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+		if( poly_cache->ringIndices ) 
+		{
+			result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+		}
+		else if ( type1 == POLYGONTYPE ) 
+		{
+			result = point_in_polygon((LWPOLY*)lwgeom, point);
+		}
+		else if ( type1 == MULTIPOLYGONTYPE ) 
+		{
+			result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
+		}
+		else {
+			/* Gulp! Should not be here... */
+			elog(ERROR,"Type isn't poly or multipoly!");
+			PG_RETURN_NULL(); 
+		}
         PG_FREE_IF_COPY(geom1, 0);
         PG_FREE_IF_COPY(geom2, 1);
         lwgeom_release((LWGEOM *)lwgeom);
@@ -1569,7 +1586,7 @@
                 lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom1));
                 point = lwpoint_deserialize(SERIALIZED_FORM(geom2));
 
-                POSTGIS_DEBUGF(3, "Precall point_in_polygon %p, %p", lwgeom, point);
+                POSTGIS_DEBUGF(3, "Precall point_in_multipolygon_rtree %p, %p", lwgeom, point);
 
                 /*
                  * Switch the context to the function-scope context,
@@ -1581,7 +1598,24 @@
                 fcinfo->flinfo->fn_extra = poly_cache;
                 MemoryContextSwitchTo(old_context);
 
-				result = point_in_multipolygon(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+				if( poly_cache->ringIndices ) 
+				{
+					result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+				}
+				else if ( type1 == POLYGONTYPE ) 
+				{
+					result = point_in_polygon((LWPOLY*)lwgeom, point);
+				}
+				else if ( type1 == MULTIPOLYGONTYPE ) 
+				{
+					result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
+				}
+				else {
+					/* Gulp! Should not be here... */
+					elog(ERROR,"Type isn't poly or multipoly!");
+					PG_RETURN_NULL(); 
+				}
+
                 PG_FREE_IF_COPY(geom1, 0);
                 PG_FREE_IF_COPY(geom2, 1);
 				lwgeom_release((LWGEOM *)lwgeom);
@@ -1688,7 +1722,7 @@
          */
         type1 = lwgeom_getType((uchar)SERIALIZED_FORM(geom1)[0]);
         type2 = lwgeom_getType((uchar)SERIALIZED_FORM(geom2)[0]);
-    	if((type2 == POLYGONTYPE || type1 == MULTIPOLYGONTYPE) && type1 == POINTTYPE)
+    	if((type2 == POLYGONTYPE || type2 == MULTIPOLYGONTYPE) && type1 == POINTTYPE)
         {
                 POSTGIS_DEBUG(3, "Point in Polygon test requested...short-circuiting.");
 
@@ -1705,7 +1739,24 @@
                 fcinfo->flinfo->fn_extra = poly_cache;
                 MemoryContextSwitchTo(old_context);
 
-				result = point_in_multipolygon(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+				if( poly_cache->ringIndices ) 
+				{
+					result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+				}
+				else if ( type2 == POLYGONTYPE ) 
+				{
+					result = point_in_polygon((LWPOLY*)lwgeom, point);
+				}
+				else if ( type2 == MULTIPOLYGONTYPE ) 
+				{
+					result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
+				}
+				else {
+					/* Gulp! Should not be here... */
+					elog(ERROR,"Type isn't poly or multipoly!");
+					PG_RETURN_NULL(); 
+				}
+
                 PG_FREE_IF_COPY(geom1, 0);
                 PG_FREE_IF_COPY(geom2, 1);
                 lwgeom_release((LWGEOM *)lwgeom);
@@ -1833,7 +1884,24 @@
                 fcinfo->flinfo->fn_extra = poly_cache;
                 MemoryContextSwitchTo(old_context);
 
-				result = point_in_multipolygon(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+				if( poly_cache->ringIndices ) 
+				{
+					result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+				}
+				else if ( type2 == POLYGONTYPE ) 
+				{
+					result = point_in_polygon((LWPOLY*)lwgeom, point);
+				}
+				else if ( type2 == MULTIPOLYGONTYPE ) 
+				{
+					result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
+				}
+				else {
+					/* Gulp! Should not be here... */
+					elog(ERROR,"Type isn't poly or multipoly!");
+					PG_RETURN_NULL(); 
+				}
+				
                 PG_FREE_IF_COPY(geom1, 0);
                 PG_FREE_IF_COPY(geom2, 1);
                 lwgeom_release((LWGEOM *)lwgeom);
@@ -1983,7 +2051,7 @@
 	GEOSGeom g1,g2;
 	bool result;
 	BOX2DFLOAT4 box1, box2;
-	int type1, type2;
+	int type1, type2, polytype;
 	LWPOINT *point;
 	LWGEOM *lwgeom;
         MemoryContext old_context;
@@ -2028,10 +2096,12 @@
 		    point = lwpoint_deserialize(SERIALIZED_FORM(geom1));
 		    lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom2));
 			serialized_poly = SERIALIZED_FORM(geom2);
+			polytype = type2;
         } else {
 		    point = lwpoint_deserialize(SERIALIZED_FORM(geom2));
 		    lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom1));
 			serialized_poly = SERIALIZED_FORM(geom1);
+			polytype = type1;
 		}
         /*
          * Switch the context to the function-scope context,
@@ -2043,7 +2113,24 @@
         fcinfo->flinfo->fn_extra = poly_cache;
         MemoryContextSwitchTo(old_context);
 
-		result = point_in_multipolygon(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+		if( poly_cache->ringIndices ) 
+		{
+			result = point_in_multipolygon_rtree(poly_cache->ringIndices, poly_cache->polyCount, poly_cache->ringCount, point);
+		}
+		else if ( polytype == POLYGONTYPE ) 
+		{
+			result = point_in_polygon((LWPOLY*)lwgeom, point);
+		}
+		else if ( polytype == MULTIPOLYGONTYPE ) 
+		{
+			result = point_in_multipolygon((LWMPOLY*)lwgeom, point);
+		}
+		else {
+			/* Gulp! Should not be here... */
+			elog(ERROR,"Type isn't poly or multipoly!");
+			PG_RETURN_NULL(); 
+		}
+
 		PG_FREE_IF_COPY(geom1, 0);
 		PG_FREE_IF_COPY(geom2, 1);
 		lwgeom_release((LWGEOM *)lwgeom);

Modified: trunk/lwgeom/lwgeom_rtree.c
===================================================================
--- trunk/lwgeom/lwgeom_rtree.c	2008-09-27 08:19:18 UTC (rev 3021)
+++ trunk/lwgeom/lwgeom_rtree.c	2008-09-28 09:03:32 UTC (rev 3022)
@@ -214,7 +214,7 @@
 /*
  * Free the cache object and all the sub-objects properly.
  */
-void freeCache(RTREE_POLY_CACHE *cache)
+void clearCache(RTREE_POLY_CACHE *cache)
 {
 	int i;
 	LWDEBUGF(2, "freeCache called for %p", cache);
@@ -224,7 +224,10 @@
 	}
 	lwfree(cache->ringIndices);
 	lwfree(cache->poly);
-	lwfree(cache);
+	cache->poly = 0;
+	cache->ringIndices = 0;
+	cache->ringCount = 0;
+	cache->polyCount = 0;
 }
 
  
@@ -387,18 +390,26 @@
 		
 }
 
+RTREE_POLY_CACHE * createCache()
+{
+	RTREE_POLY_CACHE *result;
+	result = lwalloc(sizeof(RTREE_POLY_CACHE));
+	result->polyCount = 0;
+	result->ringCount = 0;
+	result->ringIndices = 0;
+	result->poly = 0;
+	return result;
+}
 
-RTREE_POLY_CACHE *createNewCache(LWGEOM *lwgeom, uchar *serializedPoly)
+void populateCache(RTREE_POLY_CACHE *currentCache, LWGEOM *lwgeom, uchar *serializedPoly)
 {
-	RTREE_POLY_CACHE *result;
 	int i, j, k, length;
 	
-	LWDEBUGF(2, "createNewCache called with %p", lwgeom);
+	LWDEBUGF(2, "populateCache called with cache %p geom %p", currentCache, lwgeom);
 
-	result = lwalloc(sizeof(RTREE_POLY_CACHE));
-
 	if(TYPE_GETTYPE(lwgeom->type) == MULTIPOLYGONTYPE) 
 	{
+		LWDEBUG(2, "populateCache MULTIPOLYGON");
 		LWMPOLY *mpoly = (LWMPOLY *)lwgeom;
 		int nrings = 0;
 		/*
@@ -408,15 +419,15 @@
 		{
 			nrings += mpoly->geoms[i]->nrings;
 		}
-		result->polyCount = mpoly->ngeoms;
-		result->ringCount = nrings;
-		result->ringIndices = lwalloc(sizeof(RTREE_NODE *) * nrings);
+		currentCache->polyCount = mpoly->ngeoms;
+		currentCache->ringCount = nrings;
+		currentCache->ringIndices = lwalloc(sizeof(RTREE_NODE *) * nrings);
 		/*
 		** Load the exterior rings onto the ringIndices array first
 		*/
 		for( i = 0; i < mpoly->ngeoms; i++ ) 
 		{
-			result->ringIndices[i] = createTree(mpoly->geoms[i]->rings[0]);
+			currentCache->ringIndices[i] = createTree(mpoly->geoms[i]->rings[0]);
 		}
 		/*
 		** Load the interior rings (holes) onto ringIndices next
@@ -425,23 +436,24 @@
 		{
 			for( k = 1; k < mpoly->geoms[j]->nrings; k++ ) 
 			{
-				result->ringIndices[i] = createTree(mpoly->geoms[j]->rings[k]);
+				currentCache->ringIndices[i] = createTree(mpoly->geoms[j]->rings[k]);
 				i++;
 			}
 		}
 	}
 	else if ( TYPE_GETTYPE(lwgeom->type) == POLYGONTYPE ) 
 	{
+		LWDEBUG(2, "populateCache POLYGON");
 		LWPOLY *poly = (LWPOLY *)lwgeom;
-		result->polyCount = 1;
-		result->ringCount = poly->nrings;
+		currentCache->polyCount = 1;
+		currentCache->ringCount = poly->nrings;
 		/*
 		** Just load the rings on in order
 		*/
-		result->ringIndices = lwalloc(sizeof(RTREE_NODE *) * poly->nrings);
+		currentCache->ringIndices = lwalloc(sizeof(RTREE_NODE *) * poly->nrings);
 		for( i = 0; i < poly->nrings; i++ ) 
 		{
-			result->ringIndices[i] = createTree(poly->rings[i]);
+			currentCache->ringIndices[i] = createTree(poly->rings[i]);
 		}
 	}
 	else 
@@ -455,12 +467,9 @@
 	** we can test for equality against subsequent polygons.
 	*/
 	length = lwgeom_size(serializedPoly);
-	result->poly = lwalloc(length);
-	memcpy(result->poly, serializedPoly, length); 
-	
-	LWDEBUGF(3, "createNewCache returning %p", result);
-
-	return result;
+	currentCache->poly = lwalloc(length);
+	memcpy(currentCache->poly, serializedPoly, length); 
+	LWDEBUGF(3, "populateCache returning %p", currentCache);
 }
 
 /* 
@@ -470,8 +479,7 @@
  * method.	The method will allocate memory for the cache it creates,
  * as well as freeing the memory of any cache that is no longer applicable.
  */
-RTREE_POLY_CACHE *retrieveCache(LWGEOM *lwgeom, uchar *serializedPoly, 
-				RTREE_POLY_CACHE *currentCache)
+RTREE_POLY_CACHE *retrieveCache(LWGEOM *lwgeom, uchar *serializedPoly, RTREE_POLY_CACHE *currentCache)
 {
 	int length;
 
@@ -480,12 +488,13 @@
 	if(!currentCache)
 	{
 		LWDEBUG(3, "No existing cache, create one.");
-		return createNewCache(lwgeom, serializedPoly);
+		return createCache();
 	}
 	if(!(currentCache->poly))
 	{
-		LWDEBUG(3, "Cache contains no polygon, creating new cache.");
-		return createNewCache(lwgeom, serializedPoly);
+		LWDEBUG(3, "Cache contains no polygon, populating it.");
+		populateCache(currentCache, lwgeom, serializedPoly);
+		return currentCache;
 	}
 
 	length = lwgeom_size(serializedPoly);
@@ -493,14 +502,14 @@
 	if(lwgeom_size(currentCache->poly) != length)
 	{
 		LWDEBUG(3, "Polygon size mismatch, creating new cache.");
-		freeCache(currentCache);
-		return createNewCache(lwgeom, serializedPoly);
+		clearCache(currentCache);
+		return currentCache;
 	}
 	if( memcmp(serializedPoly, currentCache->poly, length) ) 
 	{
 		LWDEBUG(3, "Polygon mismatch, creating new cache.");
-		freeCache(currentCache);
-		return createNewCache(lwgeom, serializedPoly);
+		clearCache(currentCache);
+		return currentCache;
 	}
 
 	LWDEBUGF(3, "Polygon match, retaining current cache, %p.", currentCache);

Modified: trunk/lwgeom/lwgeom_rtree.h
===================================================================
--- trunk/lwgeom/lwgeom_rtree.h	2008-09-27 08:19:18 UTC (rev 3021)
+++ trunk/lwgeom/lwgeom_rtree.h	2008-09-28 09:03:32 UTC (rev 3022)
@@ -56,8 +56,9 @@
  * it is applicable to the current polygon.
  */
 RTREE_POLY_CACHE *retrieveCache(LWGEOM *lwgeom, uchar *serializedPoly, RTREE_POLY_CACHE *currentCache);
-RTREE_POLY_CACHE *createNewCache(LWGEOM *lwgeom, uchar *serializedPoly);
+RTREE_POLY_CACHE *createCache();
 /* Frees the cache. */
-void freeCache(RTREE_POLY_CACHE *cache);
+void populateCache(RTREE_POLY_CACHE *cache, LWGEOM *lwgeom, uchar *serializedPoly);
+void clearCache(RTREE_POLY_CACHE *cache);
 
 #endif /* !defined _LIBLWGEOM_H */



More information about the postgis-commits mailing list