PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ gserialized_peek_gbox_p()

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

Definition at line 461 of file g_serialized.c.

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

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().

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