PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ gserialized_peek_gbox_p()

static int gserialized_peek_gbox_p ( const GSERIALIZED g,
GBOX gbox 
)
static

Definition at line 463 of file g_serialized.c.

References GSERIALIZED::data, GBOX::flags, GSERIALIZED::flags, FLAGS_GET_BBOX, FLAGS_GET_GEODETIC, FLAGS_GET_M, FLAGS_GET_Z, FLAGS_NDIMS, FP_MAX, FP_MIN, gbox_float_round(), gserialized_get_type(), LINETYPE, LW_FAILURE, LW_SUCCESS, GBOX::mmax, GBOX::mmin, MULTILINETYPE, MULTIPOINTTYPE, POINTTYPE, ovdump::type, GBOX::xmax, GBOX::xmin, GBOX::ymax, GBOX::ymin, GBOX::zmax, and GBOX::zmin.

Referenced by gserialized_get_gbox_p(), test_gserialized_peek_gbox_p_fails_for_unsupported_cases(), test_gserialized_peek_gbox_p_gets_correct_box(), and test_gserialized_peek_gbox_p_no_box_when_empty().

464 {
466 
467  /* Peeking doesn't help if you already have a box or are geodetic */
468  if ( FLAGS_GET_GEODETIC(g->flags) || FLAGS_GET_BBOX(g->flags) )
469  {
470  return LW_FAILURE;
471  }
472 
473  /* Boxes of points are easy peasy */
474  if ( type == POINTTYPE )
475  {
476  int i = 1; /* Start past <pointtype><padding> */
477  double *dptr = (double*)(g->data);
478 
479  /* Read the empty flag */
480  int *iptr = (int*)(g->data);
481  int isempty = (iptr[1] == 0);
482 
483  /* EMPTY point has no box */
484  if ( isempty ) return LW_FAILURE;
485 
486  gbox->xmin = gbox->xmax = dptr[i++];
487  gbox->ymin = gbox->ymax = dptr[i++];
488  gbox->flags = g->flags;
489  if ( FLAGS_GET_Z(g->flags) )
490  {
491  gbox->zmin = gbox->zmax = dptr[i++];
492  }
493  if ( FLAGS_GET_M(g->flags) )
494  {
495  gbox->mmin = gbox->mmax = dptr[i++];
496  }
497  gbox_float_round(gbox);
498  return LW_SUCCESS;
499  }
500  /* We can calculate the box of a two-point cartesian line trivially */
501  else if ( type == LINETYPE )
502  {
503  int ndims = FLAGS_NDIMS(g->flags);
504  int i = 0; /* Start at <linetype><npoints> */
505  double *dptr = (double*)(g->data);
506  int *iptr = (int*)(g->data);
507  int npoints = iptr[1]; /* Read the npoints */
508 
509  /* This only works with 2-point lines */
510  if ( npoints != 2 )
511  return LW_FAILURE;
512 
513  /* Advance to X */
514  /* Past <linetype><npoints> */
515  i++;
516  gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
517  gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
518 
519  /* Advance to Y */
520  i++;
521  gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
522  gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
523 
524  gbox->flags = g->flags;
525  if ( FLAGS_GET_Z(g->flags) )
526  {
527  /* Advance to Z */
528  i++;
529  gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
530  gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
531  }
532  if ( FLAGS_GET_M(g->flags) )
533  {
534  /* Advance to M */
535  i++;
536  gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
537  gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
538  }
539  gbox_float_round(gbox);
540  return LW_SUCCESS;
541  }
542  /* We can also do single-entry multi-points */
543  else if ( type == MULTIPOINTTYPE )
544  {
545  int i = 0; /* Start at <multipointtype><ngeoms> */
546  double *dptr = (double*)(g->data);
547  int *iptr = (int*)(g->data);
548  int ngeoms = iptr[1]; /* Read the ngeoms */
549  int npoints;
550 
551  /* This only works with single-entry multipoints */
552  if ( ngeoms != 1 )
553  return LW_FAILURE;
554 
555  /* Npoints is at <multipointtype><ngeoms><pointtype><npoints> */
556  npoints = iptr[3];
557 
558  /* The check below is necessary because we can have a MULTIPOINT
559  * that contains a single, empty POINT (ngeoms = 1, npoints = 0) */
560  if ( npoints != 1 )
561  return LW_FAILURE;
562 
563  /* Move forward two doubles (four ints) */
564  /* Past <multipointtype><ngeoms> */
565  /* Past <pointtype><npoints> */
566  i += 2;
567 
568  /* Read the doubles from the one point */
569  gbox->xmin = gbox->xmax = dptr[i++];
570  gbox->ymin = gbox->ymax = dptr[i++];
571  gbox->flags = g->flags;
572  if ( FLAGS_GET_Z(g->flags) )
573  {
574  gbox->zmin = gbox->zmax = dptr[i++];
575  }
576  if ( FLAGS_GET_M(g->flags) )
577  {
578  gbox->mmin = gbox->mmax = dptr[i++];
579  }
580  gbox_float_round(gbox);
581  return LW_SUCCESS;
582  }
583  /* And we can do single-entry multi-lines with two vertices (!!!) */
584  else if ( type == MULTILINETYPE )
585  {
586  int ndims = FLAGS_NDIMS(g->flags);
587  int i = 0; /* Start at <multilinetype><ngeoms> */
588  double *dptr = (double*)(g->data);
589  int *iptr = (int*)(g->data);
590  int ngeoms = iptr[1]; /* Read the ngeoms */
591  int npoints;
592 
593  /* This only works with 1-line multilines */
594  if ( ngeoms != 1 )
595  return LW_FAILURE;
596 
597  /* Npoints is at <multilinetype><ngeoms><linetype><npoints> */
598  npoints = iptr[3];
599 
600  if ( npoints != 2 )
601  return LW_FAILURE;
602 
603  /* Advance to X */
604  /* Move forward two doubles (four ints) */
605  /* Past <multilinetype><ngeoms> */
606  /* Past <linetype><npoints> */
607  i += 2;
608  gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
609  gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
610 
611  /* Advance to Y */
612  i++;
613  gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
614  gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
615 
616  gbox->flags = g->flags;
617  if ( FLAGS_GET_Z(g->flags) )
618  {
619  /* Advance to Z */
620  i++;
621  gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
622  gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
623  }
624  if ( FLAGS_GET_M(g->flags) )
625  {
626  /* Advance to M */
627  i++;
628  gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
629  gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
630  }
631  gbox_float_round(gbox);
632  return LW_SUCCESS;
633  }
634 
635  return LW_FAILURE;
636 }
#define LINETYPE
Definition: liblwgeom.h:86
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
Definition: g_serialized.c:86
uint8_t data[1]
Definition: liblwgeom.h:384
#define FLAGS_GET_GEODETIC(flags)
Definition: liblwgeom.h:143
double xmax
Definition: liblwgeom.h:293
#define MULTIPOINTTYPE
Definition: liblwgeom.h:88
#define LW_SUCCESS
Definition: liblwgeom.h:80
#define FP_MIN(A, B)
#define LW_FAILURE
Definition: liblwgeom.h:79
unsigned int uint32_t
Definition: uthash.h:78
void gbox_float_round(GBOX *gbox)
Round given GBOX to float boundaries.
Definition: g_box.c:717
double zmax
Definition: liblwgeom.h:297
double ymin
Definition: liblwgeom.h:294
double xmin
Definition: liblwgeom.h:292
#define FLAGS_GET_BBOX(flags)
Definition: liblwgeom.h:142
double ymax
Definition: liblwgeom.h:295
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:140
uint8_t flags
Definition: liblwgeom.h:291
double mmin
Definition: liblwgeom.h:298
double zmin
Definition: liblwgeom.h:296
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:85
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:141
type
Definition: ovdump.py:41
double mmax
Definition: liblwgeom.h:299
#define MULTILINETYPE
Definition: liblwgeom.h:89
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:152
uint8_t flags
Definition: liblwgeom.h:383
#define FP_MAX(A, B)
Here is the call graph for this function:
Here is the caller graph for this function: