PostGIS  2.5.0dev-r@@SVN_REVISION@@

◆ BOX3D_to_LWGEOM()

Datum BOX3D_to_LWGEOM ( PG_FUNCTION_ARGS  )

Alter BOX3D cast so that a valid geometry is always returned depending upon the size of the BOX3D. The code makes the following assumptions:

  • If the BOX3D is a single point then return a POINT geometry
  • If the BOX3D represents a line in any of X, Y or Z dimension, return a LINESTRING geometry
  • If the BOX3D represents a plane in the X, Y, or Z dimension, return a POLYGON geometry
  • Otherwise return a POLYHEDRALSURFACE geometry

Definition at line 194 of file lwgeom_box3d.c.

References LWGEOM::flags, FLAGS_SET_SOLID, geometry_serialize(), gserialized_set_srid(), LW_FALSE, LW_TRUE, lwalloc(), lwcollection_construct(), lwcollection_free(), lwline_as_lwgeom(), lwline_construct(), lwline_free(), lwpoint_as_lwgeom(), lwpoint_construct(), lwpoint_free(), lwpoly_as_lwgeom(), lwpoly_construct_rectangle(), lwpoly_free(), POLYHEDRALSURFACETYPE, ptarray_append_point(), ptarray_construct_empty(), BOX3D::srid, SRID_UNKNOWN, POINT4D::x, BOX3D::xmax, BOX3D::xmin, POINT4D::y, BOX3D::ymax, BOX3D::ymin, POINT4D::z, BOX3D::zmax, and BOX3D::zmin.

Referenced by BOX3D_to_BOX().

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[7], &points[6], &points[5]));
330  /* add left polygon */
332  &points[0], &points[4], &points[5], &points[1]));
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[5], &points[6], &points[2]));
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 }
double x
Definition: liblwgeom.h:354
int32_t srid
Definition: liblwgeom.h:281
#define FLAGS_SET_SOLID(flags, value)
Definition: liblwgeom.h:150
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:43
uint8_t flags
Definition: liblwgeom.h:399
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
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
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:96
double ymin
Definition: liblwgeom.h:279
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:320
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:330
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:279
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:175
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:187
double z
Definition: liblwgeom.h:354
double xmax
Definition: liblwgeom.h:280
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:356
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:335
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:354
double ymax
Definition: liblwgeom.h:280
LWPOLY * lwpoly_construct_rectangle(char hasz, char hasm, POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D *p4)
Definition: lwpoly.c:80
double zmax
Definition: liblwgeom.h:280
double zmin
Definition: liblwgeom.h:279
Here is the call graph for this function:
Here is the caller graph for this function: