Changeset 3817

Show
Ignore:
Timestamp:
03/09/09 11:40:23 (3 years ago)
Author:
pramsey
Message:

Fix for GBT#96.

Location:
trunk
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • trunk/liblwgeom/liblwgeom.h

    r3814 r3817  
    454454extern LWPOINT *lwgeom_as_lwpoint(LWGEOM *lwgeom); 
    455455extern LWCIRCSTRING *lwgeom_as_lwcircstring(LWGEOM *lwgeom); 
     456extern LWGEOM *lwgeom_as_multi(LWGEOM *lwgeom); 
    456457 
    457458/* Casts LW*->LWGEOM (always cast) */ 
     
    602603#define WKBSRIDFLAG 0x20000000 
    603604#define WKBBBOXFLAG 0x10000000 
     605 
    604606 
    605607/* These macros work on PG_LWGEOM.type, LWGEOM.type and all its subclasses */ 
  • trunk/liblwgeom/lwgeom.c

    r3814 r3817  
    343343LWGEOM *lwpoint_as_lwgeom(LWPOINT *obj) { return (LWGEOM *)obj; } 
    344344 
     345 
     346/*  
     347** Look-up for the correct MULTI* type promotion for 
     348** singleton types. 
     349*/ 
     350static unsigned char MULTITYPE[16] = { 
     351        0, 
     352        MULTIPOINTTYPE, 
     353        MULTILINETYPE, 
     354        MULTIPOLYGONTYPE, 
     355        0,0,0,0, 
     356        MULTICURVETYPE, 
     357        MULTICURVETYPE, 
     358        0,0,0, 
     359        MULTISURFACETYPE, 
     360        0,0 
     361}; 
     362 
     363/* 
     364** Create a new LWGEOM of the appropriate MULTI* type. 
     365*/ 
     366LWGEOM * 
     367lwgeom_as_multi(LWGEOM *lwgeom) 
     368{ 
     369        LWGEOM **ogeoms; 
     370        LWGEOM *ogeom = NULL; 
     371        BOX2DFLOAT4 *box = NULL; 
     372        int type; 
     373 
     374        ogeoms = lwalloc(sizeof(LWGEOM*)); 
     375 
     376        /* 
     377        ** This funx is a no-op only if a bbox cache is already present 
     378        ** in input.  
     379        */ 
     380        if ( lwgeom_contains_subgeoms(TYPE_GETTYPE(lwgeom->type)) ) 
     381        { 
     382                return lwgeom_clone(lwgeom); 
     383        } 
     384 
     385        type = TYPE_GETTYPE(lwgeom->type); 
     386 
     387        if ( MULTITYPE[type] ) 
     388        { 
     389                ogeoms[0] = lwgeom_clone(lwgeom); 
     390 
     391                /* Sub-geometries are not allowed to have bboxes or SRIDs, move the bbox to the collection */ 
     392                box = ogeoms[0]->bbox; 
     393                ogeoms[0]->bbox = NULL; 
     394                ogeoms[0]->SRID = -1; 
     395                         
     396                ogeom = (LWGEOM *)lwcollection_construct(MULTITYPE[type], lwgeom->SRID, box, 1, ogeoms); 
     397        } 
     398        else  
     399        { 
     400                return lwgeom_clone(lwgeom); 
     401        } 
     402 
     403        return ogeom; 
     404} 
     405 
    345406void 
    346407lwgeom_release(LWGEOM *lwgeom) 
  • trunk/postgis/lwgeom_functions_basic.c

    r3814 r3817  
    14921492        PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); 
    14931493        PG_LWGEOM *result; 
    1494         LWGEOM *lwgeoms[1]; 
    14951494        LWGEOM *lwgeom; 
    1496         int type; 
    1497         int SRID=-1; 
    1498         BOX2DFLOAT4 *box; 
     1495        LWGEOM *ogeom; 
    14991496 
    15001497        POSTGIS_DEBUG(2, "LWGEOM_force_multi called"); 
    15011498 
    15021499        /* 
    1503          * This funx is a no-op only if a bbox cache is already present 
    1504          * in input. If bbox cache is not there we'll need to handle 
    1505          * automatic bbox addition FOR_COMPLEX_GEOMS. 
    1506          */ 
    1507         if ( lwgeom_contains_subgeoms(TYPE_GETTYPE(geom->type)) && 
    1508                         TYPE_HASBBOX(geom->type) ) 
     1500        ** This funx is a no-op only if a bbox cache is already present 
     1501        ** in input. If bbox cache is not there we'll need to handle 
     1502        ** automatic bbox addition FOR_COMPLEX_GEOMS. 
     1503        */ 
     1504        if ( lwgeom_contains_subgeoms(TYPE_GETTYPE(geom->type)) && TYPE_HASBBOX(geom->type) ) 
    15091505        { 
    15101506                PG_RETURN_POINTER(geom); 
    15111507        } 
     1508 
    15121509 
    15131510        /* deserialize into lwgeoms[0] */ 
    15141511        lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom)); 
    1515         type = TYPE_GETTYPE(lwgeom->type); 
    1516  
    1517         /* if it's a single POINT, LINESTRING or POLYGON geom, make it a multi */ 
    1518         if ( type == POINTTYPE || type == LINETYPE || type == POLYGONTYPE ) 
    1519         { 
    1520                 type += 3; 
    1521                 SRID = lwgeom->SRID; 
    1522                 /* We transfer bbox ownership from input to output */ 
    1523                 box = lwgeom->bbox; 
    1524                 lwgeom->SRID=-1; 
    1525                 lwgeom->bbox=NULL; 
    1526                 lwgeoms[0] = lwgeom; 
    1527  
    1528                 lwgeom = (LWGEOM *)lwcollection_construct(type, 
    1529                                 SRID, box, 1, lwgeoms); 
    1530         } 
    1531  
    1532  
    1533         result = pglwgeom_serialize(lwgeom); 
    1534         lwgeom_release(lwgeom); 
     1512        ogeom = lwgeom_as_multi(lwgeom); 
     1513                printf("ogeom %p\n",ogeom); 
     1514                printf("ogeom->type %d\n", ogeom->type); 
     1515 
     1516        result = pglwgeom_serialize(ogeom); 
    15351517 
    15361518        PG_FREE_IF_COPY(geom, 0); 
  • trunk/regress/regress_expected

    r3373 r3817  
    170170143|SRID=6;MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0))) 
    171171143_|SRID=6;MULTIPOLYGON(((0 0,1 0,1 1,0 1,0 0))) 
     172143c1|MULTICURVE(CIRCULARSTRING(0 0,1 1,2 2)) 
    172173144|POINTM(1 2 0) 
    173174144_|POINTM(1 2 0) 
  • trunk/regress/regress.sql

    r2616 r3817  
    245245select '143', ST_asewkt(ST_multi(ST_setsrid('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'::geometry, 6))); 
    246246select '143_', asewkt(multi(setsrid('POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'::geometry, 6))); 
    247  
     247select '143c1', ST_asewkt(ST_multi('CIRCULARSTRING(0 0, 1 1, 2 2)'::geometry)); 
    248248select '144', ST_asewkt(ST_force_3dm('POINT(1 2 3)')); 
    249249select '144_', asewkt(force_3dm('POINT(1 2 3)'));