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

◆ gserialized2_peek_gbox_p()

int gserialized2_peek_gbox_p ( const GSERIALIZED g,
GBOX gbox 
)

Definition at line 393 of file gserialized2.c.

394{
395 uint32_t type = gserialized2_get_type(g);
396 uint8_t *geometry_start = gserialized2_get_geometry_p(g);
397 double *dptr = (double *)(geometry_start);
398 int32_t *iptr = (int32_t *)(geometry_start);
399
400 /* Peeking doesn't help if you already have a box or are geodetic */
402 {
403 return LW_FAILURE;
404 }
405
406 /* Boxes of points are easy peasy */
407 if (type == POINTTYPE)
408 {
409 int i = 1; /* Start past <pointtype><padding> */
410
411 /* Read the npoints flag */
412 int isempty = (iptr[1] == 0);
413
414 /* EMPTY point has no box */
415 if (isempty) return LW_FAILURE;
416
417 gbox->xmin = gbox->xmax = dptr[i++];
418 gbox->ymin = gbox->ymax = dptr[i++];
420 if (G2FLAGS_GET_Z(g->gflags))
421 {
422 gbox->zmin = gbox->zmax = dptr[i++];
423 }
424 if (G2FLAGS_GET_M(g->gflags))
425 {
426 gbox->mmin = gbox->mmax = dptr[i++];
427 }
428 gbox_float_round(gbox);
429 return LW_SUCCESS;
430 }
431 /* We can calculate the box of a two-point cartesian line trivially */
432 else if (type == LINETYPE)
433 {
434 int ndims = G2FLAGS_NDIMS(g->gflags);
435 int i = 0; /* Start at <linetype><npoints> */
436 int npoints = iptr[1]; /* Read the npoints */
437
438 /* This only works with 2-point lines */
439 if (npoints != 2)
440 return LW_FAILURE;
441
442 /* Advance to X */
443 /* Past <linetype><npoints> */
444 i++;
445 gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
446 gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
447
448 /* Advance to Y */
449 i++;
450 gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
451 gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
452
454 if (G2FLAGS_GET_Z(g->gflags))
455 {
456 /* Advance to Z */
457 i++;
458 gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
459 gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
460 }
461 if (G2FLAGS_GET_M(g->gflags))
462 {
463 /* Advance to M */
464 i++;
465 gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
466 gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
467 }
468 gbox_float_round(gbox);
469 return LW_SUCCESS;
470 }
471 /* We can also do single-entry multi-points */
472 else if (type == MULTIPOINTTYPE)
473 {
474 int i = 0; /* Start at <multipointtype><ngeoms> */
475 int ngeoms = iptr[1]; /* Read the ngeoms */
476 int npoints;
477
478 /* This only works with single-entry multipoints */
479 if (ngeoms != 1)
480 return LW_FAILURE;
481
482 /* Npoints is at <multipointtype><ngeoms><pointtype><npoints> */
483 npoints = iptr[3];
484
485 /* The check below is necessary because we can have a MULTIPOINT
486 * that contains a single, empty POINT (ngeoms = 1, npoints = 0) */
487 if (npoints != 1)
488 return LW_FAILURE;
489
490 /* Move forward two doubles (four ints) */
491 /* Past <multipointtype><ngeoms> */
492 /* Past <pointtype><npoints> */
493 i += 2;
494
495 /* Read the doubles from the one point */
496 gbox->xmin = gbox->xmax = dptr[i++];
497 gbox->ymin = gbox->ymax = dptr[i++];
499 if (G2FLAGS_GET_Z(g->gflags))
500 {
501 gbox->zmin = gbox->zmax = dptr[i++];
502 }
503 if (G2FLAGS_GET_M(g->gflags))
504 {
505 gbox->mmin = gbox->mmax = dptr[i++];
506 }
507 gbox_float_round(gbox);
508 return LW_SUCCESS;
509 }
510 /* And we can do single-entry multi-lines with two vertices (!!!) */
511 else if (type == MULTILINETYPE)
512 {
513 int ndims = G2FLAGS_NDIMS(g->gflags);
514 int i = 0; /* Start at <multilinetype><ngeoms> */
515 int ngeoms = iptr[1]; /* Read the ngeoms */
516 int npoints;
517
518 /* This only works with 1-line multilines */
519 if (ngeoms != 1)
520 return LW_FAILURE;
521
522 /* Npoints is at <multilinetype><ngeoms><linetype><npoints> */
523 npoints = iptr[3];
524
525 if (npoints != 2)
526 return LW_FAILURE;
527
528 /* Advance to X */
529 /* Move forward two doubles (four ints) */
530 /* Past <multilinetype><ngeoms> */
531 /* Past <linetype><npoints> */
532 i += 2;
533 gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
534 gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
535
536 /* Advance to Y */
537 i++;
538 gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
539 gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
540
542 if (G2FLAGS_GET_Z(g->gflags))
543 {
544 /* Advance to Z */
545 i++;
546 gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
547 gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
548 }
549 if (G2FLAGS_GET_M(g->gflags))
550 {
551 /* Advance to M */
552 i++;
553 gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
554 gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
555 }
556 gbox_float_round(gbox);
557 return LW_SUCCESS;
558 }
559
560 return LW_FAILURE;
561}
void gbox_float_round(GBOX *gbox)
Round given GBOX to float boundaries.
Definition gbox.c:774
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:110
#define MULTILINETYPE
Definition liblwgeom.h:120
#define LINETYPE
Definition liblwgeom.h:117
#define LW_SUCCESS
Definition liblwgeom.h:111
#define MULTIPOINTTYPE
Definition liblwgeom.h:119
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:116
#define FP_MAX(A, B)
#define FP_MIN(A, B)
double ymax
Definition liblwgeom.h:343
double zmax
Definition liblwgeom.h:345
double xmax
Definition liblwgeom.h:341
double zmin
Definition liblwgeom.h:344
double mmax
Definition liblwgeom.h:347
double ymin
Definition liblwgeom.h:342
double xmin
Definition liblwgeom.h:340
double mmin
Definition liblwgeom.h:346
lwflags_t flags
Definition liblwgeom.h:339
uint8_t gflags
Definition liblwgeom.h:432

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: