PostGIS  3.7.0dev-r@@SVN_REVISION@@

◆ lwgeom_solid_contains_lwgeom()

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

Definition at line 382 of file measures3d.c.

383 {
384  const GBOX *b1;
385  const GBOX *b2;
386 
387  /* If solid isn't solid it can't contain anything */
388  if (!FLAGS_GET_SOLID(solid->flags))
389  return LW_FALSE;
390 
391  b1 = lwgeom_get_bbox(solid);
392  b2 = lwgeom_get_bbox(g);
393 
394  /* If box won't contain box, shape won't contain shape */
395  if (!gbox_contains_3d(b1, b2))
396  return LW_FALSE;
397  else /* Raycast upwards in Z */
398  {
399  POINT4D pt;
400  /* We'll skew copies if we're not lucky */
401  LWGEOM *solid_copy = lwgeom_clone_deep(solid);
402  LWGEOM *g_copy = lwgeom_clone_deep(g);
403 
404  while (LW_TRUE)
405  {
406  uint8_t is_boundary = LW_FALSE;
407  uint8_t is_inside = LW_FALSE;
408 
409  /* take first point */
410  if (!lwgeom_startpoint(g_copy, &pt))
411  return LW_FALSE;
412 
413  /* get part of solid that is upwards */
414  LWCOLLECTION *c = lwgeom_clip_to_ordinate_range(solid_copy, 'Z', pt.z, DBL_MAX, 0);
415 
416  for (uint32_t i = 0; i < c->ngeoms; i++)
417  {
418  if (c->geoms[i]->type == POLYGONTYPE)
419  {
420  /* 3D raycast along Z is 2D point in polygon */
421  int t = lwpoly_contains_point((LWPOLY *)c->geoms[i], (POINT2D *)&pt);
422 
423  if (t == LW_INSIDE)
424  is_inside = !is_inside;
425  else if (t == LW_BOUNDARY)
426  {
427  is_boundary = LW_TRUE;
428  break;
429  }
430  }
431  else if (c->geoms[i]->type == TRIANGLETYPE)
432  {
433  /* 3D raycast along Z is 2D point in polygon */
434  LWTRIANGLE *tri = (LWTRIANGLE *)c->geoms[i];
435  int t = ptarray_contains_point(tri->points, (POINT2D *)&pt);
436 
437  if (t == LW_INSIDE)
438  is_inside = !is_inside;
439  else if (t == LW_BOUNDARY)
440  {
441  is_boundary = LW_TRUE;
442  break;
443  }
444  }
445  }
446 
448  lwgeom_free(solid_copy);
449  lwgeom_free(g_copy);
450 
451  if (is_boundary)
452  {
453  /* randomly skew a bit and restart*/
454  double cx = lwrandom_uniform() - 0.5;
455  double cy = lwrandom_uniform() - 0.5;
456  AFFINE aff = {1, 0, cx, 0, 1, cy, 0, 0, 1, 0, 0, 0};
457 
458  solid_copy = lwgeom_clone_deep(solid);
459  lwgeom_affine(solid_copy, &aff);
460 
461  g_copy = lwgeom_clone_deep(g);
462  lwgeom_affine(g_copy, &aff);
463 
464  continue;
465  }
466  return is_inside;
467  }
468  }
469 }
#define LW_FALSE
Definition: liblwgeom.h:94
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
Definition: lwgeom.c:2221
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1218
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
Definition: lwgeom.c:529
#define POLYGONTYPE
Definition: liblwgeom.h:104
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
Definition: lwgeom.c:2083
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:170
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:743
#define TRIANGLETYPE
Definition: liblwgeom.h:115
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
#define LW_INSIDE
Constants for point-in-polygon return values.
#define LW_BOUNDARY
int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt)
Return LW_INSIDE if the point is inside the POINTARRAY, LW_OUTSIDE if it is outside,...
Definition: ptarray.c:751
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:375
uint32_t ngeoms
Definition: liblwgeom.h:580
LWGEOM ** geoms
Definition: liblwgeom.h:575
uint8_t type
Definition: liblwgeom.h:462
lwflags_t flags
Definition: liblwgeom.h:461
POINTARRAY * points
Definition: liblwgeom.h:495
double z
Definition: liblwgeom.h:414

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: