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

◆ 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++];
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
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++];
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
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.
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: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)
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, 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: