PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ gserialized1_peek_gbox_p()

int gserialized1_peek_gbox_p ( const GSERIALIZED g,
GBOX gbox 
)

Definition at line 298 of file gserialized1.c.

299 {
300  uint32_t type = gserialized1_get_type(g);
301 
302  /* Peeking doesn't help if you already have a box or are geodetic */
304  {
305  return LW_FAILURE;
306  }
307 
308  /* Boxes of points are easy peasy */
309  if ( type == POINTTYPE )
310  {
311  int i = 1; /* Start past <pointtype><padding> */
312  double *dptr = (double*)(g->data);
313 
314  /* Read the empty flag */
315  int32_t *iptr = (int32_t *)(g->data);
316  int isempty = (iptr[1] == 0);
317 
318  /* EMPTY point has no box */
319  if ( isempty ) return LW_FAILURE;
320 
321  gbox->xmin = gbox->xmax = dptr[i++];
322  gbox->ymin = gbox->ymax = dptr[i++];
323  gbox->flags = gserialized1_get_lwflags(g);
324  if ( G1FLAGS_GET_Z(g->gflags) )
325  {
326  gbox->zmin = gbox->zmax = dptr[i++];
327  }
328  if ( G1FLAGS_GET_M(g->gflags) )
329  {
330  gbox->mmin = gbox->mmax = dptr[i++];
331  }
332  gbox_float_round(gbox);
333  return LW_SUCCESS;
334  }
335  /* We can calculate the box of a two-point cartesian line trivially */
336  else if ( type == LINETYPE )
337  {
338  int ndims = G1FLAGS_NDIMS(g->gflags);
339  int i = 0; /* Start at <linetype><npoints> */
340  double *dptr = (double*)(g->data);
341  int32_t *iptr = (int32_t *)(g->data);
342  int npoints = iptr[1]; /* Read the npoints */
343 
344  /* This only works with 2-point lines */
345  if ( npoints != 2 )
346  return LW_FAILURE;
347 
348  /* Advance to X */
349  /* Past <linetype><npoints> */
350  i++;
351  gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
352  gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
353 
354  /* Advance to Y */
355  i++;
356  gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
357  gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
358 
359  gbox->flags = gserialized1_get_lwflags(g);
360  if ( G1FLAGS_GET_Z(g->gflags) )
361  {
362  /* Advance to Z */
363  i++;
364  gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
365  gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
366  }
367  if ( G1FLAGS_GET_M(g->gflags) )
368  {
369  /* Advance to M */
370  i++;
371  gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
372  gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
373  }
374  gbox_float_round(gbox);
375  return LW_SUCCESS;
376  }
377  /* We can also do single-entry multi-points */
378  else if ( type == MULTIPOINTTYPE )
379  {
380  int i = 0; /* Start at <multipointtype><ngeoms> */
381  double *dptr = (double*)(g->data);
382  int32_t *iptr = (int32_t *)(g->data);
383  int ngeoms = iptr[1]; /* Read the ngeoms */
384  int npoints;
385 
386  /* This only works with single-entry multipoints */
387  if ( ngeoms != 1 )
388  return LW_FAILURE;
389 
390  /* Npoints is at <multipointtype><ngeoms><pointtype><npoints> */
391  npoints = iptr[3];
392 
393  /* The check below is necessary because we can have a MULTIPOINT
394  * that contains a single, empty POINT (ngeoms = 1, npoints = 0) */
395  if ( npoints != 1 )
396  return LW_FAILURE;
397 
398  /* Move forward two doubles (four ints) */
399  /* Past <multipointtype><ngeoms> */
400  /* Past <pointtype><npoints> */
401  i += 2;
402 
403  /* Read the doubles from the one point */
404  gbox->xmin = gbox->xmax = dptr[i++];
405  gbox->ymin = gbox->ymax = dptr[i++];
406  gbox->flags = gserialized1_get_lwflags(g);
407  if ( G1FLAGS_GET_Z(g->gflags) )
408  {
409  gbox->zmin = gbox->zmax = dptr[i++];
410  }
411  if ( G1FLAGS_GET_M(g->gflags) )
412  {
413  gbox->mmin = gbox->mmax = dptr[i++];
414  }
415  gbox_float_round(gbox);
416  return LW_SUCCESS;
417  }
418  /* And we can do single-entry multi-lines with two vertices (!!!) */
419  else if ( type == MULTILINETYPE )
420  {
421  int ndims = G1FLAGS_NDIMS(g->gflags);
422  int i = 0; /* Start at <multilinetype><ngeoms> */
423  double *dptr = (double*)(g->data);
424  int32_t *iptr = (int32_t *)(g->data);
425  int ngeoms = iptr[1]; /* Read the ngeoms */
426  int npoints;
427 
428  /* This only works with 1-line multilines */
429  if ( ngeoms != 1 )
430  return LW_FAILURE;
431 
432  /* Npoints is at <multilinetype><ngeoms><linetype><npoints> */
433  npoints = iptr[3];
434 
435  if ( npoints != 2 )
436  return LW_FAILURE;
437 
438  /* Advance to X */
439  /* Move forward two doubles (four ints) */
440  /* Past <multilinetype><ngeoms> */
441  /* Past <linetype><npoints> */
442  i += 2;
443  gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
444  gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
445 
446  /* Advance to Y */
447  i++;
448  gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
449  gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
450 
451  gbox->flags = gserialized1_get_lwflags(g);
452  if ( G1FLAGS_GET_Z(g->gflags) )
453  {
454  /* Advance to Z */
455  i++;
456  gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
457  gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
458  }
459  if ( G1FLAGS_GET_M(g->gflags) )
460  {
461  /* Advance to M */
462  i++;
463  gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
464  gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
465  }
466  gbox_float_round(gbox);
467  return LW_SUCCESS;
468  }
469 
470  return LW_FAILURE;
471 }
void gbox_float_round(GBOX *gbox)
Round given GBOX to float boundaries.
Definition: gbox.c:774
lwflags_t gserialized1_get_lwflags(const GSERIALIZED *g)
Read the flags from a GSERIALIZED and return a standard lwflag integer.
Definition: gserialized1.c:39
uint32_t gserialized1_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
Definition: gserialized1.c:131
#define G1FLAGS_GET_M(gflags)
Definition: gserialized1.h:17
#define G1FLAGS_NDIMS(gflags)
Definition: gserialized1.h:29
#define G1FLAGS_GET_BBOX(gflags)
Definition: gserialized1.h:18
#define G1FLAGS_GET_GEODETIC(gflags)
Definition: gserialized1.h:19
#define G1FLAGS_GET_Z(gflags)
Definition: gserialized1.h:16
#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)
type
Definition: ovdump.py:42
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 data[1]
Definition: liblwgeom.h:433
uint8_t gflags
Definition: liblwgeom.h:432

References GSERIALIZED::data, GBOX::flags, FP_MAX, FP_MIN, G1FLAGS_GET_BBOX, G1FLAGS_GET_GEODETIC, G1FLAGS_GET_M, G1FLAGS_GET_Z, G1FLAGS_NDIMS, gbox_float_round(), GSERIALIZED::gflags, gserialized1_get_lwflags(), gserialized1_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 gserialized1_fast_gbox_p(), gserialized1_get_gbox_p(), test_gserialized1_peek_gbox_p_fails_for_unsupported_cases(), test_gserialized1_peek_gbox_p_gets_correct_box(), and test_gserialized1_peek_gbox_p_no_box_when_empty().

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