PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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++];
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
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++];
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
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:786
lwflags_t gserialized1_get_lwflags(const GSERIALIZED *g)
Read the flags from a GSERIALIZED and return a standard lwflag integer.
uint32_t gserialized1_get_type(const GSERIALIZED *g)
Extract the geometry type from the serialized form (it hides in the anonymous data area,...
#define G1FLAGS_GET_M(gflags)
#define G1FLAGS_NDIMS(gflags)
#define G1FLAGS_GET_BBOX(gflags)
#define G1FLAGS_GET_GEODETIC(gflags)
#define G1FLAGS_GET_Z(gflags)
#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)
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, 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: