PostGIS  2.5.0dev-r@@SVN_REVISION@@

◆ gserialized_peek_gbox_p()

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

Definition at line 460 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().

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