PostGIS  2.5.7dev-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 183 of file lwgeom_box3d.c.

184 {
185  BOX3D *box = (BOX3D *)PG_GETARG_POINTER(0);
186  POINTARRAY *pa;
187  GSERIALIZED *result;
188  POINT4D pt;
189 
203 
204  /* BOX3D is a point */
205  if ((box->xmin == box->xmax) && (box->ymin == box->ymax) && (box->zmin == box->zmax))
206  {
207  LWPOINT *lwpt = lwpoint_construct(SRID_UNKNOWN, NULL, pa);
208 
209  pt.x = box->xmin;
210  pt.y = box->ymin;
211  pt.z = box->zmin;
212  ptarray_append_point(pa, &pt, LW_TRUE);
213 
214  result = geometry_serialize(lwpoint_as_lwgeom(lwpt));
215  lwpoint_free(lwpt);
216  }
217  /* BOX3D is a line */
218  else if (((box->xmin == box->xmax || box->ymin == box->ymax) && box->zmin == box->zmax) ||
219  ((box->xmin == box->xmax || box->zmin == box->zmax) && box->ymin == box->ymax) ||
220  ((box->ymin == box->ymax || box->zmin == box->zmax) && box->xmin == box->xmax))
221  {
222  LWLINE *lwline = lwline_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  pt.x = box->xmax;
229  pt.y = box->ymax;
230  pt.z = box->zmax;
231  ptarray_append_point(pa, &pt, LW_TRUE);
232 
233  result = geometry_serialize(lwline_as_lwgeom(lwline));
234  lwline_free(lwline);
235  }
236  /* BOX3D is a polygon in the X plane */
237  else if (box->xmin == box->xmax)
238  {
239  POINT4D points[4];
240  LWPOLY *lwpoly;
241 
242  /* Initialize the 4 vertices of the polygon */
243  points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0};
244  points[1] = (POINT4D){box->xmin, box->ymax, box->zmin, 0.0};
245  points[2] = (POINT4D){box->xmin, box->ymax, box->zmax, 0.0};
246  points[3] = (POINT4D){box->xmin, box->ymin, box->zmax, 0.0};
247 
248  lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]);
249  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
250  lwpoly_free(lwpoly);
251  }
252  /* BOX3D is a polygon in the Y plane */
253  else if (box->ymin == box->ymax)
254  {
255  POINT4D points[4];
256  LWPOLY *lwpoly;
257 
258  /* Initialize the 4 vertices of the polygon */
259  points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0};
260  points[1] = (POINT4D){box->xmax, box->ymin, box->zmin, 0.0};
261  points[2] = (POINT4D){box->xmax, box->ymin, box->zmax, 0.0};
262  points[3] = (POINT4D){box->xmin, box->ymin, box->zmax, 0.0};
263 
264  lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]);
265  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
266  lwpoly_free(lwpoly);
267  }
268  /* BOX3D is a polygon in the Z plane */
269  else if (box->zmin == box->zmax)
270  {
271  POINT4D points[4];
272  LWPOLY *lwpoly;
273 
274  /* Initialize the 4 vertices of the polygon */
275  points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0};
276  points[1] = (POINT4D){box->xmin, box->ymax, box->zmin, 0.0};
277  points[2] = (POINT4D){box->xmax, box->ymax, box->zmin, 0.0};
278  points[3] = (POINT4D){box->xmax, box->ymin, box->zmin, 0.0};
279 
280  lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]);
281  result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
282  lwpoly_free(lwpoly);
283  }
284  /* BOX3D is a polyhedron */
285  else
286  {
287  POINT4D points[8];
288  static const int ngeoms = 6;
289  LWGEOM **geoms = (LWGEOM **)lwalloc(sizeof(LWGEOM *) * ngeoms);
290  LWGEOM *geom = NULL;
291 
292  /* Initialize the 8 vertices of the box */
293  points[0] = (POINT4D){box->xmin, box->ymin, box->zmin, 0.0};
294  points[1] = (POINT4D){box->xmin, box->ymax, box->zmin, 0.0};
295  points[2] = (POINT4D){box->xmax, box->ymax, box->zmin, 0.0};
296  points[3] = (POINT4D){box->xmax, box->ymin, box->zmin, 0.0};
297  points[4] = (POINT4D){box->xmin, box->ymin, box->zmax, 0.0};
298  points[5] = (POINT4D){box->xmin, box->ymax, box->zmax, 0.0};
299  points[6] = (POINT4D){box->xmax, box->ymax, box->zmax, 0.0};
300  points[7] = (POINT4D){box->xmax, box->ymin, box->zmax, 0.0};
301 
302  /* add bottom polygon */
303  geoms[0] = lwpoly_as_lwgeom(
304  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[1], &points[2], &points[3]));
305  /* add top polygon */
306  geoms[1] = lwpoly_as_lwgeom(
307  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[4], &points[7], &points[6], &points[5]));
308  /* add left polygon */
309  geoms[2] = lwpoly_as_lwgeom(
310  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[4], &points[5], &points[1]));
311  /* add right polygon */
312  geoms[3] = lwpoly_as_lwgeom(
313  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[3], &points[2], &points[6], &points[7]));
314  /* add front polygon */
315  geoms[4] = lwpoly_as_lwgeom(
316  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[0], &points[3], &points[7], &points[4]));
317  /* add back polygon */
318  geoms[5] = lwpoly_as_lwgeom(
319  lwpoly_construct_rectangle(LW_TRUE, LW_FALSE, &points[1], &points[5], &points[6], &points[2]));
320 
321  geom = (LWGEOM *)lwcollection_construct(POLYHEDRALSURFACETYPE, SRID_UNKNOWN, NULL, ngeoms, geoms);
322 
323  FLAGS_SET_SOLID(geom->flags, 1);
324 
325  result = geometry_serialize(geom);
327  }
328 
329  gserialized_set_srid(result, box->srid);
330 
331  PG_RETURN_POINTER(result);
332 }
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:117
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:330
#define LW_FALSE
Definition: liblwgeom.h:77
void lwpoint_free(LWPOINT *pt)
Definition: lwpoint.c:213
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition: lwgeom.c:320
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:335
LWPOINT * lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:129
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:97
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:70
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:356
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:43
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:156
void * lwalloc(size_t size)
Definition: lwutil.c:229
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:175
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
#define SRID_UNKNOWN
Unknown SRID value.
Definition: liblwgeom.h:188
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
#define FLAGS_SET_SOLID(flags, value)
Definition: liblwgeom.h:151
void lwline_free(LWLINE *line)
Definition: lwline.c:76
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
double xmax
Definition: liblwgeom.h:281
double zmin
Definition: liblwgeom.h:280
double ymax
Definition: liblwgeom.h:281
double ymin
Definition: liblwgeom.h:280
double zmax
Definition: liblwgeom.h:281
double xmin
Definition: liblwgeom.h:280
int32_t srid
Definition: liblwgeom.h:282
uint8_t flags
Definition: liblwgeom.h:400
double x
Definition: liblwgeom.h:355
double z
Definition: liblwgeom.h:355
double y
Definition: liblwgeom.h:355

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.

Here is the call graph for this function: