PostGIS  2.2.8dev-r@@SVN_REVISION@@

◆ RTreeBuilder()

static int RTreeBuilder ( const LWGEOM lwgeom,
GeomCache *  cache 
)
static

Callback function sent into the GetGeomCache generic caching system.

Given a LWGEOM* this function builds and stores an RTREE_POLY_CACHE into the provided GeomCache object.

Definition at line 302 of file lwgeom_rtree.c.

References LWMPOLY::geoms, RTreeGeomCache::index, LW_FAILURE, LW_SUCCESS, lwalloc(), MULTIPOLYGONTYPE, LWMPOLY::ngeoms, LWPOLY::nrings, RTREE_POLY_CACHE::polyCount, POLYGONTYPE, r, RTREE_POLY_CACHE::ringCounts, RTREE_POLY_CACHE::ringIndices, LWPOLY::rings, RTreeCacheCreate(), RTreeCreate(), and LWGEOM::type.

303 {
304  int i, p, r;
305  LWMPOLY *mpoly;
306  LWPOLY *poly;
307  int nrings;
308  RTreeGeomCache* rtree_cache = (RTreeGeomCache*)cache;
309  RTREE_POLY_CACHE* currentCache;
310 
311  if ( ! cache )
312  return LW_FAILURE;
313 
314  if ( rtree_cache->index )
315  {
316  lwpgerror("RTreeBuilder asked to build index where one already exists.");
317  return LW_FAILURE;
318  }
319 
320  if (lwgeom->type == MULTIPOLYGONTYPE)
321  {
322  POSTGIS_DEBUG(2, "RTreeBuilder MULTIPOLYGON");
323  mpoly = (LWMPOLY *)lwgeom;
324  nrings = 0;
325  /*
326  ** Count the total number of rings.
327  */
328  currentCache = RTreeCacheCreate();
329  currentCache->polyCount = mpoly->ngeoms;
330  currentCache->ringCounts = lwalloc(sizeof(int) * mpoly->ngeoms);
331  for ( i = 0; i < mpoly->ngeoms; i++ )
332  {
333  currentCache->ringCounts[i] = mpoly->geoms[i]->nrings;
334  nrings += mpoly->geoms[i]->nrings;
335  }
336  currentCache->ringIndices = lwalloc(sizeof(RTREE_NODE *) * nrings);
337  /*
338  ** Load the array in geometry order, each outer ring followed by the inner rings
339  ** associated with that outer ring
340  */
341  i = 0;
342  for ( p = 0; p < mpoly->ngeoms; p++ )
343  {
344  for ( r = 0; r < mpoly->geoms[p]->nrings; r++ )
345  {
346  currentCache->ringIndices[i] = RTreeCreate(mpoly->geoms[p]->rings[r]);
347  i++;
348  }
349  }
350  rtree_cache->index = currentCache;
351  }
352  else if ( lwgeom->type == POLYGONTYPE )
353  {
354  POSTGIS_DEBUG(2, "RTreeBuilder POLYGON");
355  poly = (LWPOLY *)lwgeom;
356  currentCache = RTreeCacheCreate();
357  currentCache->polyCount = 1;
358  currentCache->ringCounts = lwalloc(sizeof(int));
359  currentCache->ringCounts[0] = poly->nrings;
360  /*
361  ** Just load the rings on in order
362  */
363  currentCache->ringIndices = lwalloc(sizeof(RTREE_NODE *) * poly->nrings);
364  for ( i = 0; i < poly->nrings; i++ )
365  {
366  currentCache->ringIndices[i] = RTreeCreate(poly->rings[i]);
367  }
368  rtree_cache->index = currentCache;
369  }
370  else
371  {
372  /* Uh oh, shouldn't be here. */
373  lwpgerror("RTreeBuilder got asked to build index on non-polygon");
374  return LW_FAILURE;
375  }
376  return LW_SUCCESS;
377 }
char * r
Definition: cu_in_wkt.c:24
The following struct and methods are used for a 1D RTree implementation, described at: http://lin-ear...
Definition: lwgeom_rtree.h:21
#define POLYGONTYPE
Definition: liblwgeom.h:72
The tree structure used for fast P-i-P tests by point_in_multipolygon_rtree()
Definition: lwgeom_rtree.h:33
#define LW_SUCCESS
Definition: liblwgeom.h:65
#define LW_FAILURE
Definition: liblwgeom.h:64
static RTREE_NODE * RTreeCreate(POINTARRAY *pointArray)
Creates an rtree given a pointer to the point array.
Definition: lwgeom_rtree.c:204
LWPOLY ** geoms
Definition: liblwgeom.h:480
static RTREE_POLY_CACHE * RTreeCacheCreate()
Allocate a fresh clean RTREE_POLY_CACHE.
Definition: lwgeom_rtree.c:29
POINTARRAY ** rings
Definition: liblwgeom.h:441
int nrings
Definition: liblwgeom.h:439
int ngeoms
Definition: liblwgeom.h:478
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:75
uint8_t type
Definition: liblwgeom.h:380
void * lwalloc(size_t size)
Definition: lwutil.c:199
RTREE_NODE ** ringIndices
Definition: lwgeom_rtree.h:35
RTREE_POLY_CACHE * index
Definition: lwgeom_rtree.h:50
Here is the call graph for this function: