PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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;
213
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;
228 pt.x = box->xmax;
229 pt.y = box->ymax;
230 pt.z = box->zmax;
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 *g, int32_t srid)
Write the SRID into the serialized form (it is packed into three bytes so this is a handy function).
LWCOLLECTION * lwcollection_construct(uint8_t type, int32_t srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
LWGEOM * lwpoint_as_lwgeom(const LWPOINT *obj)
Definition lwgeom.c:326
#define LW_FALSE
Definition liblwgeom.h:108
void lwpoint_free(LWPOINT *pt)
Definition lwpoint.c:213
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition lwpoint.c:129
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition ptarray.c:59
void * lwalloc(size_t size)
Definition lwutil.c:227
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
Definition lwline.c:42
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition lwgeom.c:321
#define POLYHEDRALSURFACETYPE
Definition liblwgeom.h:128
void lwcollection_free(LWCOLLECTION *col)
LWPOLY * lwpoly_construct_rectangle(char hasz, char hasm, POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D *p4)
Definition lwpoly.c:80
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 lwpoly_free(LWPOLY *poly)
Definition lwpoly.c:175
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
#define SRID_UNKNOWN
Unknown SRID value.
Definition liblwgeom.h:229
#define FLAGS_SET_SOLID(flags, value)
Definition liblwgeom.h:191
LWGEOM * lwpoly_as_lwgeom(const LWPOLY *obj)
Definition lwgeom.c:311
void lwline_free(LWLINE *line)
Definition lwline.c:67
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
double xmax
Definition liblwgeom.h:326
double zmin
Definition liblwgeom.h:325
double ymax
Definition liblwgeom.h:326
double ymin
Definition liblwgeom.h:325
double zmax
Definition liblwgeom.h:326
double xmin
Definition liblwgeom.h:325
int32_t srid
Definition liblwgeom.h:327
lwflags_t flags
Definition liblwgeom.h:447
double x
Definition liblwgeom.h:400
double z
Definition liblwgeom.h:400
double y
Definition liblwgeom.h:400

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: