PostGIS  3.4.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 191 of file lwgeom_box3d.c.

192 {
193  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
194  POINTARRAY *pa;
196  POINT4D pt;
197 
211 
212  /* BOX3D is a point */
213  if ((box->xmin == box->xmax) && (box->ymin == box->ymax) && (box->zmin == box->zmax))
214  {
215  LWPOINT *lwpt = lwpoint_construct(SRID_UNKNOWN, NULL, pa);
216 
217  pt.x = box->xmin;
218  pt.y = box->ymin;
219  pt.z = box->zmin;
220  ptarray_append_point(pa, &pt, LW_TRUE);
221 
222  result = geometry_serialize(lwpoint_as_lwgeom(lwpt));
223  lwpoint_free(lwpt);
224  }
225  /* BOX3D is a line */
226  else if (((box->xmin == box->xmax || box->ymin == box->ymax) && box->zmin == box->zmax) ||
227  ((box->xmin == box->xmax || box->zmin == box->zmax) && box->ymin == box->ymax) ||
228  ((box->ymin == box->ymax || box->zmin == box->zmax) && box->xmin == box->xmax))
229  {
230  LWLINE *lwline = lwline_construct(SRID_UNKNOWN, NULL, pa);
231 
232  pt.x = box->xmin;
233  pt.y = box->ymin;
234  pt.z = box->zmin;
235  ptarray_append_point(pa, &pt, LW_TRUE);
236  pt.x = box->xmax;
237  pt.y = box->ymax;
238  pt.z = box->zmax;
239  ptarray_append_point(pa, &pt, LW_TRUE);
240 
241  result = geometry_serialize(lwline_as_lwgeom(lwline));
242  lwline_free(lwline);
243  }
244  /* BOX3D is a polygon in the X plane */
245  else if (box->xmin == box->xmax)
246  {
247  POINT4D points[4];
248  LWPOLY *lwpoly;
249 
250  /* Initialize the 4 vertices of the polygon */
251  points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0};
252  points[1] = (POINT4D){box->xmin, box->ymax, box->zmin, 0.0};
253  points[2] = (POINT4D){box->xmin, box->ymax, box->zmax, 0.0};
254  points[3] = (POINT4D){box->xmin, box->ymin, box->zmax, 0.0};
255 
256  lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]);
257  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
258  lwpoly_free(lwpoly);
259  }
260  /* BOX3D is a polygon in the Y plane */
261  else if (box->ymin == box->ymax)
262  {
263  POINT4D points[4];
264  LWPOLY *lwpoly;
265 
266  /* Initialize the 4 vertices of the polygon */
267  points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0};
268  points[1] = (POINT4D){box->xmax, box->ymin, box->zmin, 0.0};
269  points[2] = (POINT4D){box->xmax, box->ymin, box->zmax, 0.0};
270  points[3] = (POINT4D){box->xmin, box->ymin, box->zmax, 0.0};
271 
272  lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]);
273  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
274  lwpoly_free(lwpoly);
275  }
276  /* BOX3D is a polygon in the Z plane */
277  else if (box->zmin == box->zmax)
278  {
279  POINT4D points[4];
280  LWPOLY *lwpoly;
281 
282  /* Initialize the 4 vertices of the polygon */
283  points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0};
284  points[1] = (POINT4D){box->xmin, box->ymax, box->zmin, 0.0};
285  points[2] = (POINT4D){box->xmax, box->ymax, box->zmin, 0.0};
286  points[3] = (POINT4D){box->xmax, box->ymin, box->zmin, 0.0};
287 
288  lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]);
289  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
290  lwpoly_free(lwpoly);
291  }
292  /* BOX3D is a polyhedron */
293  else
294  {
295  POINT4D points[8];
296  static const int ngeoms = 6;
297  LWGEOM **geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms);
298  LWGEOM *geom = NULL;
299 
300  /* Initialize the 8 vertices of the box */
301  points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0};
302  points[1] = (POINT4D){box->xmin, box->ymax, box->zmin, 0.0};
303  points[2] = (POINT4D){box->xmax, box->ymax, box->zmin, 0.0};
304  points[3] = (POINT4D){box->xmax, box->ymin, box->zmin, 0.0};
305  points[4] = (POINT4D){box->xmin, box->ymin, box->zmax, 0.0};
306  points[5] = (POINT4D){box->xmin, box->ymax, box->zmax, 0.0};
307  points[6] = (POINT4D){box->xmax, box->ymax, box->zmax, 0.0};
308  points[7] = (POINT4D){box->xmax, box->ymin, box->zmax, 0.0};
309 
310  /* add bottom polygon */
311  geoms[0] = lwpoly_as_lwgeom(
312  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]));
313  /* add top polygon */
314  geoms[1] = lwpoly_as_lwgeom(
315  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[4], &points[7], &points[6], &points[5]));
316  /* add left polygon */
317  geoms[2] = lwpoly_as_lwgeom(
318  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[4], &points[5], &points[1]));
319  /* add right polygon */
320  geoms[3] = lwpoly_as_lwgeom(
321  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[3], &points[2], &points[6], &points[7]));
322  /* add front polygon */
323  geoms[4] = lwpoly_as_lwgeom(
324  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[3], &points[7], &points[4]));
325  /* add back polygon */
326  geoms[5] = lwpoly_as_lwgeom(
327  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[1], &points[5], &points[6], &points[2]));
328 
329  geom = (LWGEOM *)lwcollection_construct(POLYHEDRALSURFACETYPE, SRID_UNKNOWN, NULL, ngeoms, geoms);
330 
331  FLAGS_SET_SOLID(geom->flags, 1);
332 
333  result = geometry_serialize(geom);
335  }
336 
338 
339  PG_RETURN_POINTER(result);
340 }
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition: cu_print.c:262
void gserialized_set_srid(GSERIALIZED *g, int32_t srid)
Write the SRID into the serialized form (it is packed into three bytes so this is a handy function).
Definition: gserialized.c:138
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:339
#define LW_FALSE
Definition: liblwgeom.h:94
void lwpoint_free(LWPOINT *pt)
Definition: lwpoint.c:213
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:329
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
LWPOLY * lwpoly_construct_rectangle(char hasz, char hasm, POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D *p4)
Definition: lwpoly.c:80
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition: lwgeom.c:344
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:129
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:114
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:59
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:357
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,...
Definition: ptarray.c:147
void * lwalloc(size_t size)
Definition: lwutil.c:227
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:42
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:175
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:93
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:215
#define FLAGS_SET_SOLID(flags, value)
Definition: liblwgeom.h:177
void lwline_free(LWLINE *line)
Definition: lwline.c:67
double xmax
Definition: liblwgeom.h:340
double zmin
Definition: liblwgeom.h:339
double ymax
Definition: liblwgeom.h:340
double ymin
Definition: liblwgeom.h:339
double zmax
Definition: liblwgeom.h:340
double xmin
Definition: liblwgeom.h:339
int32_t srid
Definition: liblwgeom.h:341
lwflags_t flags
Definition: liblwgeom.h:461
double x
Definition: liblwgeom.h:414
double z
Definition: liblwgeom.h:414
double y
Definition: liblwgeom.h:414

References LWGEOM::flags, FLAGS_SET_SOLID, 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(), result, BOX3D::srid, SRID_UNKNOWN, POINT4D::x, BOX3D::xmax, BOX3D::xmin, POINT4D::y, BOX3D::ymax, BOX3D::ymin, POINT4D::z, BOX3D::zmax, and BOX3D::zmin.

Here is the call graph for this function: