mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-23 16:42:35 +00:00
#3466, Casting from box3d to geometry drops Z dimension (Julien Rouhaud)
git-svn-id: http://svn.osgeo.org/postgis/trunk@14786 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
parent
59a06fcf53
commit
45b0803360
2
NEWS
2
NEWS
|
@ -2,6 +2,8 @@ PostGIS 2.3.0
|
|||
2015/XX/XX
|
||||
|
||||
* Important / Breaking Changes *
|
||||
- #3466, Casting from box3d to geometry now returns a 3D
|
||||
geometry (Julien Rouhaud)
|
||||
* Deprecated signatures *
|
||||
* New Features *
|
||||
|
||||
|
|
|
@ -208,6 +208,7 @@ Ingvild Nystuen,
|
|||
Jason Smith,
|
||||
Jeff Adams,
|
||||
Jose Carlos Martinez Llari,
|
||||
Julien Rouhaud,
|
||||
Kashif Rasul,
|
||||
Klaus Foerster,
|
||||
Kris Jurka,
|
||||
|
|
|
@ -1337,6 +1337,7 @@ extern LWLINE *lwline_addpoint(LWLINE *line, LWPOINT *point, uint32_t where);
|
|||
extern LWLINE *lwline_removepoint(LWLINE *line, uint32_t which);
|
||||
extern void lwline_setPoint4d(LWLINE *line, uint32_t which, POINT4D *newpoint);
|
||||
extern LWPOLY *lwpoly_from_lwlines(const LWLINE *shell, uint32_t nholes, const LWLINE **holes);
|
||||
extern LWPOLY* lwpoly_construct_rectangle(char hasz, char hasm, POINT4D *p1, POINT4D *p2, POINT4D *p3, POINT4D *p4);
|
||||
extern LWTRIANGLE *lwtriangle_from_lwline(const LWLINE *shell);
|
||||
extern LWMPOINT *lwmpoint_from_lwgeom(const LWGEOM *g); /* Extract the coordinates of an LWGEOM into an LWMPOINT */
|
||||
|
||||
|
|
|
@ -75,6 +75,24 @@ lwpoly_construct(int srid, GBOX *bbox, uint32_t nrings, POINTARRAY **points)
|
|||
return result;
|
||||
}
|
||||
|
||||
LWPOLY*
|
||||
lwpoly_construct_rectangle(char hasz, char hasm, POINT4D *p1, POINT4D *p2,
|
||||
POINT4D *p3, POINT4D *p4)
|
||||
{
|
||||
POINTARRAY *pa = ptarray_construct_empty(hasz, hasm, 5);
|
||||
LWPOLY *lwpoly = lwpoly_construct_empty(SRID_UNKNOWN, hasz, hasm);
|
||||
|
||||
ptarray_append_point(pa, p1, LW_TRUE);
|
||||
ptarray_append_point(pa, p2, LW_TRUE);
|
||||
ptarray_append_point(pa, p3, LW_TRUE);
|
||||
ptarray_append_point(pa, p4, LW_TRUE);
|
||||
ptarray_append_point(pa, p1, LW_TRUE);
|
||||
|
||||
lwpoly_add_ring(lwpoly, pa);
|
||||
|
||||
return lwpoly;
|
||||
}
|
||||
|
||||
LWPOLY*
|
||||
lwpoly_construct_empty(int srid, char hasz, char hasm)
|
||||
{
|
||||
|
|
|
@ -494,29 +494,18 @@ Datum BOX2D_to_LWGEOM(PG_FUNCTION_ARGS)
|
|||
}
|
||||
else
|
||||
{
|
||||
POINT4D points[4];
|
||||
LWPOLY *poly;
|
||||
POINTARRAY **ppa = lwalloc(sizeof(POINTARRAY*));
|
||||
|
||||
/* Assign coordinates to point array */
|
||||
pt.x = box->xmin;
|
||||
pt.y = box->ymin;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
pt.x = box->xmin;
|
||||
pt.y = box->ymax;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
pt.x = box->xmax;
|
||||
pt.y = box->ymax;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
pt.x = box->xmax;
|
||||
pt.y = box->ymin;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
pt.x = box->xmin;
|
||||
pt.y = box->ymin;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
/* Initialize the 4 vertices of the polygon */
|
||||
points[0] = (POINT4D) { box->xmin, box->ymin };
|
||||
points[1] = (POINT4D) { box->xmin, box->ymax };
|
||||
points[2] = (POINT4D) { box->xmax, box->ymax };
|
||||
points[3] = (POINT4D) { box->xmax, box->ymin };
|
||||
|
||||
/* Construct polygon */
|
||||
ppa[0] = pa;
|
||||
poly = lwpoly_construct(SRID_UNKNOWN, NULL, 1, ppa);
|
||||
poly = lwpoly_construct_rectangle(LW_FALSE, LW_FALSE, &points[0], &points[1],
|
||||
&points[2], &points[3]);
|
||||
result = geometry_serialize(lwpoly_as_lwgeom(poly));
|
||||
lwpoly_free(poly);
|
||||
}
|
||||
|
|
|
@ -199,69 +199,159 @@ Datum BOX3D_to_LWGEOM(PG_FUNCTION_ARGS)
|
|||
GSERIALIZED *result;
|
||||
POINT4D pt;
|
||||
|
||||
|
||||
/**
|
||||
* 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 either a horizontal or
|
||||
* vertical line, return a LINESTRING geometry
|
||||
* - Otherwise return a POLYGON
|
||||
* - 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
|
||||
*/
|
||||
|
||||
pa = ptarray_construct_empty(0, 0, 5);
|
||||
pa = ptarray_construct_empty(LW_TRUE, LW_FALSE, 5);
|
||||
|
||||
if ( (box->xmin == box->xmax) && (box->ymin == box->ymax) )
|
||||
/* BOX3D is a point */
|
||||
if ( (box->xmin == box->xmax) && (box->ymin == box->ymax) &&
|
||||
(box->zmin == box->zmax) )
|
||||
{
|
||||
LWPOINT *lwpt = lwpoint_construct(SRID_UNKNOWN, NULL, pa);
|
||||
|
||||
pt.x = box->xmin;
|
||||
pt.y = box->ymin;
|
||||
pt.z = box->zmin;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
|
||||
result = geometry_serialize(lwpoint_as_lwgeom(lwpt));
|
||||
lwpoint_free(lwpt);
|
||||
}
|
||||
else if (box->xmin == box->xmax ||
|
||||
box->ymin == box->ymax)
|
||||
/* BOX3D is a line */
|
||||
else if (((box->xmin == box->xmax ||
|
||||
box->ymin == box->ymax) &&
|
||||
box->zmin == box->zmax) ||
|
||||
((box->xmin == box->xmax ||
|
||||
box->zmin == box->zmax) &&
|
||||
box->ymin == box->ymax) ||
|
||||
((box->ymin == box->ymax ||
|
||||
box->zmin == box->zmax) &&
|
||||
box->xmin == box->xmax))
|
||||
{
|
||||
LWLINE *lwline = lwline_construct(SRID_UNKNOWN, NULL, pa);
|
||||
|
||||
pt.x = box->xmin;
|
||||
pt.y = box->ymin;
|
||||
pt.z = box->zmin;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
pt.x = box->xmax;
|
||||
pt.y = box->ymax;
|
||||
pt.z = box->zmax;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
|
||||
result = geometry_serialize(lwline_as_lwgeom(lwline));
|
||||
lwline_free(lwline);
|
||||
}
|
||||
/* BOX3D is a polygon in the X plane */
|
||||
else if (box->xmin == box->xmax)
|
||||
{
|
||||
POINT4D points[4];
|
||||
LWPOLY *lwpoly;
|
||||
|
||||
/* Initialize the 4 vertices of the polygon */
|
||||
points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin };
|
||||
points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin };
|
||||
points[2] = (POINT4D) { box->xmin, box->ymax, box->zmax };
|
||||
points[3] = (POINT4D) { box->xmin, box->ymin, box->zmax };
|
||||
|
||||
lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE,
|
||||
&points[0], &points[1], &points[2], &points[3]);
|
||||
result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
|
||||
lwpoly_free(lwpoly);
|
||||
}
|
||||
/* BOX3D is a polygon in the Y plane */
|
||||
else if (box->ymin == box->ymax)
|
||||
{
|
||||
POINT4D points[4];
|
||||
LWPOLY *lwpoly;
|
||||
|
||||
/* Initialize the 4 vertices of the polygon */
|
||||
points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin };
|
||||
points[1] = (POINT4D) { box->xmax, box->ymin, box->zmin };
|
||||
points[2] = (POINT4D) { box->xmax, box->ymin, box->zmax };
|
||||
points[3] = (POINT4D) { box->xmin, box->ymin, box->zmax };
|
||||
|
||||
lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE,
|
||||
&points[0], &points[1], &points[2], &points[3]);
|
||||
result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
|
||||
lwpoly_free(lwpoly);
|
||||
}
|
||||
/* BOX3D is a polygon in the Z plane */
|
||||
else if (box->zmin == box->zmax)
|
||||
{
|
||||
POINT4D points[4];
|
||||
LWPOLY *lwpoly;
|
||||
|
||||
/* Initialize the 4 vertices of the polygon */
|
||||
points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin };
|
||||
points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin };
|
||||
points[2] = (POINT4D) { box->xmax, box->ymax, box->zmin };
|
||||
points[3] = (POINT4D) { box->xmax, box->ymin, box->zmin };
|
||||
|
||||
lwpoly = lwpoly_construct_rectangle(LW_TRUE, LW_FALSE,
|
||||
&points[0], &points[1], &points[2], &points[3]);
|
||||
result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
|
||||
lwpoly_free(lwpoly);
|
||||
}
|
||||
/* BOX3D is a polyhedron */
|
||||
else
|
||||
{
|
||||
LWPOLY *lwpoly = lwpoly_construct(SRID_UNKNOWN, NULL, 1, &pa);
|
||||
POINT4D points[8];
|
||||
static const int ngeoms = 6;
|
||||
LWGEOM **geoms = (LWGEOM **) lwalloc(sizeof(LWGEOM *) * ngeoms);
|
||||
LWGEOM *geom = NULL;
|
||||
|
||||
pt.x = box->xmin;
|
||||
pt.y = box->ymin;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
pt.x = box->xmin;
|
||||
pt.y = box->ymax;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
pt.x = box->xmax;
|
||||
pt.y = box->ymax;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
pt.x = box->xmax;
|
||||
pt.y = box->ymin;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
pt.x = box->xmin;
|
||||
pt.y = box->ymin;
|
||||
ptarray_append_point(pa, &pt, LW_TRUE);
|
||||
/* Initialize the 8 vertices of the box */
|
||||
points[0] = (POINT4D) { box->xmin, box->ymin, box->zmin };
|
||||
points[1] = (POINT4D) { box->xmin, box->ymax, box->zmin };
|
||||
points[2] = (POINT4D) { box->xmax, box->ymax, box->zmin };
|
||||
points[3] = (POINT4D) { box->xmax, box->ymin, box->zmin };
|
||||
points[4] = (POINT4D) { box->xmin, box->ymin, box->zmax };
|
||||
points[5] = (POINT4D) { box->xmin, box->ymax, box->zmax };
|
||||
points[6] = (POINT4D) { box->xmax, box->ymax, box->zmax };
|
||||
points[7] = (POINT4D) { box->xmax, box->ymin, box->zmax };
|
||||
|
||||
result = geometry_serialize(lwpoly_as_lwgeom(lwpoly));
|
||||
|
||||
/* add bottom polygon */
|
||||
geoms[0] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE,
|
||||
&points[0], &points[1], &points[2], &points[3]));
|
||||
/* add top polygon */
|
||||
geoms[1] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE,
|
||||
&points[4], &points[5], &points[6], &points[7]));
|
||||
/* add left polygon */
|
||||
geoms[2] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE,
|
||||
&points[0], &points[1], &points[5], &points[4]));
|
||||
/* add right polygon */
|
||||
geoms[3] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE,
|
||||
&points[3], &points[2], &points[6], &points[7]));
|
||||
/* add back polygon */
|
||||
geoms[4] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE,
|
||||
&points[0], &points[3], &points[7], &points[4]));
|
||||
/* add front polygon */
|
||||
geoms[5] = lwpoly_as_lwgeom(lwpoly_construct_rectangle(LW_TRUE, LW_FALSE,
|
||||
&points[1], &points[2], &points[6], &points[5]));
|
||||
|
||||
geom = (LWGEOM *) lwcollection_construct(POLYHEDRALSURFACETYPE,
|
||||
SRID_UNKNOWN, NULL, ngeoms, geoms);
|
||||
|
||||
FLAGS_SET_SOLID(geom->flags, 1);
|
||||
|
||||
result = geometry_serialize(geom);
|
||||
lwcollection_free((LWCOLLECTION *) geom);
|
||||
}
|
||||
|
||||
gserialized_set_srid(result, box->srid);
|
||||
|
||||
PG_RETURN_POINTER(result);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
-- postgres
|
||||
--- regression test for postGIS
|
||||
|
||||
|
||||
|
@ -129,7 +130,12 @@ select '76a',ST_OrderingEquals('LINESTRING(1 1, 2 2)'::GEOMETRY,'LINESTRING(1 1,
|
|||
select '106',box3d('MULTIPOINT(0 0, 7 7)'::GEOMETRY) as bvol;
|
||||
|
||||
-- box3d only type is only used for indexing -- NEVER use one yourself
|
||||
select '107',ST_AsEWKT(geometry('BOX3D(0 0 0, 7 7 7 )'::BOX3D));
|
||||
select '107a',ST_AsEWKT(geometry('BOX3D(1 2 3, 1 2 3 )'::BOX3D));
|
||||
select '107b',ST_AsEWKT(geometry('BOX3D(2 3 3, 7 3 3 )'::BOX3D));
|
||||
select '107c',ST_AsEWKT(geometry('BOX3D(2 3 5, 6 8 5 )'::BOX3D));
|
||||
select '107d',ST_AsEWKT(geometry('BOX3D(1 -1 4, 2 -1 9 )'::BOX3D));
|
||||
select '107e',ST_AsEWKT(geometry('BOX3D(-1 3 5, -1 6 8 )'::BOX3D));
|
||||
select '107f',ST_AsEWKT(geometry('BOX3D(1 2 3, 4 5 6 )'::BOX3D));
|
||||
|
||||
--- debug function testing
|
||||
|
||||
|
|
|
@ -87,7 +87,12 @@ ERROR: parse error - invalid geometry at character 23
|
|||
76|f
|
||||
76a|f
|
||||
106|BOX3D(0 0 0,7 7 0)
|
||||
107|POLYGON((0 0,0 7,7 7,7 0,0 0))
|
||||
107a|POINT(1 2 3)
|
||||
107b|LINESTRING(2 3 3,7 3 3)
|
||||
107c|POLYGON((2 3 5,2 8 5,6 8 5,6 3 5,2 3 5))
|
||||
107d|POLYGON((1 -1 4,2 -1 4,2 -1 9,1 -1 9,1 -1 4))
|
||||
107e|POLYGON((-1 3 5,-1 6 5,-1 6 8,-1 3 8,-1 3 5))
|
||||
107f|POLYHEDRALSURFACE(((1 2 3,1 5 3,4 5 3,4 2 3,1 2 3)),((1 2 6,1 5 6,4 5 6,4 2 6,1 2 6)),((1 2 3,1 5 3,1 5 6,1 2 6,1 2 3)),((4 2 3,4 5 3,4 5 6,4 2 6,4 2 3)),((1 2 3,4 2 3,4 2 6,1 2 6,1 2 3)),((1 5 3,4 5 3,4 5 6,1 5 6,1 5 3)))
|
||||
108|2
|
||||
109|4
|
||||
110|6
|
||||
|
|
|
@ -178,7 +178,12 @@ select '105','MULTIPOINT(-0.0001 0, 7 7)'::GEOMETRY @ 'MULTIPOINT(0 0, 10 10)'::
|
|||
select '106',box3d('MULTIPOINT(0 0, 7 7)'::GEOMETRY) as bvol;
|
||||
|
||||
-- box3d only type is only used for indexing -- NEVER use one yourself
|
||||
select '107',ST_AsEWKT(geometry('BOX3D(0 0 0, 7 7 7 )'::BOX3D));
|
||||
select '107a',ST_AsEWKT(geometry('BOX3D(1 2 3, 1 2 3 )'::BOX3D));
|
||||
select '107b',ST_AsEWKT(geometry('BOX3D(2 3 3, 7 3 3 )'::BOX3D));
|
||||
select '107c',ST_AsEWKT(geometry('BOX3D(2 3 5, 6 8 5 )'::BOX3D));
|
||||
select '107d',ST_AsEWKT(geometry('BOX3D(1 -1 4, 2 -1 9 )'::BOX3D));
|
||||
select '107e',ST_AsEWKT(geometry('BOX3D(-1 3 5, -1 6 8 )'::BOX3D));
|
||||
select '107f',ST_AsEWKT(geometry('BOX3D(1 2 3, 4 5 6 )'::BOX3D));
|
||||
|
||||
--- debug function testing
|
||||
|
||||
|
|
|
@ -116,7 +116,12 @@ ERROR: parse error - invalid geometry at character 23
|
|||
104|t
|
||||
105|f
|
||||
106|BOX3D(0 0 0,7 7 0)
|
||||
107|POLYGON((0 0,0 7,7 7,7 0,0 0))
|
||||
107a|POINT(1 2 3)
|
||||
107b|LINESTRING(2 3 3,7 3 3)
|
||||
107c|POLYGON((2 3 5,2 8 5,6 8 5,6 3 5,2 3 5))
|
||||
107d|POLYGON((1 -1 4,2 -1 4,2 -1 9,1 -1 9,1 -1 4))
|
||||
107e|POLYGON((-1 3 5,-1 6 5,-1 6 8,-1 3 8,-1 3 5))
|
||||
107f|POLYHEDRALSURFACE(((1 2 3,1 5 3,4 5 3,4 2 3,1 2 3)),((1 2 6,1 5 6,4 5 6,4 2 6,1 2 6)),((1 2 3,1 5 3,1 5 6,1 2 6,1 2 3)),((4 2 3,4 5 3,4 5 6,4 2 6,4 2 3)),((1 2 3,4 2 3,4 2 6,1 2 6,1 2 3)),((1 5 3,4 5 3,4 5 6,1 5 6,1 5 3)))
|
||||
108|2
|
||||
109|4
|
||||
110|6
|
||||
|
|
Loading…
Reference in a new issue