PostGIS  2.5.0dev-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 ( ! box ) return;
174 
175  out->low.x = box->xmin;
176  out->low.y = box->ymin;
177 
178  out->high.x = box->xmax;
179  out->high.y = box->ymax;
180 }
181 
183 Datum BOX3D_to_BOX(PG_FUNCTION_ARGS)
184 {
185  BOX3D *in = (BOX3D *)PG_GETARG_POINTER(0);
186  BOX *box = palloc(sizeof(BOX));
187 
188  box3d_to_box_p(in, box);
189  PG_RETURN_POINTER(box);
190 }
191 
192 
194 Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS)
195 {
196  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
197  POINTARRAY *pa;
198  GSERIALIZED *result;
199  POINT4D pt;
200 
215 
216  /* BOX3D is a point */
217  if ( (box->xmin == box->xmax) && (box->ymin == box->ymax) &&
218  (box->zmin == box->zmax) )
219  {
220  LWPOINT *lwpt = lwpoint_construct(SRID_UNKNOWN, NULL, pa);
221 
222  pt.x = box->xmin;
223  pt.y = box->ymin;
224  pt.z = box->zmin;
225  ptarray_append_point(pa, &pt, LW_TRUE);
226 
227  result = geometry_serialize(lwpoint_as_lwgeom(lwpt));
228  lwpoint_free(lwpt);
229  }
230  /* BOX3D is a line */
231  else if (((box->xmin == box->xmax ||
232  box->ymin == box->ymax) &&
233  box->zmin == box->zmax) ||
234  ((box->xmin == box->xmax ||
235  box->zmin == box->zmax) &&
236  box->ymin == box->ymax) ||
237  ((box->ymin == box->ymax ||
238  box->zmin == box->zmax) &&
239  box->xmin == box->xmax))
240  {
241  LWLINE *lwline = lwline_construct(SRID_UNKNOWN, NULL, pa);
242 
243  pt.x = box->xmin;
244  pt.y = box->ymin;
245  pt.z = box->zmin;
246  ptarray_append_point(pa, &pt, LW_TRUE);
247  pt.x = box->xmax;
248  pt.y = box->ymax;
249  pt.z = box->zmax;
250  ptarray_append_point(pa, &pt, LW_TRUE);
251 
252  result = geometry_serialize(lwline_as_lwgeom(lwline));
253  lwline_free(lwline);
254  }
255  /* BOX3D is a polygon in the X plane */
256  else if (box->xmin == box->xmax)
257  {
258  POINT4D points[4];
259  LWPOLY *lwpoly;
260 
261  /* Initialize the 4 vertices of the polygon */
262  points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin, 0.0 };
263  points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin, 0.0 };
264  points[2] = (POINT4D) { box->xmin, box->ymax, box->zmax, 0.0 };
265  points[3] = (POINT4D) { box->xmin, box->ymin, box->zmax, 0.0 };
266 
268  &points[0], &points[1], &points[2], &points[3]);
269  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
270  lwpoly_free(lwpoly);
271  }
272  /* BOX3D is a polygon in the Y plane */
273  else if (box->ymin == box->ymax)
274  {
275  POINT4D points[4];
276  LWPOLY *lwpoly;
277 
278  /* Initialize the 4 vertices of the polygon */
279  points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin, 0.0 };
280  points[1] = (POINT4D) { box->xmax, box->ymin, box->zmin, 0.0 };
281  points[2] = (POINT4D) { box->xmax, box->ymin, box->zmax, 0.0 };
282  points[3] = (POINT4D) { box->xmin, box->ymin, box->zmax, 0.0 };
283 
285  &points[0], &points[1], &points[2], &points[3]);
286  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
287  lwpoly_free(lwpoly);
288  }
289  /* BOX3D is a polygon in the Z plane */
290  else if (box->zmin == box->zmax)
291  {
292  POINT4D points[4];
293  LWPOLY *lwpoly;
294 
295  /* Initialize the 4 vertices of the polygon */
296  points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin, 0.0 };
297  points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin, 0.0 };
298  points[2] = (POINT4D) { box->xmax, box->ymax, box->zmin, 0.0 };
299  points[3] = (POINT4D) { box->xmax, box->ymin, box->zmin, 0.0 };
300 
302  &points[0], &points[1], &points[2], &points[3]);
303  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
304  lwpoly_free(lwpoly);
305  }
306  /* BOX3D is a polyhedron */
307  else
308  {
309  POINT4D points[8];
310  static const int ngeoms = 6;
311  LWGEOM **geoms = (LWGEOM **) lwalloc(sizeof(LWGEOM *) * ngeoms);
312  LWGEOM *geom = NULL;
313 
314  /* Initialize the 8 vertices of the box */
315  points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin, 0.0 };
316  points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin, 0.0 };
317  points[2] = (POINT4D) { box->xmax, box->ymax, box->zmin, 0.0 };
318  points[3] = (POINT4D) { box->xmax, box->ymin, box->zmin, 0.0 };
319  points[4] = (POINT4D) { box->xmin, box->ymin, box->zmax, 0.0 };
320  points[5] = (POINT4D) { box->xmin, box->ymax, box->zmax, 0.0 };
321  points[6] = (POINT4D) { box->xmax, box->ymax, box->zmax, 0.0 };
322  points[7] = (POINT4D) { box->xmax, box->ymin, box->zmax, 0.0 };
323 
324  /* add bottom polygon */
326  &points[0], &points[1], &points[2], &points[3]));
327  /* add top polygon */
329  &points[4], &points[5], &points[6], &points[7]));
330  /* add left polygon */
332  &points[0], &points[1], &points[5], &points[4]));
333  /* add right polygon */
335  &points[3], &points[2], &points[6], &points[7]));
336  /* add back polygon */
338  &points[0], &points[3], &points[7], &points[4]));
339  /* add front polygon */
341  &points[1], &points[2], &points[6], &points[5]));
342 
344  SRID_UNKNOWN, NULL, ngeoms, geoms);
345 
346  FLAGS_SET_SOLID(geom->flags, 1);
347 
348  result = geometry_serialize(geom);
350  }
351 
352  gserialized_set_srid(result, box->srid);
353 
354  PG_RETURN_POINTER(result);
355 }
356 
358 void
359 expand_box3d(BOX3D *box, double d)
360 {
361  box->xmin -= d;
362  box->ymin -= d;
363  box->zmin -= d;
364 
365  box->xmax += d;
366  box->ymax += d;
367  box->zmax += d;
368 }
369 
370 static void
371 expand_box3d_xyz(BOX3D *box, double dx, double dy, double dz)
372 {
373  box->xmin -= dx;
374  box->xmax += dx;
375  box->ymin -= dy;
376  box->ymax += dy;
377  box->zmin -= dz;
378  box->zmax += dz;
379 }
380 
382 Datum BOX3D_expand(PG_FUNCTION_ARGS)
383 {
384  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
385  BOX3D *result = (BOX3D *)palloc(sizeof(BOX3D));
386  memcpy(result, box, sizeof(BOX3D));
387 
388  if (PG_NARGS() == 2) {
389  /* Expand the box the same amount in all directions */
390  double d = PG_GETARG_FLOAT8(1);
391  expand_box3d(result, d);
392  }
393  else
394  {
395  double dx = PG_GETARG_FLOAT8(1);
396  double dy = PG_GETARG_FLOAT8(2);
397  double dz = PG_GETARG_FLOAT8(3);
398 
399  expand_box3d_xyz(result, dx, dy, dz);
400  }
401 
402  PG_RETURN_POINTER(result);
403 }
404 
413 Datum LWGEOM_to_BOX3D(PG_FUNCTION_ARGS)
414 {
415  GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
416  LWGEOM *lwgeom = lwgeom_from_gserialized(geom);
417  GBOX gbox;
418  BOX3D *result;
419  int rv = lwgeom_calculate_gbox(lwgeom, &gbox);
420 
421  if ( rv == LW_FAILURE )
422  PG_RETURN_NULL();
423 
424  result = box3d_from_gbox(&gbox);
425  result->srid = lwgeom->srid;
426 
427  lwgeom_free(lwgeom);
428  PG_RETURN_POINTER(result);
429 }
430 
432 Datum BOX3D_xmin(PG_FUNCTION_ARGS)
433 {
434  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
435  PG_RETURN_FLOAT8(Min(box->xmin, box->xmax));
436 }
437 
439 Datum BOX3D_ymin(PG_FUNCTION_ARGS)
440 {
441  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
442  PG_RETURN_FLOAT8(Min(box->ymin, box->ymax));
443 }
444 
446 Datum BOX3D_zmin(PG_FUNCTION_ARGS)
447 {
448  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
449  PG_RETURN_FLOAT8(Min(box->zmin, box->zmax));
450 }
451 
453 Datum BOX3D_xmax(PG_FUNCTION_ARGS)
454 {
455  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
456  PG_RETURN_FLOAT8(Max(box->xmin, box->xmax));
457 }
458 
460 Datum BOX3D_ymax(PG_FUNCTION_ARGS)
461 {
462  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
463  PG_RETURN_FLOAT8(Max(box->ymin, box->ymax));
464 }
465 
467 Datum BOX3D_zmax(PG_FUNCTION_ARGS)
468 {
469  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
470  PG_RETURN_FLOAT8(Max(box->zmin, box->zmax));
471 }
472 
479 Datum BOX3D_combine(PG_FUNCTION_ARGS)
480 {
481  BOX3D *box = (BOX3D*)PG_GETARG_POINTER(0);
482  GSERIALIZED *geom = PG_ARGISNULL(1) ? NULL : (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_POINTER(1));
483  LWGEOM *lwgeom = NULL;
484  BOX3D *result = NULL;
485  GBOX gbox;
486  int32_t srid;
487  int rv;
488 
489  /* Can't do anything with null inputs */
490  if ((box == NULL) && (geom == NULL)) { PG_RETURN_NULL(); }
491  /* Null geometry but non-null box, return the box */
492  else if (geom == NULL)
493  {
494  result = palloc(sizeof(BOX3D));
495  memcpy(result, box, sizeof(BOX3D));
496  PG_RETURN_POINTER(result);
497  }
498 
499  /* Deserialize geometry and *calculate* the box */
500  /* We can't use the cached box because it's float, we *must* calculate */
501  lwgeom = lwgeom_from_gserialized(geom);
502  srid = lwgeom->srid;
503  rv = lwgeom_calculate_gbox(lwgeom, &gbox);
504  lwgeom_free(lwgeom);
505 
506  /* If we couldn't calculate the box, return what we know */
507  if ( rv == LW_FAILURE )
508  {
509  PG_FREE_IF_COPY(geom, 1);
510  /* No geom box, no input box, so null return */
511  if ( box == NULL )
512  PG_RETURN_NULL();
513  result = palloc(sizeof(BOX3D));
514  memcpy(result, box, sizeof(BOX3D));
515  PG_RETURN_POINTER(result);
516  }
517 
518  /* Null box and non-null geometry, just return the geometry box */
519  if ( box == NULL )
520  {
521  PG_FREE_IF_COPY(geom, 1);
522  result = box3d_from_gbox(&gbox);
523  result->srid = srid;
524  PG_RETURN_POINTER(result);
525  }
526 
527  result = palloc(sizeof(BOX3D));
528  result->xmax = Max(box->xmax, gbox.xmax);
529  result->ymax = Max(box->ymax, gbox.ymax);
530  result->zmax = Max(box->zmax, gbox.zmax);
531  result->xmin = Min(box->xmin, gbox.xmin);
532  result->ymin = Min(box->ymin, gbox.ymin);
533  result->zmin = Min(box->zmin, gbox.zmin);
534  result->srid = srid;
535 
536  PG_FREE_IF_COPY(geom, 1);
537  PG_RETURN_POINTER(result);
538 }
539 
541 Datum BOX3D_combine_BOX3D(PG_FUNCTION_ARGS)
542 {
543  BOX3D *box0 = (BOX3D*)(PG_ARGISNULL(0) ? NULL : PG_GETARG_POINTER(0));
544  BOX3D *box1 = (BOX3D*)(PG_ARGISNULL(1) ? NULL : PG_GETARG_POINTER(1));
545  BOX3D *result;
546 
547  if (box0 && !box1)
548  PG_RETURN_POINTER(box0);
549 
550  if (box1 && !box0)
551  PG_RETURN_POINTER(box1);
552 
553  if (!box1 && !box0)
554  PG_RETURN_NULL();
555 
556  result = palloc(sizeof(BOX3D));
557  result->xmax = Max(box0->xmax, box1->xmax);
558  result->ymax = Max(box0->ymax, box1->ymax);
559  result->zmax = Max(box0->zmax, box1->zmax);
560  result->xmin = Min(box0->xmin, box1->xmin);
561  result->ymin = Min(box0->ymin, box1->ymin);
562  result->zmin = Min(box0->zmin, box1->zmin);
563  result->srid = box0->srid;
564 
565  PG_RETURN_POINTER(result);
566 }
567 
569 Datum BOX3D_construct(PG_FUNCTION_ARGS)
570 {
571  GSERIALIZED *min = PG_GETARG_GSERIALIZED_P(0);
572  GSERIALIZED *max = PG_GETARG_GSERIALIZED_P(1);
573  BOX3D *result = palloc(sizeof(BOX3D));
574  LWGEOM *minpoint, *maxpoint;
575  POINT3DZ minp, maxp;
576 
577  minpoint = lwgeom_from_gserialized(min);
578  maxpoint = lwgeom_from_gserialized(max);
579 
580  if ( minpoint->type != POINTTYPE ||
581  maxpoint->type != POINTTYPE )
582  {
583  elog(ERROR, "BOX3D_construct: args must be points");
584  PG_RETURN_NULL();
585  }
586 
587  error_if_srid_mismatch(minpoint->srid, maxpoint->srid);
588 
589  getPoint3dz_p(((LWPOINT *)minpoint)->point, 0, &minp);
590  getPoint3dz_p(((LWPOINT *)maxpoint)->point, 0, &maxp);
591 
592  result->xmax = maxp.x;
593  result->ymax = maxp.y;
594  result->zmax = maxp.z;
595 
596  result->xmin = minp.x;
597  result->ymin = minp.y;
598  result->zmin = minp.z;
599 
600  result->srid = minpoint->srid;
601 
602  PG_RETURN_POINTER(result);
603 }
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:460
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:213
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1137
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:116
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:479
double ymin
Definition: liblwgeom.h:276
void error_if_srid_mismatch(int srid1, int srid2)
Definition: lwutil.c:338
int32_t srid
Definition: liblwgeom.h:398
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:319
Datum BOX3D_out(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:135
Datum BOX3D_construct(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:569
#define LW_FAILURE
Definition: liblwgeom.h:78
static void expand_box3d_xyz(BOX3D *box, double dx, double dy, double dz)
Definition: lwgeom_box3d.c:371
Datum BOX3D_zmax(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:467
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:739
double ymin
Definition: liblwgeom.h:293
double zmax
Definition: liblwgeom.h:296
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:329
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:194
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:173
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
Datum BOX3D_xmin(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:432
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 'd' units in all directions.
Definition: lwgeom_box3d.c:359
double ymax
Definition: liblwgeom.h:294
Datum BOX3D_to_BOX2D(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:163
double z
Definition: liblwgeom.h:351
#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:413
GBOX * box3d_to_gbox(const BOX3D *b3d)
Definition: g_box.c:87
int getPoint3dz_p(const POINTARRAY *pa, uint32_t n, POINT3DZ *point)
Definition: lwgeom_api.c:205
BOX3D * box3d_from_gbox(const GBOX *gbox)
Definition: g_box.c:60
Datum BOX3D_ymin(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:439
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:453
Datum BOX3D_expand(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:382
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
Datum BOX3D_combine_BOX3D(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:541
uint8_t type
Definition: liblwgeom.h:395
Datum BOX3D_zmin(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:446
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:342
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:334
LWPOINT * lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:129
void * lwalloc(size_t size)
Definition: lwutil.c:229
double y
Definition: liblwgeom.h:351
double ymax
Definition: liblwgeom.h:277
Datum BOX3D_to_BOX(PG_FUNCTION_ARGS)
Definition: lwgeom_box3d.c:183
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