PostGIS  2.2.7dev-r@@SVN_REVISION@@
static int gserialized_peek_gbox_p ( const GSERIALIZED g,
GBOX gbox 
)
static

Definition at line 205 of file g_serialized.c.

References GSERIALIZED::data, 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, GBOX::xmax, GBOX::xmin, GBOX::ymax, GBOX::ymin, GBOX::zmax, and GBOX::zmin.

Referenced by gserialized_get_gbox_p().

206 {
207  uint32_t type = gserialized_get_type(g);
208 
209  /* Peeking doesn't help if you already have a box or are geodetic */
210  if ( FLAGS_GET_GEODETIC(g->flags) || FLAGS_GET_BBOX(g->flags) )
211  {
212  return LW_FAILURE;
213  }
214 
215  /* Boxes of points are easy peasy */
216  if ( type == POINTTYPE )
217  {
218  int i = 1; /* Start past <pointtype><padding> */
219  double *dptr = (double*)(g->data);
220 
221  /* Read the empty flag */
222  int *iptr = (int*)(g->data);
223  int isempty = (iptr[1] == 0);
224 
225  /* EMPTY point has no box */
226  if ( isempty ) return LW_FAILURE;
227 
228  gbox->xmin = gbox->xmax = dptr[i++];
229  gbox->ymin = gbox->ymax = dptr[i++];
230  if ( FLAGS_GET_Z(g->flags) )
231  {
232  gbox->zmin = gbox->zmax = dptr[i++];
233  }
234  if ( FLAGS_GET_M(g->flags) )
235  {
236  gbox->mmin = gbox->mmax = dptr[i++];
237  }
238  gbox_float_round(gbox);
239  return LW_SUCCESS;
240  }
241  /* We can calculate the box of a two-point cartesian line trivially */
242  else if ( type == LINETYPE )
243  {
244  int ndims = FLAGS_NDIMS(g->flags);
245  int i = 0; /* Start at <linetype><npoints> */
246  double *dptr = (double*)(g->data);
247  int *iptr = (int*)(g->data);
248  int npoints = iptr[1]; /* Read the npoints */
249 
250  /* This only works with 2-point lines */
251  if ( npoints != 2 )
252  return LW_FAILURE;
253 
254  /* Advance to X */
255  /* Past <linetype><npoints> */
256  i++;
257  gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
258  gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
259 
260  /* Advance to Y */
261  i++;
262  gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
263  gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
264 
265  if ( FLAGS_GET_Z(g->flags) )
266  {
267  /* Advance to Z */
268  i++;
269  gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
270  gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
271  }
272  if ( FLAGS_GET_M(g->flags) )
273  {
274  /* Advance to M */
275  i++;
276  gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
277  gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
278  }
279  gbox_float_round(gbox);
280  return LW_SUCCESS;
281  }
282  /* We can also do single-entry multi-points */
283  else if ( type == MULTIPOINTTYPE )
284  {
285  int i = 0; /* Start at <multipointtype><ngeoms> */
286  double *dptr = (double*)(g->data);
287  int *iptr = (int*)(g->data);
288  int ngeoms = iptr[1]; /* Read the ngeoms */
289 
290  /* This only works with single-entry multipoints */
291  if ( ngeoms != 1 )
292  return LW_FAILURE;
293 
294  /* Move forward two doubles (four ints) */
295  /* Past <multipointtype><ngeoms> */
296  /* Past <pointtype><emtpyflat> */
297  i += 2;
298 
299  /* Read the doubles from the one point */
300  gbox->xmin = gbox->xmax = dptr[i++];
301  gbox->ymin = gbox->ymax = dptr[i++];
302  if ( FLAGS_GET_Z(g->flags) )
303  {
304  gbox->zmin = gbox->zmax = dptr[i++];
305  }
306  if ( FLAGS_GET_M(g->flags) )
307  {
308  gbox->mmin = gbox->mmax = dptr[i++];
309  }
310  gbox_float_round(gbox);
311  return LW_SUCCESS;
312  }
313  /* And we can do single-entry multi-lines with two vertices (!!!) */
314  else if ( type == MULTILINETYPE )
315  {
316  int ndims = FLAGS_NDIMS(g->flags);
317  int i = 0; /* Start at <multilinetype><ngeoms> */
318  double *dptr = (double*)(g->data);
319  int *iptr = (int*)(g->data);
320  int ngeoms = iptr[1]; /* Read the ngeoms */
321  int npoints;
322 
323  /* This only works with 1-line multilines */
324  if ( ngeoms != 1 )
325  return LW_FAILURE;
326 
327  /* Npoints is at <multilinetype><ngeoms><linetype><npoints> */
328  npoints = iptr[3];
329 
330  if ( npoints != 2 )
331  return LW_FAILURE;
332 
333  /* Advance to X */
334  /* Move forward two doubles (four ints) */
335  /* Past <multilinetype><ngeoms> */
336  /* Past <linetype><npoints> */
337  i += 2;
338  gbox->xmin = FP_MIN(dptr[i], dptr[i+ndims]);
339  gbox->xmax = FP_MAX(dptr[i], dptr[i+ndims]);
340 
341  /* Advance to Y */
342  i++;
343  gbox->ymin = FP_MIN(dptr[i], dptr[i+ndims]);
344  gbox->ymax = FP_MAX(dptr[i], dptr[i+ndims]);
345 
346  if ( FLAGS_GET_Z(g->flags) )
347  {
348  /* Advance to Z */
349  i++;
350  gbox->zmin = FP_MIN(dptr[i], dptr[i+ndims]);
351  gbox->zmax = FP_MAX(dptr[i], dptr[i+ndims]);
352  }
353  if ( FLAGS_GET_M(g->flags) )
354  {
355  /* Advance to M */
356  i++;
357  gbox->mmin = FP_MIN(dptr[i], dptr[i+ndims]);
358  gbox->mmax = FP_MAX(dptr[i], dptr[i+ndims]);
359  }
360  gbox_float_round(gbox);
361  return LW_SUCCESS;
362  }
363 
364  return LW_FAILURE;
365 }
#define LINETYPE
Definition: liblwgeom.h:71
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:55
uint8_t data[1]
Definition: liblwgeom.h:368
#define FLAGS_GET_GEODETIC(flags)
Definition: liblwgeom.h:127
double xmax
Definition: liblwgeom.h:277
#define MULTIPOINTTYPE
Definition: liblwgeom.h:73
#define LW_SUCCESS
Definition: liblwgeom.h:65
#define FP_MIN(A, B)
#define LW_FAILURE
Definition: liblwgeom.h:64
void gbox_float_round(GBOX *gbox)
Round given GBOX to float boundaries.
Definition: g_box.c:682
double zmax
Definition: liblwgeom.h:281
double ymin
Definition: liblwgeom.h:278
double xmin
Definition: liblwgeom.h:276
#define FLAGS_GET_BBOX(flags)
Definition: liblwgeom.h:126
double ymax
Definition: liblwgeom.h:279
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:124
double mmin
Definition: liblwgeom.h:282
double zmin
Definition: liblwgeom.h:280
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:70
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:125
double mmax
Definition: liblwgeom.h:283
#define MULTILINETYPE
Definition: liblwgeom.h:74
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:136
uint8_t flags
Definition: liblwgeom.h:367
#define FP_MAX(A, B)

Here is the call graph for this function:

Here is the caller graph for this function: