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

◆ gserialized2_peek_gbox_p()

int gserialized2_peek_gbox_p ( const GSERIALIZED g,
GBOX gbox 
)

Definition at line 362 of file gserialized2.c.

363{
364 uint32_t type = gserialized2_get_type(g);
365 uint8_t *geometry_start = gserialized2_get_geometry_p(g);
366 double *dptr = (double *)(geometry_start);
367 int32_t *iptr = (int32_t *)(geometry_start);
368
369 /* Peeking doesn't help if you already have a box or are geodetic */
371 {
372 return LW_FAILURE;
373 }
374
375 /* Boxes of points are easy peasy */
376 if (type == POINTTYPE)
377 {
378 int i = 1; /* Start past <pointtype><padding> */
379
380 /* Read the npoints flag */
381 int isempty = (iptr[1] == 0);
382
383 /* EMPTY point has no box */
384 if (isempty) return LW_FAILURE;
385
386 gbox->xmin = gbox->xmax = dptr[i++];
387 gbox->ymin = gbox->ymax = dptr[i++];
389 if (G2FLAGS_GET_Z(g->gflags))
390 {
391 gbox->zmin = gbox->zmax = dptr[i++];
392 }
393 if (G2FLAGS_GET_M(g->gflags))
394 {
395 gbox->mmin = gbox->mmax = dptr[i++];
396 }
397 gbox_float_round(gbox);
398 return LW_SUCCESS;
399 }
400 /* We can calculate the box of a two-point cartesian line trivially */
401 else if (type == LINETYPE)
402 {
403 int ndims = G2FLAGS_NDIMS(g->gflags);
404 int i = 0; /* Start at <linetype><npoints> */
405 int npoints = iptr[1]; /* Read the npoints */
406
407 /* This only works with 2-point lines */
408 if (npoints != 2)
409 return LW_FAILURE;
410
411 /* Advance to X */
412 /* Past <linetype><npoints> */
413 i++;
414 gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
415 gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
416
417 /* Advance to Y */
418 i++;
419 gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
420 gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
421
423 if (G2FLAGS_GET_Z(g->gflags))
424 {
425 /* Advance to Z */
426 i++;
427 gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
428 gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
429 }
430 if (G2FLAGS_GET_M(g->gflags))
431 {
432 /* Advance to M */
433 i++;
434 gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
435 gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
436 }
437 gbox_float_round(gbox);
438 return LW_SUCCESS;
439 }
440 /* We can also do single-entry multi-points */
441 else if (type == MULTIPOINTTYPE)
442 {
443 int i = 0; /* Start at <multipointtype><ngeoms> */
444 int ngeoms = iptr[1]; /* Read the ngeoms */
445 int npoints;
446
447 /* This only works with single-entry multipoints */
448 if (ngeoms != 1)
449 return LW_FAILURE;
450
451 /* Npoints is at <multipointtype><ngeoms><pointtype><npoints> */
452 npoints = iptr[3];
453
454 /* The check below is necessary because we can have a MULTIPOINT
455 * that contains a single, empty POINT (ngeoms = 1, npoints = 0) */
456 if (npoints != 1)
457 return LW_FAILURE;
458
459 /* Move forward two doubles (four ints) */
460 /* Past <multipointtype><ngeoms> */
461 /* Past <pointtype><npoints> */
462 i += 2;
463
464 /* Read the doubles from the one point */
465 gbox->xmin = gbox->xmax = dptr[i++];
466 gbox->ymin = gbox->ymax = dptr[i++];
468 if (G2FLAGS_GET_Z(g->gflags))
469 {
470 gbox->zmin = gbox->zmax = dptr[i++];
471 }
472 if (G2FLAGS_GET_M(g->gflags))
473 {
474 gbox->mmin = gbox->mmax = dptr[i++];
475 }
476 gbox_float_round(gbox);
477 return LW_SUCCESS;
478 }
479 /* And we can do single-entry multi-lines with two vertices (!!!) */
480 else if (type == MULTILINETYPE)
481 {
482 int ndims = G2FLAGS_NDIMS(g->gflags);
483 int i = 0; /* Start at <multilinetype><ngeoms> */
484 int ngeoms = iptr[1]; /* Read the ngeoms */
485 int npoints;
486
487 /* This only works with 1-line multilines */
488 if (ngeoms != 1)
489 return LW_FAILURE;
490
491 /* Npoints is at <multilinetype><ngeoms><linetype><npoints> */
492 npoints = iptr[3];
493
494 if (npoints != 2)
495 return LW_FAILURE;
496
497 /* Advance to X */
498 /* Move forward two doubles (four ints) */
499 /* Past <multilinetype><ngeoms> */
500 /* Past <linetype><npoints> */
501 i += 2;
502 gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
503 gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
504
505 /* Advance to Y */
506 i++;
507 gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
508 gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
509
511 if (G2FLAGS_GET_Z(g->gflags))
512 {
513 /* Advance to Z */
514 i++;
515 gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
516 gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
517 }
518 if (G2FLAGS_GET_M(g->gflags))
519 {
520 /* Advance to M */
521 i++;
522 gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
523 gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
524 }
525 gbox_float_round(gbox);
526 return LW_SUCCESS;
527 }
528
529 return LW_FAILURE;
530}
void gbox_float_round(GBOX *gbox)
Round given GBOX to float boundaries.
Definition gbox.c:786
uint32_t gserialized2_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
static uint8_t * gserialized2_get_geometry_p(const GSERIALIZED *g)
lwflags_t gserialized2_get_lwflags(const GSERIALIZED *g)
Read the flags from a GSERIALIZED and return a standard lwflag integer.
#define G2FLAGS_GET_BBOX(gflags)
#define G2FLAGS_GET_GEODETIC(gflags)
#define G2FLAGS_GET_Z(gflags)
#define G2FLAGS_GET_M(gflags)
#define G2FLAGS_NDIMS(gflags)
#define LW_FAILURE
Definition liblwgeom.h:96
#define MULTILINETYPE
Definition liblwgeom.h:106
#define LINETYPE
Definition liblwgeom.h:103
#define LW_SUCCESS
Definition liblwgeom.h:97
#define MULTIPOINTTYPE
Definition liblwgeom.h:105
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
#define FP_MAX(A, B)
#define FP_MIN(A, B)
double ymax
Definition liblwgeom.h:357
double zmax
Definition liblwgeom.h:359
double xmax
Definition liblwgeom.h:355
double zmin
Definition liblwgeom.h:358
double mmax
Definition liblwgeom.h:361
double ymin
Definition liblwgeom.h:356
double xmin
Definition liblwgeom.h:354
double mmin
Definition liblwgeom.h:360
lwflags_t flags
Definition liblwgeom.h:353
uint8_t gflags
Definition liblwgeom.h:446

References GBOX::flags, FP_MAX, FP_MIN, G2FLAGS_GET_BBOX, G2FLAGS_GET_GEODETIC, G2FLAGS_GET_M, G2FLAGS_GET_Z, G2FLAGS_NDIMS, gbox_float_round(), GSERIALIZED::gflags, gserialized2_get_geometry_p(), gserialized2_get_lwflags(), gserialized2_get_type(), LINETYPE, LW_FAILURE, LW_SUCCESS, GBOX::mmax, GBOX::mmin, MULTILINETYPE, MULTIPOINTTYPE, POINTTYPE, GBOX::xmax, GBOX::xmin, GBOX::ymax, GBOX::ymin, GBOX::zmax, and GBOX::zmin.

Referenced by gserialized2_fast_gbox_p(), gserialized2_get_gbox_p(), test_gserialized2_peek_gbox_p_fails_for_unsupported_cases(), test_gserialized2_peek_gbox_p_gets_correct_box(), and test_gserialized2_peek_gbox_p_no_box_when_empty().

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