[postgis-commits] svn - r3817 - in trunk: liblwgeom postgis regress
postgis-commits at postgis.refractions.net
postgis-commits at postgis.refractions.net
Mon Mar 9 11:40:24 PDT 2009
Author: pramsey
Date: 2009-03-09 11:40:23 -0700 (Mon, 09 Mar 2009)
New Revision: 3817
Modified:
trunk/liblwgeom/liblwgeom.h
trunk/liblwgeom/lwgeom.c
trunk/postgis/lwgeom_functions_basic.c
trunk/regress/regress.sql
trunk/regress/regress_expected
Log:
Fix for GBT#96.
Modified: trunk/liblwgeom/liblwgeom.h
===================================================================
--- trunk/liblwgeom/liblwgeom.h 2009-03-09 17:19:54 UTC (rev 3816)
+++ trunk/liblwgeom/liblwgeom.h 2009-03-09 18:40:23 UTC (rev 3817)
@@ -453,6 +453,7 @@
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 @@
#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)))
Modified: trunk/liblwgeom/lwgeom.c
===================================================================
--- trunk/liblwgeom/lwgeom.c 2009-03-09 17:19:54 UTC (rev 3816)
+++ trunk/liblwgeom/lwgeom.c 2009-03-09 18:40:23 UTC (rev 3817)
@@ -342,6 +342,67 @@
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)
{
Modified: trunk/postgis/lwgeom_functions_basic.c
===================================================================
--- trunk/postgis/lwgeom_functions_basic.c 2009-03-09 17:19:54 UTC (rev 3816)
+++ trunk/postgis/lwgeom_functions_basic.c 2009-03-09 18:40:23 UTC (rev 3817)
@@ -1491,48 +1491,30 @@
{
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;
+ result = pglwgeom_serialize(ogeom);
- lwgeom = (LWGEOM *)lwcollection_construct(type,
- SRID, box, 1, lwgeoms);
- }
-
-
- result = pglwgeom_serialize(lwgeom);
- lwgeom_release(lwgeom);
-
PG_FREE_IF_COPY(geom, 0);
PG_RETURN_POINTER(result);
Modified: trunk/regress/regress.sql
===================================================================
--- trunk/regress/regress.sql 2009-03-09 17:19:54 UTC (rev 3816)
+++ trunk/regress/regress.sql 2009-03-09 18:40:23 UTC (rev 3817)
@@ -244,7 +244,7 @@
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)'));
Modified: trunk/regress/regress_expected
===================================================================
--- trunk/regress/regress_expected 2009-03-09 17:19:54 UTC (rev 3816)
+++ trunk/regress/regress_expected 2009-03-09 18:40:23 UTC (rev 3817)
@@ -169,6 +169,7 @@
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)
More information about the postgis-commits
mailing list