[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