PostGIS  2.3.8dev-r@@SVN_REVISION@@
lwgeom_box3d.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * PostGIS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * PostGIS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  **********************************************************************
20  *
21  * ^copyright^
22  *
23  **********************************************************************/
24 
25 
26 #include "postgres.h"
27 #include "fmgr.h"
28 #include "utils/elog.h"
29 #include "utils/geo_decls.h"
30 
31 #include "../postgis_config.h"
32 #include "lwgeom_pg.h"
33 #include "liblwgeom.h"
34 
35 #include <math.h>
36 #include <float.h>
37 #include <string.h>
38 #include <stdio.h>
39 #include <errno.h>
40 
41 #define SHOW_DIGS_DOUBLE 15
42 #define MAX_DIGS_DOUBLE (SHOW_DIGS_DOUBLE + 6 + 1 + 3 +1)
43 
44 /* forward defs */
45 Datum BOX3D_in(PG_FUNCTION_ARGS);
46 Datum BOX3D_out(PG_FUNCTION_ARGS);
47 Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS);
48 Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS);
49 Datum BOX3D_expand(PG_FUNCTION_ARGS);
50 Datum BOX3D_to_BOX2D(PG_FUNCTION_ARGS);
51 Datum BOX3D_to_BOX(PG_FUNCTION_ARGS);
52 Datum BOX3D_xmin(PG_FUNCTION_ARGS);
53 Datum BOX3D_ymin(PG_FUNCTION_ARGS);
54 Datum BOX3D_zmin(PG_FUNCTION_ARGS);
55 Datum BOX3D_xmax(PG_FUNCTION_ARGS);
56 Datum BOX3D_ymax(PG_FUNCTION_ARGS);
57 Datum BOX3D_zmax(PG_FUNCTION_ARGS);
58 Datum BOX3D_combine(PG_FUNCTION_ARGS);
59 Datum BOX3D_combine_BOX3D(PG_FUNCTION_ARGS);
60 
72 Datum BOX3D_in(PG_FUNCTION_ARGS)
73 {
74  char *str = PG_GETARG_CSTRING(0);
75  int nitems;
76  BOX3D *box = (BOX3D *) palloc(sizeof(BOX3D));
77  box->zmin = 0;
78  box->zmax = 0;
79 
80 
81  /*printf( "box3d_in gets '%s'\n",str); */
82 
83  if (strstr(str,"BOX3D(") != str )
84  {
85  pfree(box);
86  elog(ERROR,"BOX3D parser - doesn't start with BOX3D(");
87  PG_RETURN_NULL();
88  }
89 
90  nitems = sscanf(str,"BOX3D(%le %le %le ,%le %le %le)",
91  &box->xmin, &box->ymin, &box->zmin,
92  &box->xmax, &box->ymax, &box->zmax);
93  if (nitems != 6 )
94  {
95  nitems = sscanf(str,"BOX3D(%le %le ,%le %le)",
96  &box->xmin, &box->ymin, &box->xmax, &box->ymax);
97  if (nitems != 4)
98  {
99  pfree(box);
100  elog(ERROR,"BOX3D parser - couldnt parse. It should look like: BOX3D(xmin ymin zmin,xmax ymax zmax) or BOX3D(xmin ymin,xmax ymax)");
101  PG_RETURN_NULL();
102  }
103  }
104 
105  if (box->xmin > box->xmax)
106  {
107  float tmp = box->xmin;
108  box->xmin = box->xmax;
109  box->xmax = tmp;
110  }
111  if (box->ymin > box->ymax)
112  {
113  float tmp = box->ymin;
114  box->ymin = box->ymax;
115  box->ymax = tmp;
116  }
117  if (box->zmin > box->zmax)
118  {
119  float tmp = box->zmin;
120  box->zmin = box->zmax;
121  box->zmax = tmp;
122  }
123  box->srid = SRID_UNKNOWN;
124  PG_RETURN_POINTER(box);
125 }
126 
127 
135 Datum BOX3D_out(PG_FUNCTION_ARGS)
136 {
137  BOX3D *bbox = (BOX3D *) PG_GETARG_POINTER(0);
138  int size;
139  char *result;
140 
141  if (bbox == NULL)
142  {
143  result = palloc(5);
144  strcat(result,"NULL");
145  PG_RETURN_CSTRING(result);
146  }
147 
148 
149  /*double digits+ "BOX3D"+ "()" + commas +null */
150  size = MAX_DIGS_DOUBLE*6+5+2+4+5+1;
151 
152  result = (char *) palloc(size);
153 
154  sprintf(result, "BOX3D(%.15g %.15g %.15g,%.15g %.15g %.15g)",
155  bbox->xmin, bbox->ymin, bbox->zmin,
156  bbox->xmax,bbox->ymax,bbox->zmax);
157 
158  PG_RETURN_CSTRING(result);
159 }
160 
161 
163 Datum BOX3D_to_BOX2D(PG_FUNCTION_ARGS)
164 {
165  BOX3D *in = (BOX3D *)PG_GETARG_POINTER(0);
166  GBOX *out = box3d_to_gbox(in);
167  PG_RETURN_POINTER(out);
168 }
169 
170 static void
171 box3d_to_box_p(BOX3D *box, BOX *out)
172 {
173 #if PARANOIA_LEVEL > 0
174  if (box == NULL) return;
175 #endif
176 
177  out->low.x = box->xmin;
178  out->low.y = box->ymin;
179 
180  out->high.x = box->xmax;
181  out->high.y = box->ymax;
182 }
183 
185 Datum BOX3D_to_BOX(PG_FUNCTION_ARGS)
186 {
187  BOX3D *in = (BOX3D *)PG_GETARG_POINTER(0);
188  BOX *box = palloc(sizeof(BOX));
189 
190  box3d_to_box_p(in, box);
191  PG_RETURN_POINTER(box);
192 }
193 
194 
196 Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS)
197 {
198  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
199  POINTARRAY *pa;
200  GSERIALIZED *result;
201  POINT4D pt;
202 
217 
218  /* BOX3D is a point */
219  if ( (box->xmin == box->xmax) && (box->ymin == box->ymax) &&
220  (box->zmin == box->zmax) )
221  {
222  LWPOINT *lwpt = lwpoint_construct(SRID_UNKNOWN, NULL, pa);
223 
224  pt.x = box->xmin;
225  pt.y = box->ymin;
226  pt.z = box->zmin;
227  ptarray_append_point(pa, &pt, LW_TRUE);
228 
229  result = geometry_serialize(lwpoint_as_lwgeom(lwpt));
230  lwpoint_free(lwpt);
231  }
232  /* BOX3D is a line */
233  else if (((box->xmin == box->xmax ||
234  box->ymin == box->ymax) &&
235  box->zmin == box->zmax) ||
236  ((box->xmin == box->xmax ||
237  box->zmin == box->zmax) &&
238  box->ymin == box->ymax) ||
239  ((box->ymin == box->ymax ||
240  box->zmin == box->zmax) &&
241  box->xmin == box->xmax))
242  {
243  LWLINE *lwline = lwline_construct(SRID_UNKNOWN, NULL, pa);
244 
245  pt.x = box->xmin;
246  pt.y = box->ymin;
247  pt.z = box->zmin;
248  ptarray_append_point(pa, &pt, LW_TRUE);
249  pt.x = box->xmax;
250  pt.y = box->ymax;
251  pt.z = box->zmax;
252  ptarray_append_point(pa, &pt, LW_TRUE);
253 
254  result = geometry_serialize(lwline_as_lwgeom(lwline));
255  lwline_free(lwline);
256  }
257  /* BOX3D is a polygon in the X plane */
258  else if (box->xmin == box->xmax)
259  {
260  POINT4D points[4];
261  LWPOLY *lwpoly;
262 
263  /* Initialize the 4 vertices of the polygon */
264  points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin };
265  points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin };
266  points[2] = (POINT4D) { box->xmin, box->ymax, box->zmax };
267  points[3] = (POINT4D) { box->xmin, box->ymin, box->zmax };
268 
270  &points[0], &points[1], &points[2], &points[3]);
271  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
272  lwpoly_free(lwpoly);
273  }
274  /* BOX3D is a polygon in the Y plane */
275  else if (box->ymin == box->ymax)
276  {
277  POINT4D points[4];
278  LWPOLY *lwpoly;
279 
280  /* Initialize the 4 vertices of the polygon */
281  points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin };
282  points[1] = (POINT4D) { box->xmax, box->ymin, box->zmin };
283  points[2] = (POINT4D) { box->xmax, box->ymin, box->zmax };
284  points[3] = (POINT4D) { box->xmin, box->ymin, box->zmax };
285 
287  &points[0], &points[1], &points[2], &points[3]);
288  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
289  lwpoly_free(lwpoly);
290  }
291  /* BOX3D is a polygon in the Z plane */
292  else if (box->zmin == box->zmax)
293  {
294  POINT4D points[4];
295  LWPOLY *lwpoly;
296 
297  /* Initialize the 4 vertices of the polygon */
298  points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin };
299  points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin };
300  points[2] = (POINT4D) { box->xmax, box->ymax, box->zmin };
301  points[3] = (POINT4D) { box->xmax, box->ymin, box->zmin };
302 
304  &points[0], &points[1], &points[2], &points[3]);
305  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
306  lwpoly_free(lwpoly);
307  }
308  /* BOX3D is a polyhedron */
309  else
310  {
311  POINT4D points[8];
312  static const int ngeoms = 6;
313  LWGEOM **geoms = (LWGEOM **) lwalloc(sizeof(LWGEOM *) * ngeoms);
314  LWGEOM *geom = NULL;
315 
316  /* Initialize the 8 vertices of the box */
317  points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin };
318  points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin };
319  points[2] = (POINT4D) { box->xmax, box->ymax, box->zmin };
320  points[3] = (POINT4D) { box->xmax, box->ymin, box->zmin };
321  points[4] = (POINT4D) { box->xmin, box->ymin, box->zmax };
322  points[5] = (POINT4D) { box->xmin, box->ymax, box->zmax };
323  points[6] = (POINT4D) { box->xmax, box->ymax, box->zmax };
324  points[7] = (POINT4D) { box->xmax, box->ymin, box->zmax };
325 
326  /* add bottom polygon */
328  &points[0], &points[1], &points[2], &points[3]));
329  /* add top polygon */
331  &points[4], &points[7], &points[6], &points[5]));
332  /* add left polygon */
334  &points[0], &points[4], &points[5], &points[1]));
335  /* add right polygon */
337  &points[3], &points[2], &points[6], &points[7]));
338  /* add back polygon */
340  &points[0], &points[3], &points[7], &points[4]));
341  /* add front polygon */
343  &points[1], &points[5], &points[6], &points[2]));
344 
346  SRID_UNKNOWN, NULL, ngeoms, geoms);
347 
348  FLAGS_SET_SOLID(geom->flags, 1);
349 
350  result = geometry_serialize(geom);
352  }
353 
354  gserialized_set_srid(result, box->srid);
355 
356  PG_RETURN_POINTER(result);
357 }
358 
360 void
361 expand_box3d(BOX3D *box, double d)
362 {
363  box->xmin -= d;
364  box->ymin -= d;
365  box->zmin -= d;
366 
367  box->xmax += d;
368  box->ymax += d;
369  box->zmax += d;
370 }
371 
372 static void
373 expand_box3d_xyz(BOX3D *box, double dx, double dy, double dz)
374 {
375  box->xmin -= dx;
376  box->xmax += dx;
377  box->ymin -= dy;
378  box->ymax += dy;
379  box->zmin -= dz;
380  box->zmax += dz;
381 }
382 
384 Datum BOX3D_expand(PG_FUNCTION_ARGS)
385 {
386  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
387  BOX3D *result = (BOX3D *)palloc(sizeof(BOX3D));
388  memcpy(result, box, sizeof(BOX3D));
389 
390  if (PG_NARGS() == 2) {
391  /* Expand the box the same amount in all directions */
392  double d = PG_GETARG_FLOAT8(1);
393  expand_box3d(result, d);
394  }
395  else
396  {
397  double dx = PG_GETARG_FLOAT8(1);
398  double dy = PG_GETARG_FLOAT8(2);
399  double dz = PG_GETARG_FLOAT8(3);
400 
401  expand_box3d_xyz(result, dx, dy, dz);
402  }
403 
404  PG_RETURN_POINTER(result);
405 }
406 
415 Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS)
416 {
417  GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
418  LWGEOM *lwgeom = lwgeom_from_gserialized(geom);
419  GBOX gbox;
420  BOX3D *result;
421  int rv = lwgeom_calculate_gbox(lwgeom, &gbox);
422 
423  if ( rv == LW_FAILURE )
424  PG_RETURN_NULL();
425 
426  result = box3d_from_gbox(&gbox);
427  result->srid = lwgeom->srid;
428 
429  lwgeom_free(lwgeom);
430  PG_RETURN_POINTER(result);
431 }
432 
434 Datum BOX3D_xmin(PG_FUNCTION_ARGS)
435 {
436  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
437  PG_RETURN_FLOAT8(Min(box->xmin, box->xmax));
438 }
439 
441 Datum BOX3D_ymin(PG_FUNCTION_ARGS)
442 {
443  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
444  PG_RETURN_FLOAT8(Min(box->ymin, box->ymax));
445 }
446 
448 Datum BOX3D_zmin(PG_FUNCTION_ARGS)
449 {
450  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
451  PG_RETURN_FLOAT8(Min(box->zmin, box->zmax));
452 }
453 
455 Datum BOX3D_xmax(PG_FUNCTION_ARGS)
456 {
457  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
458  PG_RETURN_FLOAT8(Max(box->xmin, box->xmax));
459 }
460 
462 Datum BOX3D_ymax(PG_FUNCTION_ARGS)
463 {
464  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
465  PG_RETURN_FLOAT8(Max(box->ymin, box->ymax));
466 }
467 
469 Datum BOX3D_zmax(PG_FUNCTION_ARGS)
470 {
471  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
472  PG_RETURN_FLOAT8(Max(box->zmin, box->zmax));
473 }
474 
481 Datum BOX3D_combine(PG_FUNCTION_ARGS)
482 {
483  BOX3D *box = (BOX3D*)PG_GETARG_POINTER(0);
484  GSERIALIZED *geom = PG_ARGISNULL(1) ? NULL : (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_POINTER(1));
485  LWGEOM *lwgeom = NULL;
486  BOX3D *result = NULL;
487  GBOX gbox;
488  int32_t srid;
489  int rv;
490 
491  /* Can't do anything with null inputs */
492  if ( (box == NULL) && (geom == NULL) )
493  PG_RETURN_NULL();
494 
495  /* Null geometry but non-null box, return the box */
496  if (geom == NULL)
497  {
498  result = palloc(sizeof(BOX3D));
499  memcpy(result, box, sizeof(BOX3D));
500  PG_RETURN_POINTER(result);
501  }
502 
503  /* Deserialize geometry and *calculate* the box */
504  /* We can't use the cached box because it's float, we *must* calculate */
505  lwgeom = lwgeom_from_gserialized(geom);
506  srid = lwgeom->srid;
507  rv = lwgeom_calculate_gbox(lwgeom, &gbox);
508  lwgeom_free(lwgeom);
509 
510  /* If we couldn't calculate the box, return what we know */
511  if ( rv == LW_FAILURE )
512  {
513  PG_FREE_IF_COPY(geom, 1);
514  /* No geom box, no input box, so null return */
515  if ( box == NULL )
516  PG_RETURN_NULL();
517  result = palloc(sizeof(BOX3D));
518  memcpy(result, box, sizeof(BOX3D));
519  PG_RETURN_POINTER(result);
520  }
521 
522  /* Null box and non-null geometry, just return the geometry box */
523  if ( box == NULL )
524  {
525  PG_FREE_IF_COPY(geom, 1);
526  result = box3d_from_gbox(&gbox);
527  result->srid = srid;
528  PG_RETURN_POINTER(result);
529  }
530 
531  result = palloc(sizeof(BOX3D));
532  result->xmax = Max(box->xmax, gbox.xmax);
533  result->ymax = Max(box->ymax, gbox.ymax);
534  result->zmax = Max(box->zmax, gbox.zmax);
535  result->xmin = Min(box->xmin, gbox.xmin);
536  result->ymin = Min(box->ymin, gbox.ymin);
537  result->zmin = Min(box->zmin, gbox.zmin);
538  result->srid = srid;
539 
540  PG_FREE_IF_COPY(geom, 1);
541  PG_RETURN_POINTER(result);
542 }
543 
545 Datum BOX3D_combine_BOX3D(PG_FUNCTION_ARGS)
546 {
547  BOX3D *box0 = (BOX3D*)(PG_ARGISNULL(0) ? NULL : PG_GETARG_POINTER(0));
548  BOX3D *box1 = (BOX3D*)(PG_ARGISNULL(1) ? NULL : PG_GETARG_POINTER(1));
549  BOX3D *result;
550 
551  if (box0 && !box1)
552  PG_RETURN_POINTER(box0);
553 
554  if (box1 && !box0)
555  PG_RETURN_POINTER(box1);
556 
557  if (!box1 && !box0)
558  PG_RETURN_NULL();
559 
560  result = palloc(sizeof(BOX3D));
561  result->xmax = Max(box0->xmax, box1->xmax);
562  result->ymax = Max(box0->ymax, box1->ymax);
563  result->zmax = Max(box0->zmax, box1->zmax);
564  result->xmin = Min(box0->xmin, box1->xmin);
565  result->ymin = Min(box0->ymin, box1->ymin);
566  result->zmin = Min(box0->zmin, box1->zmin);
567  result->srid = box0->srid;
568 
569  PG_RETURN_POINTER(result);
570 }
571 
573 Datum BOX3D_construct(PG_FUNCTION_ARGS)
574 {
575  GSERIALIZED *min = PG_GETARG_GSERIALIZED_P(0);
576  GSERIALIZED *max = PG_GETARG_GSERIALIZED_P(1);
577  BOX3D *result = palloc(sizeof(BOX3D));
578  LWGEOM *minpoint, *maxpoint;
579  POINT3DZ minp, maxp;
580 
581  minpoint = lwgeom_from_gserialized(min);
582  maxpoint = lwgeom_from_gserialized(max);
583 
584  if ( minpoint->type != POINTTYPE ||
585  maxpoint->type != POINTTYPE )
586  {
587  elog(ERROR, "BOX3D_construct: args must be points");
588  PG_RETURN_NULL();
589  }
590 
591  error_if_srid_mismatch(minpoint->srid, maxpoint->srid);
592 
593  getPoint3dz_p(((LWPOINT *)minpoint)->point, 0, &minp);
594  getPoint3dz_p(((LWPOINT *)maxpoint)->point, 0, &maxp);
595 
596  result->xmax = maxp.x;
597  result->ymax = maxp.y;
598  result->zmax = maxp.z;
599 
600  result->xmin = minp.x;
601  result->ymin = minp.y;
602  result->zmin = minp.z;
603 
604  result->srid = minpoint->srid;
605 
606  PG_RETURN_POINTER(result);
607 }
double x
Definition: liblwgeom.h:351
int32_t srid
Definition: liblwgeom.h:278
#define FLAGS_SET_SOLID(flags, value)
Definition: liblwgeom.h:150
double z
Definition: liblwgeom.h:333
double y
Definition: liblwgeom.h:333
Datum BOX3D_ymax(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:462
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:43
double x
Definition: liblwgeom.h:333
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
uint8_t flags
Definition: liblwgeom.h:396
double xmax
Definition: liblwgeom.h:292
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:70
void lwpoint_free(LWPOINT *pt)
Definition: lwpoint.c:195
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1063
void lwline_free(LWLINE *line)
Definition: lwline.c:76
void gserialized_set_srid(GSERIALIZED *s, int32_t srid)
Write the SRID into the serialized form (it is packed into three bytes so this is a handy function)...
Definition: g_serialized.c:100
Datum BOX3D_in(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:72
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:96
Datum BOX3D_combine(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:481
double ymin
Definition: liblwgeom.h:276
void error_if_srid_mismatch(int srid1, int srid2)
Definition: lwutil.c:369
int32_t srid
Definition: liblwgeom.h:398
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:252
Datum BOX3D_out(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:135
Datum BOX3D_construct(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:573
#define LW_FAILURE
Definition: liblwgeom.h:78
static void expand_box3d_xyz(BOX3D *box, double dx, double dy, double dz)
Definition: lwgeom_box3d.c:373
Datum BOX3D_zmax(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:469
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
Definition: lwgeom.c:665
double ymin
Definition: liblwgeom.h:293
double zmax
Definition: liblwgeom.h:296
int getPoint3dz_p(const POINTARRAY *pa, int n, POINT3DZ *point)
Definition: lwgeom_api.c:332
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:262
double xmin
Definition: liblwgeom.h:291
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_FALSE, then a duplicate point will not be added.
Definition: ptarray.c:156
#define LW_FALSE
Definition: liblwgeom.h:76
double xmin
Definition: liblwgeom.h:276
Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:196
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:152
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
Datum BOX3D_xmin(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:434
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:187
void expand_box3d(BOX3D *box, double d)
Expand given box of &#39;d&#39; units in all directions.
Definition: lwgeom_box3d.c:361
double ymax
Definition: liblwgeom.h:294
Datum BOX3D_to_BOX2D(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:163
double z
Definition: liblwgeom.h:351
int32_t srid
Definition: liblwgeom.h:409
#define MAX_DIGS_DOUBLE
Definition: lwgeom_box3d.c:42
PG_FUNCTION_INFO_V1(BOX3D_in)
BOX3D_in - takes a string rep of BOX3D and returns internal rep.
Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:415
GBOX * box3d_to_gbox(const BOX3D *b3d)
Definition: g_box.c:91
BOX3D * box3d_from_gbox(const GBOX *gbox)
Definition: g_box.c:64
Datum BOX3D_ymin(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:441
double xmax
Definition: liblwgeom.h:277
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
double zmin
Definition: liblwgeom.h:295
static void box3d_to_box_p(BOX3D *box, BOX *out)
Definition: lwgeom_box3d.c:171
Datum BOX3D_xmax(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:455
Datum BOX3D_expand(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:384
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
Datum BOX3D_combine_BOX3D(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:545
uint8_t type
Definition: liblwgeom.h:395
Datum BOX3D_zmin(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:448
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:339
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:267
LWPOINT * lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:111
void * lwalloc(size_t size)
Definition: lwutil.c:227
double y
Definition: liblwgeom.h:351
double ymax
Definition: liblwgeom.h:277
Datum BOX3D_to_BOX(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:185
LWPOLY * lwpoly_construct_rectangle(char hasz, char hasm, POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D *p4)
Definition: lwpoly.c:80
This library is the generic geometry handling section of PostGIS.
double zmax
Definition: liblwgeom.h:277
double zmin
Definition: liblwgeom.h:276