PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ lwgeom_solid_contains_lwgeom()

static int lwgeom_solid_contains_lwgeom ( const LWGEOM solid,
const LWGEOM g 
)
inlinestatic

Definition at line 348 of file measures3d.c.

349 {
350  const GBOX *b1;
351  const GBOX *b2;
352 
353  /* If solid isn't solid it can't contain anything */
354  if (!FLAGS_GET_SOLID(solid->flags))
355  return LW_FALSE;
356 
357  b1 = lwgeom_get_bbox(solid);
358  b2 = lwgeom_get_bbox(g);
359 
360  /* If box won't contain box, shape won't contain shape */
361  if (!gbox_contains_3d(b1, b2))
362  return LW_FALSE;
363  else /* Raycast upwards in Z */
364  {
365  POINT4D pt;
366  /* We'll skew copies if we're not lucky */
367  LWGEOM *solid_copy = lwgeom_clone_deep(solid);
368  LWGEOM *g_copy = lwgeom_clone_deep(g);
369 
370  while (LW_TRUE)
371  {
372  uint8_t is_boundary = LW_FALSE;
373  uint8_t is_inside = LW_FALSE;
374 
375  /* take first point */
376  if (!lwgeom_startpoint(g_copy, &pt))
377  return LW_FALSE;
378 
379  /* get part of solid that is upwards */
380  LWCOLLECTION *c = lwgeom_clip_to_ordinate_range(solid_copy, 'Z', pt.z, DBL_MAX, 0);
381 
382  for (uint32_t i = 0; i < c->ngeoms; i++)
383  {
384  if (c->geoms[i]->type == POLYGONTYPE)
385  {
386  /* 3D raycast along Z is 2D point in polygon */
387  int t = lwpoly_contains_point((LWPOLY *)c->geoms[i], (POINT2D *)&pt);
388 
389  if (t == LW_INSIDE)
390  is_inside = !is_inside;
391  else if (t == LW_BOUNDARY)
392  {
393  is_boundary = LW_TRUE;
394  break;
395  }
396  }
397  else if (c->geoms[i]->type == TRIANGLETYPE)
398  {
399  /* 3D raycast along Z is 2D point in polygon */
400  LWTRIANGLE *tri = (LWTRIANGLE *)c->geoms[i];
401  int t = ptarray_contains_point(tri->points, (POINT2D *)&pt);
402 
403  if (t == LW_INSIDE)
404  is_inside = !is_inside;
405  else if (t == LW_BOUNDARY)
406  {
407  is_boundary = LW_TRUE;
408  break;
409  }
410  }
411  }
412 
414  lwgeom_free(solid_copy);
415  lwgeom_free(g_copy);
416 
417  if (is_boundary)
418  {
419  /* randomly skew a bit and restart*/
420  double cx = lwrandom_uniform() - 0.5;
421  double cy = lwrandom_uniform() - 0.5;
422  AFFINE aff = {1, 0, cx, 0, 1, cy, 0, 0, 1, 0, 0, 0};
423 
424  solid_copy = lwgeom_clone_deep(solid);
425  lwgeom_affine(solid_copy, &aff);
426 
427  g_copy = lwgeom_clone_deep(g);
428  lwgeom_affine(g_copy, &aff);
429 
430  continue;
431  }
432  return is_inside;
433  }
434  }
435 }
#define LW_FALSE
Definition: liblwgeom.h:108
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
Definition: lwgeom.c:2113
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1138
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
Definition: lwgeom.c:511
#define POLYGONTYPE
Definition: liblwgeom.h:118
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
Definition: lwgeom.c:1975
LWCOLLECTION * lwgeom_clip_to_ordinate_range(const LWGEOM *lwin, char ordinate, double from, double to, double offset)
Given a geometry clip based on the from/to range of one of its ordinates (x, y, z,...
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:357
#define FLAGS_GET_SOLID(flags)
Definition: liblwgeom.h:184
const GBOX * lwgeom_get_bbox(const LWGEOM *lwgeom)
Get a non-empty geometry bounding box, computing and caching it if not already there.
Definition: lwgeom.c:725
#define TRIANGLETYPE
Definition: liblwgeom.h:129
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:107
#define LW_INSIDE
Constants for point-in-polygon return values.
#define LW_BOUNDARY
int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt)
Return 1 if the point is inside the POINTARRAY, -1 if it is outside, and 0 if it is on the boundary.
Definition: ptarray.c:732
int lwpoly_contains_point(const LWPOLY *poly, const POINT2D *pt)
Definition: lwpoly.c:532
double lwrandom_uniform(void)
Definition: lwrandom.c:94
static int gbox_contains_3d(const GBOX *g1, const GBOX *g2)
Definition: measures3d.c:341
uint32_t ngeoms
Definition: liblwgeom.h:566
LWGEOM ** geoms
Definition: liblwgeom.h:561
uint8_t type
Definition: liblwgeom.h:448
lwflags_t flags
Definition: liblwgeom.h:447
POINTARRAY * points
Definition: liblwgeom.h:481
double z
Definition: liblwgeom.h:400

References LWGEOM::flags, FLAGS_GET_SOLID, gbox_contains_3d(), LWCOLLECTION::geoms, LW_BOUNDARY, LW_FALSE, LW_INSIDE, LW_TRUE, lwcollection_free(), lwgeom_affine(), lwgeom_clip_to_ordinate_range(), lwgeom_clone_deep(), lwgeom_free(), lwgeom_get_bbox(), lwgeom_startpoint(), lwpoly_contains_point(), lwrandom_uniform(), LWCOLLECTION::ngeoms, LWTRIANGLE::points, POLYGONTYPE, ptarray_contains_point(), TRIANGLETYPE, LWGEOM::type, and POINT4D::z.

Referenced by lwgeom_mindistance3d_tolerance().

Here is the call graph for this function:
Here is the caller graph for this function: