[postgis-commits] svn - r3284 - trunk/lwgeom
postgis-commits at postgis.refractions.net
postgis-commits at postgis.refractions.net
Mon Nov 10 08:35:40 PST 2008
Author: pramsey
Date: 2008-11-10 08:35:40 -0800 (Mon, 10 Nov 2008)
New Revision: 3284
Modified:
trunk/lwgeom/lwgeom_geos_prepared.c
trunk/lwgeom/lwgeom_geos_prepared.h
trunk/lwgeom/lwgeom_rtree.c
trunk/lwgeom/lwgeom_rtree.h
Log:
astyle --style=ansi --indent=tab=8
Modified: trunk/lwgeom/lwgeom_geos_prepared.c
===================================================================
--- trunk/lwgeom/lwgeom_geos_prepared.c 2008-11-10 15:48:39 UTC (rev 3283)
+++ trunk/lwgeom/lwgeom_geos_prepared.c 2008-11-10 16:35:40 UTC (rev 3284)
@@ -8,7 +8,7 @@
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
- *
+ *
**********************************************************************/
#include "lwgeom_geos_prepared.h"
@@ -35,7 +35,7 @@
** objects used in computations.
**
** PreparedCacheContextMethods, a set of callback functions that
-** get hooked into a MemoryContext that is in turn used as a
+** get hooked into a MemoryContext that is in turn used as a
** key in the PrepGeomHash.
**
** All this is to allow us to clean up external malloc'ed objects
@@ -56,21 +56,22 @@
** Backend prepared hash table
**
** The memory context call-backs use a MemoryContext as the parameter
-** so we need to map that over to actual references to GEOS objects to
+** so we need to map that over to actual references to GEOS objects to
** delete.
**
** This hash table stores a key/value pair of MemoryContext/Geom* objects.
*/
static HTAB* PrepGeomHash = NULL;
-#define PREPARED_BACKEND_HASH_SIZE 32
+#define PREPARED_BACKEND_HASH_SIZE 32
-typedef struct
+typedef struct
{
MemoryContext context;
const GEOSPreparedGeometry* prepared_geom;
GEOSGeometry* geom;
-} PrepGeomHashEntry;
+}
+PrepGeomHashEntry;
/* Memory context hash table function prototypes */
uint32 mcxt_ptr_hasha(const void *key, Size keysize);
@@ -90,20 +91,21 @@
#endif
/* Memory context definition must match the current version of PostgreSQL */
-static MemoryContextMethods PreparedCacheContextMethods = {
- NULL,
- NULL,
- NULL,
- PreparedCacheInit,
- PreparedCacheReset,
- PreparedCacheDelete,
- NULL,
- PreparedCacheIsEmpty,
- PreparedCacheStats
+static MemoryContextMethods PreparedCacheContextMethods =
+ {
+ NULL,
+ NULL,
+ NULL,
+ PreparedCacheInit,
+ PreparedCacheReset,
+ PreparedCacheDelete,
+ NULL,
+ PreparedCacheIsEmpty,
+ PreparedCacheStats
#ifdef MEMORY_CONTEXT_CHECKING
- , PreparedCacheCheck
+ , PreparedCacheCheck
#endif
-};
+ };
static void
PreparedCacheInit(MemoryContext context)
@@ -128,9 +130,9 @@
POSTGIS_DEBUGF(3, "deleting geom object (%p) and prepared geom object (%p) with MemoryContext key (%p)", pghe->geom, pghe->prepared_geom, context);
/* Free them */
- if( pghe->prepared_geom )
+ if ( pghe->prepared_geom )
GEOSPreparedGeom_destroy( pghe->prepared_geom );
- if( pghe->geom )
+ if ( pghe->geom )
GEOSGeom_destroy( pghe->geom );
/* Remove the hash entry as it is no longer needed */
@@ -182,7 +184,7 @@
** mcxt_ptr_hash
** Build a key from a pointer and a size value.
*/
-uint32
+uint32
mcxt_ptr_hasha(const void *key, Size keysize)
{
uint32 hashval;
@@ -204,7 +206,7 @@
PrepGeomHash = hash_create("PostGIS Prepared Geometry Backend MemoryContext Hash", PREPARED_BACKEND_HASH_SIZE, &ctl, (HASH_ELEM | HASH_FUNCTION));
}
-static void
+static void
AddPrepGeomHashEntry(PrepGeomHashEntry pghe)
{
bool found;
@@ -213,7 +215,7 @@
/* The hash key is the MemoryContext pointer */
key = (void *)&(pghe.context);
-
+
he = (PrepGeomHashEntry *) hash_search(PrepGeomHash, key, HASH_ENTER, &found);
if (!found)
{
@@ -244,11 +246,11 @@
}
-static void
+static void
DeletePrepGeomHashEntry(MemoryContext mcxt)
{
void **key;
- PrepGeomHashEntry *he;
+ PrepGeomHashEntry *he;
/* The hash key is the MemoryContext pointer */
key = (void *)&mcxt;
@@ -268,10 +270,10 @@
**
** Pull the current prepared geometry from the cache or make
** one if there is not one available. Only prepare geometry
-** if we are seeing a key for the second time. That way rapidly
+** if we are seeing a key for the second time. That way rapidly
** cycling keys don't cause too much preparing.
*/
-PrepGeomCache*
+PrepGeomCache*
GetPrepGeomCache(FunctionCallInfoData *fcinfo, PG_LWGEOM *pg_geom1, PG_LWGEOM *pg_geom2)
{
MemoryContext old_context;
@@ -280,16 +282,16 @@
size_t pg_geom1_size = 0;
size_t pg_geom2_size = 0;
- /* Make sure this isn't someone else's cache object. */
- if( cache && cache->type != 2 ) cache = NULL;
+ /* Make sure this isn't someone else's cache object. */
+ if ( cache && cache->type != 2 ) cache = NULL;
if (!PrepGeomHash)
CreatePrepGeomHash();
- if( pg_geom1 )
+ if ( pg_geom1 )
pg_geom1_size = VARSIZE(pg_geom1) + VARHDRSZ;
- if( pg_geom2 )
+ if ( pg_geom2 )
pg_geom2_size = VARSIZE(pg_geom2) + VARHDRSZ;
if ( cache == NULL)
@@ -301,12 +303,12 @@
** wasted time preparing a geometry we don't need.
*/
PrepGeomHashEntry pghe;
-
+
old_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
- cache = palloc(sizeof(PrepGeomCache));
+ cache = palloc(sizeof(PrepGeomCache));
MemoryContextSwitchTo(old_context);
-
- cache->type = 2;
+
+ cache->type = 2;
cache->prepared_geom = 0;
cache->geom = 0;
cache->argnum = 0;
@@ -315,9 +317,9 @@
cache->pg_geom1_size = 0;
cache->pg_geom2_size = 0;
cache->context = MemoryContextCreate(T_AllocSetContext, 8192,
- &PreparedCacheContextMethods,
- fcinfo->flinfo->fn_mcxt,
- "PostGIS Prepared Geometry Context");
+ &PreparedCacheContextMethods,
+ fcinfo->flinfo->fn_mcxt,
+ "PostGIS Prepared Geometry Context");
POSTGIS_DEBUGF(1, "GetPrepGeomCache: creating cache: %p", cache);
@@ -331,9 +333,9 @@
POSTGIS_DEBUGF(3, "GetPrepGeomCache: adding context to hash: %p", cache);
}
else if ( pg_geom1 &&
- cache->argnum != 2 &&
- cache->pg_geom1_size == pg_geom1_size &&
- memcmp(cache->pg_geom1, pg_geom1, pg_geom1_size) == 0)
+ cache->argnum != 2 &&
+ cache->pg_geom1_size == pg_geom1_size &&
+ memcmp(cache->pg_geom1, pg_geom1, pg_geom1_size) == 0)
{
if ( !cache->prepared_geom )
{
@@ -342,7 +344,7 @@
** Prepare it.
*/
PrepGeomHashEntry* pghe;
-
+
cache->geom = POSTGIS2GEOS( pg_geom1 );
cache->prepared_geom = GEOSPrepare( cache->geom );
cache->argnum = 1;
@@ -354,7 +356,7 @@
POSTGIS_DEBUG(3, "GetPrepGeomCache: storing references to prepared obj in argument 1");
}
else
- {
+ {
/*
** Cache hit, and we're good to go. Do nothing.
*/
@@ -363,38 +365,38 @@
/* We don't need new keys until we have a cache miss */
copy_keys = 0;
}
- else if ( pg_geom2 &&
- cache->argnum != 1 &&
- cache->pg_geom2_size == pg_geom2_size &&
- memcmp(cache->pg_geom2, pg_geom2, pg_geom2_size) == 0)
+ else if ( pg_geom2 &&
+ cache->argnum != 1 &&
+ cache->pg_geom2_size == pg_geom2_size &&
+ memcmp(cache->pg_geom2, pg_geom2, pg_geom2_size) == 0)
{
- if ( !cache->prepared_geom )
- {
- /*
- ** Cache hit on arg2, but we haven't prepared our geometry yet.
- ** Prepare it.
- */
- PrepGeomHashEntry* pghe;
-
- cache->geom = POSTGIS2GEOS( pg_geom2 );
- cache->prepared_geom = GEOSPrepare( cache->geom );
- cache->argnum = 2;
- POSTGIS_DEBUG(1, "GetPrepGeomCache: preparing obj in argument 2");
-
- pghe = GetPrepGeomHashEntry(cache->context);
- pghe->geom = cache->geom;
- pghe->prepared_geom = cache->prepared_geom;
- POSTGIS_DEBUG(3, "GetPrepGeomCache: storing references to prepared obj in argument 2");
- }
- else
- {
- /*
- ** Cache hit, and we're good to go. Do nothing.
- */
- POSTGIS_DEBUG(1, "GetPrepGeomCache: cache hit, argument 2");
- }
- /* We don't need new keys until we have a cache miss */
- copy_keys = 0;
+ if ( !cache->prepared_geom )
+ {
+ /*
+ ** Cache hit on arg2, but we haven't prepared our geometry yet.
+ ** Prepare it.
+ */
+ PrepGeomHashEntry* pghe;
+
+ cache->geom = POSTGIS2GEOS( pg_geom2 );
+ cache->prepared_geom = GEOSPrepare( cache->geom );
+ cache->argnum = 2;
+ POSTGIS_DEBUG(1, "GetPrepGeomCache: preparing obj in argument 2");
+
+ pghe = GetPrepGeomHashEntry(cache->context);
+ pghe->geom = cache->geom;
+ pghe->prepared_geom = cache->prepared_geom;
+ POSTGIS_DEBUG(3, "GetPrepGeomCache: storing references to prepared obj in argument 2");
+ }
+ else
+ {
+ /*
+ ** Cache hit, and we're good to go. Do nothing.
+ */
+ POSTGIS_DEBUG(1, "GetPrepGeomCache: cache hit, argument 2");
+ }
+ /* We don't need new keys until we have a cache miss */
+ copy_keys = 0;
}
else if ( cache->prepared_geom )
{
@@ -411,14 +413,14 @@
POSTGIS_DEBUGF(1, "GetPrepGeomCache: cache miss, argument %d", cache->argnum);
GEOSPreparedGeom_destroy( cache->prepared_geom );
GEOSGeom_destroy( cache->geom );
-
+
cache->prepared_geom = 0;
cache->geom = 0;
cache->argnum = 0;
}
-
- if( copy_keys && pg_geom1 )
+
+ if ( copy_keys && pg_geom1 )
{
/*
** If this is a new key (cache miss) we flip into the function
@@ -428,18 +430,18 @@
*/
POSTGIS_DEBUG(1, "GetPrepGeomCache: copying pg_geom1 into cache");
old_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
- if( cache->pg_geom1 )
+ if ( cache->pg_geom1 )
pfree(cache->pg_geom1);
cache->pg_geom1 = palloc(pg_geom1_size);
MemoryContextSwitchTo(old_context);
memcpy(cache->pg_geom1, pg_geom1, pg_geom1_size);
cache->pg_geom1_size = pg_geom1_size;
}
- if( copy_keys && pg_geom2 )
- {
+ if ( copy_keys && pg_geom2 )
+ {
POSTGIS_DEBUG(1, "GetPrepGeomCache: copying pg_geom2 into cache");
old_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
- if( cache->pg_geom2 )
+ if ( cache->pg_geom2 )
pfree(cache->pg_geom2);
cache->pg_geom2 = palloc(pg_geom2_size);
MemoryContextSwitchTo(old_context);
@@ -448,7 +450,7 @@
}
return cache;
-
+
}
#endif /* PREPARED_GEOM */
@@ -464,7 +466,7 @@
{
#ifndef PREPARED_GEOM
elog(ERROR,"Not implemented in this version!");
- PG_RETURN_NULL();
+ PG_RETURN_NULL();
#else
PG_LWGEOM * geom1;
PG_LWGEOM * geom2;
@@ -488,10 +490,10 @@
* Do the test IFF BOUNDING BOX AVAILABLE.
*/
if ( getbox2d_p(SERIALIZED_FORM(geom1), &box1) &&
- getbox2d_p(SERIALIZED_FORM(geom2), &box2) )
+ getbox2d_p(SERIALIZED_FORM(geom2), &box2) )
{
if (( box2.xmin < box1.xmin ) || ( box2.xmax > box1.xmax ) ||
- ( box2.ymin < box1.ymin ) || ( box2.ymax > box1.ymax ))
+ ( box2.ymin < box1.ymin ) || ( box2.ymax > box1.ymax ))
PG_RETURN_BOOL(FALSE);
}
@@ -564,7 +566,7 @@
getbox2d_p(SERIALIZED_FORM(geom2), &box2) )
{
if (( box2.xmin < box1.xmin ) || ( box2.xmax > box1.xmax ) ||
- ( box2.ymin < box1.ymin ) || ( box2.ymax > box1.ymax ))
+ ( box2.ymin < box1.ymin ) || ( box2.ymax > box1.ymax ))
PG_RETURN_BOOL(FALSE);
}
@@ -636,7 +638,7 @@
getbox2d_p(SERIALIZED_FORM(geom2), &box2) )
{
if (( box2.xmax < box1.xmin ) || ( box2.xmin > box1.xmax ) ||
- ( box2.ymax < box1.ymin ) || ( box2.ymin > box1.ymax ))
+ ( box2.ymax < box1.ymin ) || ( box2.ymin > box1.ymax ))
PG_RETURN_BOOL(FALSE);
}
Modified: trunk/lwgeom/lwgeom_geos_prepared.h
===================================================================
--- trunk/lwgeom/lwgeom_geos_prepared.h 2008-11-10 15:48:39 UTC (rev 3283)
+++ trunk/lwgeom/lwgeom_geos_prepared.h 2008-11-10 16:35:40 UTC (rev 3284)
@@ -7,7 +7,7 @@
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
- *
+ *
**********************************************************************/
#include "../postgis_config.h"
@@ -34,34 +34,35 @@
** GEOS prepared geometry is only available from GEOS 3.1 onwards
*/
#if POSTGIS_GEOS_VERSION >= 31
-#define PREPARED_GEOM
+#define PREPARED_GEOM
#endif
-/*
+/*
** Cache structure. We use PG_LWGEOM as keys so no transformations
-** are needed before we memcmp them with other keys. We store the
+** are needed before we memcmp them with other keys. We store the
** size to avoid having to calculate the size every time.
-** The argnum gives the number of function arguments we are caching.
-** Intersects requires that both arguments be checked for cacheability,
-** while Contains only requires that the containing argument be checked.
-** Both the Geometry and the PreparedGeometry have to be cached,
+** The argnum gives the number of function arguments we are caching.
+** Intersects requires that both arguments be checked for cacheability,
+** while Contains only requires that the containing argument be checked.
+** Both the Geometry and the PreparedGeometry have to be cached,
** because the PreparedGeometry contains a reference to the geometry.
*/
#ifdef PREPARED_GEOM
typedef struct
{
char type;
- PG_LWGEOM* pg_geom1;
- PG_LWGEOM* pg_geom2;
+ PG_LWGEOM *pg_geom1;
+ PG_LWGEOM *pg_geom2;
size_t pg_geom1_size;
size_t pg_geom2_size;
int32 argnum;
- const GEOSPreparedGeometry* prepared_geom;
- GEOSGeometry* geom;
+ const GEOSPreparedGeometry *prepared_geom;
+ GEOSGeometry *geom;
MemoryContext context;
-} PrepGeomCache;
+}
+PrepGeomCache;
-/*
+/*
** Get the current cache, given the input geometries.
** Function will create cache if none exists, and prepare geometries in
** cache if necessary, or pull an existing cache if possible.
Modified: trunk/lwgeom/lwgeom_rtree.c
===================================================================
--- trunk/lwgeom/lwgeom_rtree.c 2008-11-10 15:48:39 UTC (rev 3283)
+++ trunk/lwgeom/lwgeom_rtree.c 2008-11-10 16:35:40 UTC (rev 3284)
@@ -7,7 +7,7 @@
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
- *
+ *
**********************************************************************/
#include "lwgeom_pg.h"
@@ -24,80 +24,81 @@
*/
RTREE_NODE *createTree(POINTARRAY *pointArray)
{
- RTREE_NODE *root;
+ RTREE_NODE *root;
RTREE_NODE** nodes = lwalloc(sizeof(RTREE_NODE*) * pointArray->npoints);
int i, nodeCount;
- int childNodes, parentNodes;
+ int childNodes, parentNodes;
- LWDEBUGF(2, "createTree called with pointarray %p", pointArray);
+ LWDEBUGF(2, "createTree called with pointarray %p", pointArray);
- nodeCount = pointArray->npoints - 1;
+ nodeCount = pointArray->npoints - 1;
- LWDEBUGF(3, "Total leaf nodes: %d", nodeCount);
+ LWDEBUGF(3, "Total leaf nodes: %d", nodeCount);
- /*
- * Create a leaf node for every line segment.
- */
- for(i = 0; i < nodeCount; i++)
+ /*
+ * Create a leaf node for every line segment.
+ */
+ for (i = 0; i < nodeCount; i++)
+ {
+ nodes[i] = createLeafNode(pointArray, i);
+ }
+
+ /*
+ * Next we group nodes by pairs. If there's an odd number of nodes,
+ * we bring the last node up a level as is. Continue until we have
+ * a single top node.
+ */
+ childNodes = nodeCount;
+ parentNodes = nodeCount / 2;
+ while (parentNodes > 0)
+ {
+ LWDEBUGF(3, "Merging %d children into %d parents.", childNodes, parentNodes);
+
+ i = 0;
+ while (i < parentNodes)
{
- nodes[i] = createLeafNode(pointArray, i);
+ nodes[i] = createInteriorNode(nodes[i*2], nodes[i*2+1]);
+ i++;
}
-
/*
- * Next we group nodes by pairs. If there's an odd number of nodes,
- * we bring the last node up a level as is. Continue until we have
- * a single top node.
+ * Check for an odd numbered final node.
*/
- childNodes = nodeCount;
- parentNodes = nodeCount / 2;
- while(parentNodes > 0)
+ if (parentNodes * 2 < childNodes)
{
- LWDEBUGF(3, "Merging %d children into %d parents.", childNodes, parentNodes);
+ LWDEBUGF(3, "Shuffling child %d to parent %d", childNodes - 1, i);
- i = 0;
- while(i < parentNodes)
- {
- nodes[i] = createInteriorNode(nodes[i*2], nodes[i*2+1]);
- i++;
- }
- /*
- * Check for an odd numbered final node.
- */
- if(parentNodes * 2 < childNodes)
- {
- LWDEBUGF(3, "Shuffling child %d to parent %d", childNodes - 1, i);
-
- nodes[i] = nodes[childNodes - 1];
- parentNodes++;
- }
- childNodes = parentNodes;
- parentNodes = parentNodes / 2;
+ nodes[i] = nodes[childNodes - 1];
+ parentNodes++;
}
+ childNodes = parentNodes;
+ parentNodes = parentNodes / 2;
+ }
- root = nodes[0];
- lwfree(nodes);
- LWDEBUGF(3, "createTree returning %p", root);
+ root = nodes[0];
+ lwfree(nodes);
+ LWDEBUGF(3, "createTree returning %p", root);
- return root;
+ return root;
}
-/*
- * Creates an interior node given the children.
+/*
+ * Creates an interior node given the children.
*/
-RTREE_NODE *createInteriorNode(RTREE_NODE *left, RTREE_NODE *right){
- RTREE_NODE *parent;
+RTREE_NODE *createInteriorNode(RTREE_NODE *left, RTREE_NODE *right)
+{
+ RTREE_NODE *parent;
- LWDEBUGF(2, "createInteriorNode called for children %p, %p", left, right);
+ LWDEBUGF(2, "createInteriorNode called for children %p, %p", left, right);
- parent = lwalloc(sizeof(RTREE_NODE));
- parent->leftNode = left;
- parent->rightNode = right;
- parent->interval = mergeIntervals(left->interval, right->interval);
- parent->segment = NULL;
+ parent = lwalloc(sizeof(RTREE_NODE));
+ parent->leftNode = left;
+ parent->rightNode = right;
+ parent->interval = mergeIntervals(left->interval, right->interval);
+ parent->segment = NULL;
- LWDEBUGF(3, "createInteriorNode returning %p", parent);
+ LWDEBUGF(3, "createInteriorNode returning %p", parent);
- return parent;
+ return parent;
}
/*
@@ -105,52 +106,52 @@
*/
RTREE_NODE *createLeafNode(POINTARRAY *pa, int startPoint)
{
- RTREE_NODE *parent;
- LWLINE *line;
- double value1;
- double value2;
- POINT4D tmp;
- POINTARRAY *npa;
+ RTREE_NODE *parent;
+ LWLINE *line;
+ double value1;
+ double value2;
+ POINT4D tmp;
+ POINTARRAY *npa;
- LWDEBUGF(2, "createLeafNode called for point %d of %p", startPoint, pa);
+ LWDEBUGF(2, "createLeafNode called for point %d of %p", startPoint, pa);
- if(pa->npoints < startPoint + 2)
- {
- lwerror("createLeafNode: npoints = %d, startPoint = %d", pa->npoints, startPoint);
- }
+ if (pa->npoints < startPoint + 2)
+ {
+ lwerror("createLeafNode: npoints = %d, startPoint = %d", pa->npoints, startPoint);
+ }
- /*
- * The given point array will be part of a geometry that will be freed
- * independently of the index. Since we may want to cache the index,
- * we must create independent arrays.
- */
- npa = lwalloc(sizeof(POINTARRAY));
- npa->dims = 0;
- npa->npoints = 2;
- TYPE_SETZM(npa->dims, 0, 0);
- npa->serialized_pointlist = lwalloc(pointArray_ptsize(pa) * 2);
+ /*
+ * The given point array will be part of a geometry that will be freed
+ * independently of the index. Since we may want to cache the index,
+ * we must create independent arrays.
+ */
+ npa = lwalloc(sizeof(POINTARRAY));
+ npa->dims = 0;
+ npa->npoints = 2;
+ TYPE_SETZM(npa->dims, 0, 0);
+ npa->serialized_pointlist = lwalloc(pointArray_ptsize(pa) * 2);
- getPoint4d_p(pa, startPoint, &tmp);
+ getPoint4d_p(pa, startPoint, &tmp);
- setPoint4d(npa, 0, &tmp);
- value1 = tmp.y;
+ setPoint4d(npa, 0, &tmp);
+ value1 = tmp.y;
- getPoint4d_p(pa, startPoint + 1, &tmp);
+ getPoint4d_p(pa, startPoint + 1, &tmp);
- setPoint4d(npa, 1, &tmp);
- value2 = tmp.y;
-
- line = lwline_construct(-1, NULL, npa);
-
- parent = lwalloc(sizeof(RTREE_NODE));
- parent->interval = createInterval(value1, value2);
- parent->segment = line;
- parent->leftNode = NULL;
- parent->rightNode = NULL;
+ setPoint4d(npa, 1, &tmp);
+ value2 = tmp.y;
- LWDEBUGF(3, "createLeafNode returning %p", parent);
+ line = lwline_construct(-1, NULL, npa);
- return parent;
+ parent = lwalloc(sizeof(RTREE_NODE));
+ parent->interval = createInterval(value1, value2);
+ parent->segment = line;
+ parent->leftNode = NULL;
+ parent->rightNode = NULL;
+
+ LWDEBUGF(3, "createLeafNode returning %p", parent);
+
+ return parent;
}
/*
@@ -158,17 +159,17 @@
*/
INTERVAL *mergeIntervals(INTERVAL *inter1, INTERVAL *inter2)
{
- INTERVAL *interval;
+ INTERVAL *interval;
- LWDEBUGF(2, "mergeIntervals called with %p, %p", inter1, inter2);
+ LWDEBUGF(2, "mergeIntervals called with %p, %p", inter1, inter2);
- interval = lwalloc(sizeof(INTERVAL));
- interval->max = FP_MAX(inter1->max, inter2->max);
- interval->min = FP_MIN(inter1->min, inter2->min);
+ interval = lwalloc(sizeof(INTERVAL));
+ interval->max = FP_MAX(inter1->max, inter2->max);
+ interval->min = FP_MIN(inter1->min, inter2->min);
- LWDEBUGF(3, "interval min = %8.3f, max = %8.3f", interval->min, interval->max);
+ LWDEBUGF(3, "interval min = %8.3f, max = %8.3f", interval->min, interval->max);
- return interval;
+ return interval;
}
/*
@@ -176,38 +177,39 @@
*/
INTERVAL *createInterval(double value1, double value2)
{
- INTERVAL *interval;
+ INTERVAL *interval;
- LWDEBUGF(2, "createInterval called with %8.3f, %8.3f", value1, value2);
+ LWDEBUGF(2, "createInterval called with %8.3f, %8.3f", value1, value2);
- interval = lwalloc(sizeof(INTERVAL));
- interval->max = FP_MAX(value1, value2);
- interval->min = FP_MIN(value1, value2);
+ interval = lwalloc(sizeof(INTERVAL));
+ interval->max = FP_MAX(value1, value2);
+ interval->min = FP_MIN(value1, value2);
- LWDEBUGF(3, "interval min = %8.3f, max = %8.3f", interval->min, interval->max);
+ LWDEBUGF(3, "interval min = %8.3f, max = %8.3f", interval->min, interval->max);
- return interval;
+ return interval;
}
/*
- * Recursively frees the child nodes, the interval and the line before
+ * Recursively frees the child nodes, the interval and the line before
* freeing the root node.
*/
void freeTree(RTREE_NODE *root)
{
- LWDEBUGF(2, "freeTree called for %p", root);
+ LWDEBUGF(2, "freeTree called for %p", root);
- if(root->leftNode)
- freeTree(root->leftNode);
- if(root->rightNode)
- freeTree(root->rightNode);
- lwfree(root->interval);
- if(root->segment) {
- lwfree(root->segment->points->serialized_pointlist);
- lwfree(root->segment->points);
- lwgeom_release((LWGEOM *)root->segment);
- }
- lwfree(root);
+ if (root->leftNode)
+ freeTree(root->leftNode);
+ if (root->rightNode)
+ freeTree(root->rightNode);
+ lwfree(root->interval);
+ if (root->segment)
+ {
+ lwfree(root->segment->points->serialized_pointlist);
+ lwfree(root->segment->points);
+ lwgeom_release((LWGEOM *)root->segment);
+ }
+ lwfree(root);
}
@@ -218,8 +220,8 @@
{
int i;
LWDEBUGF(2, "clearCache called for %p", cache);
- for(i = 0; i < cache->ringCount; i++)
- {
+ for (i = 0; i < cache->ringCount; i++)
+ {
freeTree(cache->ringIndices[i]);
}
lwfree(cache->ringIndices);
@@ -230,164 +232,164 @@
cache->polyCount = 0;
}
-
+
/*
* Retrieves a collection of line segments given the root and crossing value.
- * The collection is a multilinestring consisting of two point lines
- * representing the segments of the ring that may be crossed by the
+ * The collection is a multilinestring consisting of two point lines
+ * representing the segments of the ring that may be crossed by the
* horizontal projection line at the given y value.
*/
LWMLINE *findLineSegments(RTREE_NODE *root, double value)
{
- LWMLINE *tmp, *result;
- LWGEOM **lwgeoms;
-
- LWDEBUGF(2, "findLineSegments called for tree %p and value %8.3f", root, value);
+ LWMLINE *tmp, *result;
+ LWGEOM **lwgeoms;
- result = NULL;
+ LWDEBUGF(2, "findLineSegments called for tree %p and value %8.3f", root, value);
- if(!isContained(root->interval, value))
- {
- LWDEBUGF(3, "findLineSegments %p: not contained.", root);
+ result = NULL;
- return NULL;
- }
+ if (!isContained(root->interval, value))
+ {
+ LWDEBUGF(3, "findLineSegments %p: not contained.", root);
- /* If there is a segment defined for this node, include it. */
- if(root->segment)
- {
- LWDEBUGF(3, "findLineSegments %p: adding segment %p %d.", root, root->segment, TYPE_GETTYPE(root->segment->type));
+ return NULL;
+ }
- lwgeoms = lwalloc(sizeof(LWGEOM *));
- lwgeoms[0] = (LWGEOM *)root->segment;
+ /* If there is a segment defined for this node, include it. */
+ if (root->segment)
+ {
+ LWDEBUGF(3, "findLineSegments %p: adding segment %p %d.", root, root->segment, TYPE_GETTYPE(root->segment->type));
- LWDEBUGF(3, "Found geom %p, type %d, dim %d", root->segment, TYPE_GETTYPE(root->segment->type), TYPE_GETZM(root->segment->type));
+ lwgeoms = lwalloc(sizeof(LWGEOM *));
+ lwgeoms[0] = (LWGEOM *)root->segment;
- result = (LWMLINE *)lwcollection_construct(lwgeom_makeType_full(0, 0, 0, MULTILINETYPE, 0), -1, NULL, 1, lwgeoms);
- }
+ LWDEBUGF(3, "Found geom %p, type %d, dim %d", root->segment, TYPE_GETTYPE(root->segment->type), TYPE_GETZM(root->segment->type));
- /* If there is a left child node, recursively include its results. */
- if(root->leftNode)
+ result = (LWMLINE *)lwcollection_construct(lwgeom_makeType_full(0, 0, 0, MULTILINETYPE, 0), -1, NULL, 1, lwgeoms);
+ }
+
+ /* If there is a left child node, recursively include its results. */
+ if (root->leftNode)
+ {
+ LWDEBUGF(3, "findLineSegments %p: recursing left.", root);
+
+ tmp = findLineSegments(root->leftNode, value);
+ if (tmp)
{
- LWDEBUGF(3, "findLineSegments %p: recursing left.", root);
+ LWDEBUGF(3, "Found geom %p, type %d, dim %d", tmp, TYPE_GETTYPE(tmp->type), TYPE_GETZM(tmp->type));
- tmp = findLineSegments(root->leftNode, value);
- if(tmp)
- {
- LWDEBUGF(3, "Found geom %p, type %d, dim %d", tmp, TYPE_GETTYPE(tmp->type), TYPE_GETZM(tmp->type));
-
- if(result)
- result = mergeMultiLines(result, tmp);
- else
- result = tmp;
- }
+ if (result)
+ result = mergeMultiLines(result, tmp);
+ else
+ result = tmp;
}
+ }
- /* Same for any right child. */
- if(root->rightNode)
+ /* Same for any right child. */
+ if (root->rightNode)
+ {
+ LWDEBUGF(3, "findLineSegments %p: recursing right.", root);
+
+ tmp = findLineSegments(root->rightNode, value);
+ if (tmp)
{
- LWDEBUGF(3, "findLineSegments %p: recursing right.", root);
+ LWDEBUGF(3, "Found geom %p, type %d, dim %d", tmp, TYPE_GETTYPE(tmp->type), TYPE_GETZM(tmp->type));
- tmp = findLineSegments(root->rightNode, value);
- if(tmp)
- {
- LWDEBUGF(3, "Found geom %p, type %d, dim %d", tmp, TYPE_GETTYPE(tmp->type), TYPE_GETZM(tmp->type));
+ if (result)
+ result = mergeMultiLines(result, tmp);
+ else
+ result = tmp;
+ }
+ }
- if(result)
- result = mergeMultiLines(result, tmp);
- else
- result = tmp;
- }
- }
-
- return result;
+ return result;
}
/* Merges two multilinestrings into a single multilinestring. */
LWMLINE *mergeMultiLines(LWMLINE *line1, LWMLINE *line2)
{
- LWGEOM **geoms;
- LWCOLLECTION *col;
- int i, j, ngeoms;
-
- LWDEBUGF(2, "mergeMultiLines called on %p, %d, %d; %p, %d, %d", line1, line1->ngeoms, TYPE_GETTYPE(line1->type), line2, line2->ngeoms, TYPE_GETTYPE(line2->type));
+ LWGEOM **geoms;
+ LWCOLLECTION *col;
+ int i, j, ngeoms;
- ngeoms = line1->ngeoms + line2->ngeoms;
- geoms = lwalloc(sizeof(LWGEOM *) * ngeoms);
+ LWDEBUGF(2, "mergeMultiLines called on %p, %d, %d; %p, %d, %d", line1, line1->ngeoms, TYPE_GETTYPE(line1->type), line2, line2->ngeoms, TYPE_GETTYPE(line2->type));
- j = 0;
- for(i = 0; i < line1->ngeoms; i++, j++)
- {
- geoms[j] = lwgeom_clone((LWGEOM *)line1->geoms[i]);
- }
- for(i = 0; i < line2->ngeoms; i++, j++)
- {
- geoms[j] = lwgeom_clone((LWGEOM *)line2->geoms[i]);
- }
- col = lwcollection_construct(MULTILINETYPE, -1, NULL, ngeoms, geoms);
+ ngeoms = line1->ngeoms + line2->ngeoms;
+ geoms = lwalloc(sizeof(LWGEOM *) * ngeoms);
- LWDEBUGF(3, "mergeMultiLines returning %p, %d, %d", col, col->ngeoms, TYPE_GETTYPE(col->type));
+ j = 0;
+ for (i = 0; i < line1->ngeoms; i++, j++)
+ {
+ geoms[j] = lwgeom_clone((LWGEOM *)line1->geoms[i]);
+ }
+ for (i = 0; i < line2->ngeoms; i++, j++)
+ {
+ geoms[j] = lwgeom_clone((LWGEOM *)line2->geoms[i]);
+ }
+ col = lwcollection_construct(MULTILINETYPE, -1, NULL, ngeoms, geoms);
- return (LWMLINE *)col;
+ LWDEBUGF(3, "mergeMultiLines returning %p, %d, %d", col, col->ngeoms, TYPE_GETTYPE(col->type));
+
+ return (LWMLINE *)col;
}
/*
* Returns 1 if min < value <= max, 0 otherwise. */
uint32 isContained(INTERVAL *interval, double value)
{
- return FP_CONTAINS_INCL(interval->min, value, interval->max) ? 1 : 0;
+ return FP_CONTAINS_INCL(interval->min, value, interval->max) ? 1 : 0;
}
PG_FUNCTION_INFO_V1(LWGEOM_polygon_index);
Datum LWGEOM_polygon_index(PG_FUNCTION_ARGS)
{
- PG_LWGEOM *igeom, *result;
- LWGEOM *geom;
- LWPOLY *poly;
- LWMLINE *mline;
- RTREE_NODE *root;
- double yval;
+ PG_LWGEOM *igeom, *result;
+ LWGEOM *geom;
+ LWPOLY *poly;
+ LWMLINE *mline;
+ RTREE_NODE *root;
+ double yval;
#if POSTGIS_DEBUG_LEVEL > 0
int i = 0;
-#endif
-
- POSTGIS_DEBUG(2, "polygon_index called.");
+#endif
- result = NULL;
- igeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
- yval = PG_GETARG_FLOAT8(1);
- geom = lwgeom_deserialize(SERIALIZED_FORM(igeom));
- if(TYPE_GETTYPE(geom->type) != POLYGONTYPE)
- {
- lwgeom_release(geom);
- PG_FREE_IF_COPY(igeom, 0);
- PG_RETURN_NULL();
- }
- poly = (LWPOLY *)geom;
- root = createTree(poly->rings[0]);
+ POSTGIS_DEBUG(2, "polygon_index called.");
- mline = findLineSegments(root, yval);
+ result = NULL;
+ igeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+ yval = PG_GETARG_FLOAT8(1);
+ geom = lwgeom_deserialize(SERIALIZED_FORM(igeom));
+ if (TYPE_GETTYPE(geom->type) != POLYGONTYPE)
+ {
+ lwgeom_release(geom);
+ PG_FREE_IF_COPY(igeom, 0);
+ PG_RETURN_NULL();
+ }
+ poly = (LWPOLY *)geom;
+ root = createTree(poly->rings[0]);
+ mline = findLineSegments(root, yval);
+
#if POSTGIS_DEBUG_LEVEL >= 3
- POSTGIS_DEBUGF(3, "mline returned %p %d", mline, TYPE_GETTYPE(mline->type));
- for(i = 0; i < mline->ngeoms; i++)
- {
- POSTGIS_DEBUGF(3, "geom[%d] %p %d", i, mline->geoms[i], TYPE_GETTYPE(mline->geoms[i]->type));
- }
+ POSTGIS_DEBUGF(3, "mline returned %p %d", mline, TYPE_GETTYPE(mline->type));
+ for (i = 0; i < mline->ngeoms; i++)
+ {
+ POSTGIS_DEBUGF(3, "geom[%d] %p %d", i, mline->geoms[i], TYPE_GETTYPE(mline->geoms[i]->type));
+ }
#endif
- if(mline)
- result = pglwgeom_serialize((LWGEOM *)mline);
+ if (mline)
+ result = pglwgeom_serialize((LWGEOM *)mline);
- POSTGIS_DEBUGF(3, "returning result %p", result);
+ POSTGIS_DEBUGF(3, "returning result %p", result);
lwfree(root);
PG_FREE_IF_COPY(igeom, 0);
- lwgeom_release((LWGEOM *)poly);
- lwgeom_release((LWGEOM *)mline);
- PG_RETURN_POINTER(result);
-
+ lwgeom_release((LWGEOM *)poly);
+ lwgeom_release((LWGEOM *)mline);
+ PG_RETURN_POINTER(result);
+
}
RTREE_POLY_CACHE * createCache()
@@ -408,10 +410,10 @@
LWMPOLY *mpoly;
LWPOLY *poly;
int nrings;
-
+
LWDEBUGF(2, "populateCache called with cache %p geom %p", currentCache, lwgeom);
- if(TYPE_GETTYPE(lwgeom->type) == MULTIPOLYGONTYPE)
+ if (TYPE_GETTYPE(lwgeom->type) == MULTIPOLYGONTYPE)
{
LWDEBUG(2, "populateCache MULTIPOLYGON");
mpoly = (LWMPOLY *)lwgeom;
@@ -419,7 +421,7 @@
/*
** Count the total number of rings.
*/
- for( i = 0; i < mpoly->ngeoms; i++ )
+ for ( i = 0; i < mpoly->ngeoms; i++ )
{
nrings += mpoly->geoms[i]->nrings;
}
@@ -429,23 +431,23 @@
/*
** Load the exterior rings onto the ringIndices array first
*/
- for( i = 0; i < mpoly->ngeoms; i++ )
+ for ( i = 0; i < mpoly->ngeoms; i++ )
{
currentCache->ringIndices[i] = createTree(mpoly->geoms[i]->rings[0]);
}
/*
** Load the interior rings (holes) onto ringIndices next
*/
- for( j = 0; j < mpoly->ngeoms; j++ )
+ for ( j = 0; j < mpoly->ngeoms; j++ )
{
- for( k = 1; k < mpoly->geoms[j]->nrings; k++ )
+ for ( k = 1; k < mpoly->geoms[j]->nrings; k++ )
{
currentCache->ringIndices[i] = createTree(mpoly->geoms[j]->rings[k]);
i++;
}
}
}
- else if ( TYPE_GETTYPE(lwgeom->type) == POLYGONTYPE )
+ else if ( TYPE_GETTYPE(lwgeom->type) == POLYGONTYPE )
{
LWDEBUG(2, "populateCache POLYGON");
poly = (LWPOLY *)lwgeom;
@@ -455,12 +457,12 @@
** Just load the rings on in order
*/
currentCache->ringIndices = lwalloc(sizeof(RTREE_NODE *) * poly->nrings);
- for( i = 0; i < poly->nrings; i++ )
+ for ( i = 0; i < poly->nrings; i++ )
{
currentCache->ringIndices[i] = createTree(poly->rings[i]);
}
}
- else
+ else
{
/* Uh oh, shouldn't be here. */
return;
@@ -472,11 +474,11 @@
*/
length = lwgeom_size(serializedPoly);
currentCache->poly = lwalloc(length);
- memcpy(currentCache->poly, serializedPoly, length);
+ memcpy(currentCache->poly, serializedPoly, length);
LWDEBUGF(3, "populateCache returning %p", currentCache);
}
-/*
+/*
* Creates a new cachable index if needed, or returns the current cache if
* it is applicable to the current polygon.
* The memory context must be changed to function scope before calling this
@@ -489,15 +491,15 @@
LWDEBUGF(2, "retrieveCache called with %p %p %p", lwgeom, serializedPoly, currentCache);
- /* Make sure this isn't someone else's cache object. */
- if( currentCache && currentCache->type != 1 ) currentCache = NULL;
+ /* Make sure this isn't someone else's cache object. */
+ if ( currentCache && currentCache->type != 1 ) currentCache = NULL;
- if(!currentCache)
+ if (!currentCache)
{
LWDEBUG(3, "No existing cache, create one.");
return createCache();
}
- if(!(currentCache->poly))
+ if (!(currentCache->poly))
{
LWDEBUG(3, "Cache contains no polygon, populating it.");
populateCache(currentCache, lwgeom, serializedPoly);
@@ -506,13 +508,13 @@
length = lwgeom_size(serializedPoly);
- if(lwgeom_size(currentCache->poly) != length)
+ if (lwgeom_size(currentCache->poly) != length)
{
LWDEBUG(3, "Polygon size mismatch, creating new cache.");
clearCache(currentCache);
return currentCache;
}
- if( memcmp(serializedPoly, currentCache->poly, length) )
+ if ( memcmp(serializedPoly, currentCache->poly, length) )
{
LWDEBUG(3, "Polygon mismatch, creating new cache.");
clearCache(currentCache);
Modified: trunk/lwgeom/lwgeom_rtree.h
===================================================================
--- trunk/lwgeom/lwgeom_rtree.h 2008-11-10 15:48:39 UTC (rev 3283)
+++ trunk/lwgeom/lwgeom_rtree.h 2008-11-10 16:35:40 UTC (rev 3284)
@@ -3,9 +3,10 @@
typedef struct
{
- double min;
- double max;
-} INTERVAL;
+ double min;
+ double max;
+}
+INTERVAL;
/* Returns 1 if min < value <= max, 0 otherwise */
uint32 isContained(INTERVAL *interval, double value);
@@ -15,25 +16,26 @@
INTERVAL *mergeIntervals(INTERVAL *inter1, INTERVAL *inter2);
/*
- * The following struct and methods are used for a 1D RTree implementation,
+ * The following struct and methods are used for a 1D RTree implementation,
* described at:
* http://lin-ear-th-inking.blogspot.com/2007/06/packed-1-dimensional-r-tree.html
*/
typedef struct rtree_node
{
- INTERVAL *interval;
- struct rtree_node *leftNode;
- struct rtree_node *rightNode;
- LWLINE* segment;
-} RTREE_NODE;
+ INTERVAL *interval;
+ struct rtree_node *leftNode;
+ struct rtree_node *rightNode;
+ LWLINE *segment;
+}
+RTREE_NODE;
/* Creates an interior node given the children. */
RTREE_NODE *createInteriorNode(RTREE_NODE *left, RTREE_NODE *right);
/* Creates a leaf node given the pointer to the start point of the segment. */
RTREE_NODE *createLeafNode(POINTARRAY *pa, int startPoint);
-/*
- * Creates an rtree given a pointer to the point array.
- * Must copy the point array.
+/*
+ * Creates an rtree given a pointer to the point array.
+ * Must copy the point array.
*/
RTREE_NODE *createTree(POINTARRAY *pointArray);
/* Frees the tree. */
@@ -46,13 +48,14 @@
typedef struct
{
char type;
- RTREE_NODE **ringIndices;
- int ringCount;
- int polyCount;
- uchar *poly;
-} RTREE_POLY_CACHE;
+ RTREE_NODE **ringIndices;
+ int ringCount;
+ int polyCount;
+ uchar *poly;
+}
+RTREE_POLY_CACHE;
-/*
+/*
* Creates a new cachable index if needed, or returns the current cache if
* it is applicable to the current polygon.
*/
More information about the postgis-commits
mailing list