PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ gserialized1_peek_gbox_p()

int gserialized1_peek_gbox_p ( const GSERIALIZED g,
GBOX gbox 
)

Definition at line 299 of file gserialized1.c.

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

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: