Commit 84ede471 authored by Paul Ramsey's avatar Paul Ramsey

Fix for GBT#96.


git-svn-id: http://svn.osgeo.org/postgis/trunk@3817 b70326c6-7e19-0410-871a-916f4a2858ee
parent adbc4841
......@@ -453,6 +453,7 @@ extern LWPOLY *lwgeom_as_lwpoly(LWGEOM *lwgeom);
extern LWLINE *lwgeom_as_lwline(LWGEOM *lwgeom);
extern LWPOINT *lwgeom_as_lwpoint(LWGEOM *lwgeom);
extern LWCIRCSTRING *lwgeom_as_lwcircstring(LWGEOM *lwgeom);
extern LWGEOM *lwgeom_as_multi(LWGEOM *lwgeom);
/* Casts LW*->LWGEOM (always cast) */
extern LWGEOM *lwmpoly_as_lwgeom(LWMPOLY *obj);
......@@ -602,6 +603,7 @@ extern int pointArray_ptsize(const POINTARRAY *pa);
#define WKBSRIDFLAG 0x20000000
#define WKBBBOXFLAG 0x10000000
/* These macros work on PG_LWGEOM.type, LWGEOM.type and all its subclasses */
#define TYPE_SETTYPE(c,t) ((c)=(((c)&0xF0)|(t)))
......
......@@ -342,6 +342,67 @@ LWGEOM *lwpoly_as_lwgeom(LWPOLY *obj) { return (LWGEOM *)obj; }
LWGEOM *lwline_as_lwgeom(LWLINE *obj) { return (LWGEOM *)obj; }
LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj) { return (LWGEOM *)obj; }
/*
** Look-up for the correct MULTI* type promotion for
** singleton types.
*/
static unsigned char MULTITYPE[16] = {
0,
MULTIPOINTTYPE,
MULTILINETYPE,
MULTIPOLYGONTYPE,
0,0,0,0,
MULTICURVETYPE,
MULTICURVETYPE,
0,0,0,
MULTISURFACETYPE,
0,0
};
/*
** Create a new LWGEOM of the appropriate MULTI* type.
*/
LWGEOM *
lwgeom_as_multi(LWGEOM *lwgeom)
{
LWGEOM **ogeoms;
LWGEOM *ogeom = NULL;
BOX2DFLOAT4 *box = NULL;
int type;
ogeoms = lwalloc(sizeof(LWGEOM*));
/*
** This funx is a no-op only if a bbox cache is already present
** in input.
*/
if ( lwgeom_contains_subgeoms(TYPE_GETTYPE(lwgeom->type)) )
{
return lwgeom_clone(lwgeom);
}
type = TYPE_GETTYPE(lwgeom->type);
if ( MULTITYPE[type] )
{
ogeoms[0] = lwgeom_clone(lwgeom);
/* Sub-geometries are not allowed to have bboxes or SRIDs, move the bbox to the collection */
box = ogeoms[0]->bbox;
ogeoms[0]->bbox = NULL;
ogeoms[0]->SRID = -1;
ogeom = (LWGEOM *)lwcollection_construct(MULTITYPE[type], lwgeom->SRID, box, 1, ogeoms);
}
else
{
return lwgeom_clone(lwgeom);
}
return ogeom;
}
void
lwgeom_release(LWGEOM *lwgeom)
{
......
......@@ -1491,47 +1491,29 @@ Datum LWGEOM_force_multi(PG_FUNCTION_ARGS)
{
PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
PG_LWGEOM *result;
LWGEOM *lwgeoms[1];
LWGEOM *lwgeom;
int type;
int SRID=-1;
BOX2DFLOAT4 *box;
LWGEOM *ogeom;
POSTGIS_DEBUG(2, "LWGEOM_force_multi called");
/*
* This funx is a no-op only if a bbox cache is already present
* in input. If bbox cache is not there we'll need to handle
* automatic bbox addition FOR_COMPLEX_GEOMS.
*/
if ( lwgeom_contains_subgeoms(TYPE_GETTYPE(geom->type)) &&
TYPE_HASBBOX(geom->type) )
** This funx is a no-op only if a bbox cache is already present
** in input. If bbox cache is not there we'll need to handle
** automatic bbox addition FOR_COMPLEX_GEOMS.
*/
if ( lwgeom_contains_subgeoms(TYPE_GETTYPE(geom->type)) && TYPE_HASBBOX(geom->type) )
{
PG_RETURN_POINTER(geom);
}
/* deserialize into lwgeoms[0] */
lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom));
type = TYPE_GETTYPE(lwgeom->type);
ogeom = lwgeom_as_multi(lwgeom);
printf("ogeom %p\n",ogeom);
printf("ogeom->type %d\n", ogeom->type);
/* if it's a single POINT, LINESTRING or POLYGON geom, make it a multi */
if ( type == POINTTYPE || type == LINETYPE || type == POLYGONTYPE )
{
type += 3;
SRID = lwgeom->SRID;
/* We transfer bbox ownership from input to output */
box = lwgeom->bbox;
lwgeom->SRID=-1;
lwgeom->bbox=NULL;
lwgeoms[0] = lwgeom;
lwgeom = (LWGEOM *)lwcollection_construct(type,
SRID, box, 1, lwgeoms);
}
result = pglwgeom_serialize(lwgeom);
lwgeom_release(lwgeom);
result = pglwgeom_serialize(ogeom);
PG_FREE_IF_COPY(geom, 0);
......
......@@ -244,7 +244,7 @@ select '142', ST_asewkt(ST_multi(ST_setsrid('LINESTRING(2 2, 3 3)'::geometry, 5)
select '142_', asewkt(multi(setsrid('LINESTRING(2 2, 3 3)'::geometry, 5)));
select '143', ST_asewkt(ST_multi(ST_setsrid('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'::geometry, 6)));
select '143_', asewkt(multi(setsrid('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'::geometry, 6)));
select '143c1', ST_asewkt(ST_multi('CIRCULARSTRING(0 0, 1 1, 2 2)'::geometry));
select '144', ST_asewkt(ST_force_3dm('POINT(1 2 3)'));
select '144_', asewkt(force_3dm('POINT(1 2 3)'));
select '145', ST_asewkt(ST_force_3dz('POINTM(1 2 3)'));
......
......@@ -169,6 +169,7 @@ HINT: "MULTIPOINT(1 1, 2 2" <-- parse error at position 19 within geometry
142_|SRID=5;MULTILINESTRING((2 2,3 3))
143|SRID=6;MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)))
143_|SRID=6;MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0)))
143c1|MULTICURVE(CIRCULARSTRING(0 0,1 1,2 2))
144|POINTM(1 2 0)
144_|POINTM(1 2 0)
145|POINT(1 2 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment