PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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
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,...
#define POLYGONTYPE
Definition liblwgeom.h:118
void lwgeom_affine(LWGEOM *geom, const AFFINE *affine)
Definition lwgeom.c:1975
void lwcollection_free(LWCOLLECTION *col)
#define FLAGS_GET_SOLID(flags)
Definition liblwgeom.h:184
#define TRIANGLETYPE
Definition liblwgeom.h:129
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
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
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
Definition lwgeom.c:511
#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:740
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
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: