PostGIS  2.3.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 316 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.

317 {
318  int i, p, r;
319  LWMPOLY *mpoly;
320  LWPOLY *poly;
321  int nrings;
322  RTreeGeomCache* rtree_cache = (RTreeGeomCache*)cache;
323  RTREE_POLY_CACHE* currentCache;
324 
325  if ( ! cache )
326  return LW_FAILURE;
327 
328  if ( rtree_cache->index )
329  {
330  lwpgerror("RTreeBuilder asked to build index where one already exists.");
331  return LW_FAILURE;
332  }
333 
334  if (lwgeom->type == MULTIPOLYGONTYPE)
335  {
336  POSTGIS_DEBUG(2, "RTreeBuilder MULTIPOLYGON");
337  mpoly = (LWMPOLY *)lwgeom;
338  nrings = 0;
339  /*
340  ** Count the total number of rings.
341  */
342  currentCache = RTreeCacheCreate();
343  currentCache->polyCount = mpoly->ngeoms;
344  currentCache->ringCounts = lwalloc(sizeof(int) * mpoly->ngeoms);
345  for ( i = 0; i < mpoly->ngeoms; i++ )
346  {
347  currentCache->ringCounts[i] = mpoly->geoms[i]->nrings;
348  nrings += mpoly->geoms[i]->nrings;
349  }
350  currentCache->ringIndices = lwalloc(sizeof(RTREE_NODE *) * nrings);
351  /*
352  ** Load the array in geometry order, each outer ring followed by the inner rings
353  ** associated with that outer ring
354  */
355  i = 0;
356  for ( p = 0; p < mpoly->ngeoms; p++ )
357  {
358  for ( r = 0; r < mpoly->geoms[p]->nrings; r++ )
359  {
360  currentCache->ringIndices[i] = RTreeCreate(mpoly->geoms[p]->rings[r]);
361  i++;
362  }
363  }
364  rtree_cache->index = currentCache;
365  }
366  else if ( lwgeom->type == POLYGONTYPE )
367  {
368  POSTGIS_DEBUG(2, "RTreeBuilder POLYGON");
369  poly = (LWPOLY *)lwgeom;
370  currentCache = RTreeCacheCreate();
371  currentCache->polyCount = 1;
372  currentCache->ringCounts = lwalloc(sizeof(int));
373  currentCache->ringCounts[0] = poly->nrings;
374  /*
375  ** Just load the rings on in order
376  */
377  currentCache->ringIndices = lwalloc(sizeof(RTREE_NODE *) * poly->nrings);
378  for ( i = 0; i < poly->nrings; i++ )
379  {
380  currentCache->ringIndices[i] = RTreeCreate(poly->rings[i]);
381  }
382  rtree_cache->index = currentCache;
383  }
384  else
385  {
386  /* Uh oh, shouldn't be here. */
387  lwpgerror("RTreeBuilder got asked to build index on non-polygon");
388  return LW_FAILURE;
389  }
390  return LW_SUCCESS;
391 }
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:45
#define POLYGONTYPE
Definition: liblwgeom.h:86
The tree structure used for fast P-i-P tests by point_in_multipolygon_rtree()
Definition: lwgeom_rtree.h:57
#define LW_SUCCESS
Definition: liblwgeom.h:79
#define LW_FAILURE
Definition: liblwgeom.h:78
static RTREE_NODE * RTreeCreate(POINTARRAY *pointArray)
Creates an rtree given a pointer to the point array.
Definition: lwgeom_rtree.c:218
LWPOLY ** geoms
Definition: liblwgeom.h:495
static RTREE_POLY_CACHE * RTreeCacheCreate()
Allocate a fresh clean RTREE_POLY_CACHE.
Definition: lwgeom_rtree.c:43
POINTARRAY ** rings
Definition: liblwgeom.h:456
int nrings
Definition: liblwgeom.h:454
int ngeoms
Definition: liblwgeom.h:493
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:89
uint8_t type
Definition: liblwgeom.h:395
void * lwalloc(size_t size)
Definition: lwutil.c:227
RTREE_NODE ** ringIndices
Definition: lwgeom_rtree.h:59
RTREE_POLY_CACHE * index
Definition: lwgeom_rtree.h:74
Here is the call graph for this function: