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

Definition at line 206 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().

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

Here is the call graph for this function:

Here is the caller graph for this function: