PostGIS  2.4.9dev-r@@SVN_REVISION@@
lwgeom_box.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 2001-2009 Refractions Research Inc.
22  * Copyright 2009 Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
23  *
24  **********************************************************************/
25 
26 
27 #include "postgres.h"
28 #include "access/gist.h"
29 #include "access/itup.h"
30 #include "fmgr.h"
31 #include "utils/elog.h"
32 #include "utils/geo_decls.h"
33 
34 #include "../postgis_config.h"
35 #include "lwgeom_pg.h"
36 #include "liblwgeom.h"
37 
38 #include <math.h>
39 #include <float.h>
40 #include <string.h>
41 #include <stdio.h>
42 #include <errno.h>
43 
44 
45 /* forward defs */
46 Datum BOX2D_in(PG_FUNCTION_ARGS);
47 Datum BOX2D_out(PG_FUNCTION_ARGS);
48 Datum LWGEOM_to_BOX2D(PG_FUNCTION_ARGS);
49 Datum LWGEOM_to_BOX2DF(PG_FUNCTION_ARGS);
50 Datum BOX2D_expand(PG_FUNCTION_ARGS);
51 Datum BOX2D_to_BOX3D(PG_FUNCTION_ARGS);
52 Datum BOX2D_combine(PG_FUNCTION_ARGS);
53 Datum BOX2D_to_LWGEOM(PG_FUNCTION_ARGS);
54 Datum BOX2D_construct(PG_FUNCTION_ARGS);
55 
56 /* parser - "BOX(xmin ymin,xmax ymax)" */
58 Datum BOX2D_in(PG_FUNCTION_ARGS)
59 {
60  char *str = PG_GETARG_CSTRING(0);
61  int nitems;
62  double tmp;
63  GBOX box;
64  int i;
65 
66  gbox_init(&box);
67 
68  for(i = 0; str[i]; i++) {
69  str[i] = tolower(str[i]);
70  }
71 
72  nitems = sscanf(str,"box(%lf %lf,%lf %lf)", &box.xmin, &box.ymin, &box.xmax, &box.ymax);
73  if (nitems != 4)
74  {
75  elog(ERROR,"box2d parser - couldnt parse. It should look like: BOX(xmin ymin,xmax ymax)");
76  PG_RETURN_NULL();
77  }
78 
79  if (box.xmin > box.xmax)
80  {
81  tmp = box.xmin;
82  box.xmin = box.xmax;
83  box.xmax = tmp;
84  }
85  if (box.ymin > box.ymax)
86  {
87  tmp = box.ymin;
88  box.ymin = box.ymax;
89  box.ymax = tmp;
90  }
91  PG_RETURN_POINTER(gbox_copy(&box));
92 }
93 
94 /*writer "BOX(xmin ymin,xmax ymax)" */
96 Datum BOX2D_out(PG_FUNCTION_ARGS)
97 {
98  char tmp[500]; /* big enough */
99  char *result;
100  int size;
101 
102  GBOX *box = (GBOX *)PG_GETARG_POINTER(0);
103  /* Avoid unaligned access to the gbox struct */
104  GBOX box_aligned;
105  memcpy(&box_aligned, box, sizeof(GBOX));
106 
107  size = sprintf(tmp,
108  "BOX(%.15g %.15g,%.15g %.15g)",
109  box_aligned.xmin,
110  box_aligned.ymin,
111  box_aligned.xmax,
112  box_aligned.ymax);
113 
114  result= palloc(size+1); /* +1= null term */
115  memcpy(result,tmp,size+1);
116  result[size] = '\0';
117 
118  PG_RETURN_CSTRING(result);
119 }
120 
121 
122 /*convert a GSERIALIZED to BOX2D */
124 Datum LWGEOM_to_BOX2D(PG_FUNCTION_ARGS)
125 {
126  GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
127  LWGEOM *lwgeom = lwgeom_from_gserialized(geom);
128  GBOX gbox;
129 
130  /* Cannot box empty! */
131  if ( lwgeom_is_empty(lwgeom) )
132  PG_RETURN_NULL();
133 
134  /* Cannot calculate box? */
135  if ( lwgeom_calculate_gbox(lwgeom, &gbox) == LW_FAILURE )
136  PG_RETURN_NULL();
137 
138  /* Strip out higher dimensions */
139  FLAGS_SET_Z(gbox.flags, 0);
140  FLAGS_SET_M(gbox.flags, 0);
141 
142  PG_FREE_IF_COPY(geom, 0);
143  PG_RETURN_POINTER(gbox_copy(&gbox));
144 }
145 
146 
147 /*convert a GSERIALIZED to BOX2D */
149 Datum LWGEOM_to_BOX2DF(PG_FUNCTION_ARGS)
150 {
151  GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0);
152  GBOX gbox;
153 
154  if ( gserialized_get_gbox_p(geom, &gbox) == LW_FAILURE )
155  PG_RETURN_NULL();
156 
157  /* Strip out higher dimensions */
158  FLAGS_SET_Z(gbox.flags, 0);
159  FLAGS_SET_M(gbox.flags, 0);
160 
161  PG_FREE_IF_COPY(geom, 0);
162  PG_RETURN_POINTER(gbox_copy(&gbox));
163 }
164 
165 
166 /*----------------------------------------------------------
167  * Relational operators for BOXes.
168  * <, >, <=, >=, and == are based on box area.
169  *---------------------------------------------------------*/
170 
171 /*
172  * box_same - are two boxes identical?
173  */
175 Datum BOX2D_same(PG_FUNCTION_ARGS)
176 {
177  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
178  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
179 
180  PG_RETURN_BOOL(FPeq(box1->xmax, box2->xmax) &&
181  FPeq(box1->xmin, box2->xmin) &&
182  FPeq(box1->ymax, box2->ymax) &&
183  FPeq(box1->ymin, box2->ymin));
184 }
185 
186 /*
187  * box_overlap - does box1 overlap box2?
188  */
190 Datum BOX2D_overlap(PG_FUNCTION_ARGS)
191 {
192  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
193  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
194  bool result;
195 
196 
197  result = ((FPge(box1->xmax, box2->xmax) &&
198  FPle(box1->xmin, box2->xmax)) ||
199  (FPge(box2->xmax, box1->xmax) &&
200  FPle(box2->xmin, box1->xmax)))
201  &&
202  ((FPge(box1->ymax, box2->ymax) &&
203  FPle(box1->ymin, box2->ymax)) ||
204  (FPge(box2->ymax, box1->ymax) &&
205  FPle(box2->ymin, box1->ymax)));
206 
207  PG_RETURN_BOOL(result);
208 }
209 
210 
211 /*
212  * box_overleft - is the right edge of box1 to the left of
213  * the right edge of box2?
214  */
216 Datum BOX2D_overleft(PG_FUNCTION_ARGS)
217 {
218  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
219  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
220 
221  PG_RETURN_BOOL(FPle(box1->xmax, box2->xmax));
222 }
223 
224 /*
225  * box_left - is box1 strictly left of box2?
226  */
228 Datum BOX2D_left(PG_FUNCTION_ARGS)
229 {
230  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
231  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
232 
233  PG_RETURN_BOOL(FPlt(box1->xmax, box2->xmin));
234 }
235 
236 /*
237  * box_right - is box1 strictly right of box2?
238  */
240 Datum BOX2D_right(PG_FUNCTION_ARGS)
241 {
242  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
243  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
244 
245  PG_RETURN_BOOL(FPgt(box1->xmin, box2->xmax));
246 }
247 
248 /*
249  * box_overright - is the left edge of box1 to the right of
250  * the left edge of box2?
251  */
253 Datum BOX2D_overright(PG_FUNCTION_ARGS)
254 {
255  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
256  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
257 
258  PG_RETURN_BOOL(FPge(box1->xmin, box2->xmin));
259 }
260 
261 /*
262  * box_overbelow - is the bottom edge of box1 below
263  * the bottom edge of box2?
264  */
266 Datum BOX2D_overbelow(PG_FUNCTION_ARGS)
267 {
268  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
269  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
270 
271  PG_RETURN_BOOL(FPle(box1->ymax, box2->ymax));
272 }
273 
274 /*
275  * box_below - is box1 strictly below box2?
276  */
278 Datum BOX2D_below(PG_FUNCTION_ARGS)
279 {
280  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
281  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
282 
283  PG_RETURN_BOOL(FPlt(box1->ymax, box2->ymin));
284 }
285 
286 /*
287  * box_above - is box1 strictly above box2?
288  */
290 Datum BOX2D_above(PG_FUNCTION_ARGS)
291 {
292  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
293  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
294 
295  PG_RETURN_BOOL(FPgt(box1->ymin, box2->ymax));
296 }
297 
298 /*
299  * box_overabove - the top edge of box1 above
300  * the top edge of box2?
301  */
303 Datum BOX2D_overabove(PG_FUNCTION_ARGS)
304 {
305  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
306  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
307 
308  PG_RETURN_BOOL(FPge(box1->ymin, box2->ymin));
309 }
310 
311 /*
312  * box_contained - is box1 contained by box2?
313  */
315 Datum BOX2D_contained(PG_FUNCTION_ARGS)
316 {
317  GBOX *box1 =(GBOX *) PG_GETARG_POINTER(0);
318  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
319 
320  PG_RETURN_BOOL(FPle(box1->xmax, box2->xmax) &&
321  FPge(box1->xmin, box2->xmin) &&
322  FPle(box1->ymax, box2->ymax) &&
323  FPge(box1->ymin, box2->ymin));
324 }
325 
326 /*
327  * box_contain - does box1 contain box2?
328  */
330 Datum BOX2D_contain(PG_FUNCTION_ARGS)
331 {
332  GBOX *box1 = (GBOX *) PG_GETARG_POINTER(0);
333  GBOX *box2 = (GBOX *) PG_GETARG_POINTER(1);
334 
335  PG_RETURN_BOOL(FPge(box1->xmax, box2->xmax) &&
336  FPle(box1->xmin, box2->xmin) &&
337  FPge(box1->ymax, box2->ymax) &&
338  FPle(box1->ymin, box2->ymin));
339 
340 }
341 
343 Datum BOX2D_intersects(PG_FUNCTION_ARGS)
344 {
345  GBOX *a = (GBOX *) PG_GETARG_POINTER(0);
346  GBOX *b = (GBOX *) PG_GETARG_POINTER(1);
347  GBOX *n;
348 
349 
350  n = (GBOX *) palloc(sizeof(GBOX));
351 
352  n->xmax = Min(a->xmax, b->xmax);
353  n->ymax = Min(a->ymax, b->ymax);
354  n->xmin = Max(a->xmin, b->xmin);
355  n->ymin = Max(a->ymin, b->ymin);
356 
357 
358  if (n->xmax < n->xmin || n->ymax < n->ymin)
359  {
360  pfree(n);
361  /* Indicate "no intersection" by returning NULL pointer */
362  n = NULL;
363  }
364 
365  PG_RETURN_POINTER(n);
366 }
367 
368 
369 /*
370  * union of two BOX2Ds
371  */
373 Datum BOX2D_union(PG_FUNCTION_ARGS)
374 {
375  GBOX *a = (GBOX*) PG_GETARG_POINTER(0);
376  GBOX *b = (GBOX*) PG_GETARG_POINTER(1);
377  GBOX *n;
378 
379  n = (GBOX *) lwalloc(sizeof(GBOX));
380  if ( ! gbox_union(a,b,n) ) PG_RETURN_NULL();
381  PG_RETURN_POINTER(n);
382 }
383 
384 
386 Datum BOX2D_expand(PG_FUNCTION_ARGS)
387 {
388  GBOX *box = (GBOX *)PG_GETARG_POINTER(0);
389  GBOX *result = (GBOX *)palloc(sizeof(GBOX));
390  memcpy(result, box, sizeof(GBOX));
391 
392  if (PG_NARGS() == 2)
393  {
394  double d = PG_GETARG_FLOAT8(1);
395  gbox_expand(result, d);
396  }
397  else
398  {
399  double dx = PG_GETARG_FLOAT8(1);
400  double dy = PG_GETARG_FLOAT8(2);
401 
402  gbox_expand_xyzm(result, dx, dy, 0, 0);
403  }
404 
405  PG_RETURN_POINTER(result);
406 }
407 
409 Datum BOX2D_to_BOX3D(PG_FUNCTION_ARGS)
410 {
411  GBOX *box = (GBOX *)PG_GETARG_POINTER(0);
412  BOX3D *result = box3d_from_gbox(box);
413  PG_RETURN_POINTER(result);
414 }
415 
417 Datum BOX2D_combine(PG_FUNCTION_ARGS)
418 {
419  Pointer box2d_ptr = PG_GETARG_POINTER(0);
420  Pointer geom_ptr = PG_GETARG_POINTER(1);
421  GBOX *a,*b;
422  GSERIALIZED *lwgeom;
423  GBOX box, *result;
424 
425  if ( (box2d_ptr == NULL) && (geom_ptr == NULL) )
426  {
427  PG_RETURN_NULL(); /* combine_box2d(null,null) => null */
428  }
429 
430  result = (GBOX *)palloc(sizeof(GBOX));
431 
432  if (box2d_ptr == NULL)
433  {
434  lwgeom = PG_GETARG_GSERIALIZED_P(1);
435  /* empty geom would make getbox2d_p return NULL */
436  if ( ! gserialized_get_gbox_p(lwgeom, &box) ) PG_RETURN_NULL();
437  memcpy(result, &box, sizeof(GBOX));
438  PG_RETURN_POINTER(result);
439  }
440 
441  /* combine_bbox(BOX3D, null) => BOX3D */
442  if (geom_ptr == NULL)
443  {
444  memcpy(result, (char *)PG_GETARG_DATUM(0), sizeof(GBOX));
445  PG_RETURN_POINTER(result);
446  }
447 
448  /*combine_bbox(BOX3D, geometry) => union(BOX3D, geometry->bvol) */
449 
450  lwgeom = PG_GETARG_GSERIALIZED_P(1);
451  if ( ! gserialized_get_gbox_p(lwgeom, &box) )
452  {
453  /* must be the empty geom */
454  memcpy(result, (char *)PG_GETARG_DATUM(0), sizeof(GBOX));
455  PG_RETURN_POINTER(result);
456  }
457 
458  a = (GBOX *)PG_GETARG_DATUM(0);
459  b = &box;
460 
461  result->xmax = Max(a->xmax, b->xmax);
462  result->ymax = Max(a->ymax, b->ymax);
463  result->xmin = Min(a->xmin, b->xmin);
464  result->ymin = Min(a->ymin, b->ymin);
465 
466  PG_RETURN_POINTER(result);
467 }
468 
470 Datum BOX2D_to_LWGEOM(PG_FUNCTION_ARGS)
471 {
472  GBOX *box = (GBOX *)PG_GETARG_POINTER(0);
473  POINTARRAY *pa = ptarray_construct_empty(0, 0, 5);
474  POINT4D pt;
475  GSERIALIZED *result;
476 
477 
478  /*
479  * Alter BOX2D cast so that a valid geometry is always
480  * returned depending upon the size of the BOX2D. The
481  * code makes the following assumptions:
482  * - If the BOX2D is a single point then return a
483  * POINT geometry
484  * - If the BOX2D represents either a horizontal or
485  * vertical line, return a LINESTRING geometry
486  * - Otherwise return a POLYGON
487  */
488 
489  if ( (box->xmin == box->xmax) && (box->ymin == box->ymax) )
490  {
491  /* Construct and serialize point */
492  LWPOINT *point = lwpoint_make2d(SRID_UNKNOWN, box->xmin, box->ymin);
493  result = geometry_serialize(lwpoint_as_lwgeom(point));
494  lwpoint_free(point);
495  }
496  else if ( (box->xmin == box->xmax) || (box->ymin == box->ymax) )
497  {
498  LWLINE *line;
499 
500  /* Assign coordinates to point array */
501  pt.x = box->xmin;
502  pt.y = box->ymin;
503  ptarray_append_point(pa, &pt, LW_TRUE);
504  pt.x = box->xmax;
505  pt.y = box->ymax;
506  ptarray_append_point(pa, &pt, LW_TRUE);
507 
508  /* Construct and serialize linestring */
509  line = lwline_construct(SRID_UNKNOWN, NULL, pa);
510  result = geometry_serialize(lwline_as_lwgeom(line));
511  lwline_free(line);
512  }
513  else
514  {
515  POINT4D points[4];
516  LWPOLY *poly;
517 
518  /* Initialize the 4 vertices of the polygon */
519  points[0] = (POINT4D) { box->xmin, box->ymin };
520  points[1] = (POINT4D) { box->xmin, box->ymax };
521  points[2] = (POINT4D) { box->xmax, box->ymax };
522  points[3] = (POINT4D) { box->xmax, box->ymin };
523 
524  /* Construct polygon */
525  poly = lwpoly_construct_rectangle(LW_FALSE, LW_FALSE, &points[0], &points[1],
526  &points[2], &points[3]);
527  result = geometry_serialize(lwpoly_as_lwgeom(poly));
528  lwpoly_free(poly);
529  }
530 
531  PG_RETURN_POINTER(result);
532 }
533 
535 Datum BOX2D_construct(PG_FUNCTION_ARGS)
536 {
537  GSERIALIZED *pgmin = PG_GETARG_GSERIALIZED_P(0);
538  GSERIALIZED *pgmax = PG_GETARG_GSERIALIZED_P(1);
539  GBOX *result;
540  LWPOINT *minpoint, *maxpoint;
541  double min, max, tmp;
542 
543  minpoint = (LWPOINT*)lwgeom_from_gserialized(pgmin);
544  maxpoint = (LWPOINT*)lwgeom_from_gserialized(pgmax);
545 
546  if ( (minpoint->type != POINTTYPE) || (maxpoint->type != POINTTYPE) )
547  {
548  elog(ERROR, "GBOX_construct: arguments must be points");
549  PG_RETURN_NULL();
550  }
551 
552  error_if_srid_mismatch(minpoint->srid, maxpoint->srid);
553 
554  result = gbox_new(gflags(0, 0, 0));
555 
556  /* Process X min/max */
557  min = lwpoint_get_x(minpoint);
558  max = lwpoint_get_x(maxpoint);
559  if ( min > max )
560  {
561  tmp = min;
562  min = max;
563  max = tmp;
564  }
565  result->xmin = min;
566  result->xmax = max;
567 
568  /* Process Y min/max */
569  min = lwpoint_get_y(minpoint);
570  max = lwpoint_get_y(maxpoint);
571  if ( min > max )
572  {
573  tmp = min;
574  min = max;
575  max = tmp;
576  }
577  result->ymin = min;
578  result->ymax = max;
579 
580  PG_RETURN_POINTER(result);
581 }
582 
int gserialized_get_gbox_p(const GSERIALIZED *g, GBOX *box)
Read the bounding box off a serialization and calculate one if it is not already there.
Definition: g_serialized.c:642
double x
Definition: liblwgeom.h:352
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition: g_box.c:438
Datum BOX2D_union(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:373
GBOX * gbox_new(uint8_t flags)
Create a new gbox with the dimensionality indicated by the flags.
Definition: g_box.c:43
void gbox_expand_xyzm(GBOX *g, double dx, double dy, double dz, double dm)
Move the box minimums down and the maximums up by the distances provided.
Definition: g_box.c:126
Datum BOX2D_overright(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:253
Datum BOX2D_same(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:175
uint8_t type
Definition: liblwgeom.h:407
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
void * Pointer
Definition: kmeans.h:59
void gbox_expand(GBOX *g, double d)
Move the box minimums down and the maximums up by the distance provided.
Definition: g_box.c:108
Datum BOX2D_contain(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:330
Datum BOX2D_below(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:278
Datum BOX2D_overlap(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:190
LWPOINT * lwpoint_make2d(int srid, double x, double y)
Definition: lwpoint.c:163
double xmax
Definition: liblwgeom.h:293
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 lwline_free(LWLINE *line)
Definition: lwline.c:76
Datum BOX2D_combine(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:417
void error_if_srid_mismatch(int srid1, int srid2)
Definition: lwutil.c:371
Datum BOX2D_intersects(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:343
Datum BOX2D_in(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:58
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:288
Datum BOX2D_out(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:96
Datum BOX2D_overleft(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:216
PG_FUNCTION_INFO_V1(BOX2D_in)
#define LW_FAILURE
Definition: liblwgeom.h:79
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:701
#define FLAGS_SET_Z(flags, value)
Definition: liblwgeom.h:146
double lwpoint_get_x(const LWPOINT *point)
Definition: lwpoint.c:63
Datum BOX2D_to_BOX3D(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:409
double ymin
Definition: liblwgeom.h:294
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:298
void gbox_init(GBOX *gbox)
Zero out all the entries in the GBOX.
Definition: g_box.c:51
double xmin
Definition: liblwgeom.h:292
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:77
Datum LWGEOM_to_BOX2D(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:124
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:174
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:188
Datum BOX2D_overabove(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:303
Datum BOX2D_overbelow(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:266
Datum BOX2D_construct(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:535
double ymax
Definition: liblwgeom.h:295
Datum BOX2D_above(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:290
int gbox_union(const GBOX *g1, const GBOX *g2, GBOX *gout)
Update the output GBOX to be large enough to include both inputs.
Definition: g_box.c:146
int32_t srid
Definition: liblwgeom.h:410
uint8_t flags
Definition: liblwgeom.h:291
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
Datum BOX2D_left(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:228
BOX3D * box3d_from_gbox(const GBOX *gbox)
Definition: g_box.c:64
Datum BOX2D_right(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:240
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:85
Datum BOX2D_to_LWGEOM(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:470
Datum BOX2D_contained(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:315
#define FPeq(A, B)
Definition: box2d.c:37
double lwpoint_get_y(const LWPOINT *point)
Definition: lwpoint.c:76
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:303
Datum BOX2D_expand(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:386
void * lwalloc(size_t size)
Definition: lwutil.c:229
Datum LWGEOM_to_BOX2DF(PG_FUNCTION_ARGS)
Definition: lwgeom_box.c:149
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Definition: lwgeom.c:1346
double y
Definition: liblwgeom.h:352
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.
#define FLAGS_SET_M(flags, value)
Definition: liblwgeom.h:147