]> granicus.if.org Git - postgis/commitdiff
#3098, odd dimension mixes in WKT
authorPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 23 Apr 2015 22:56:23 +0000 (22:56 +0000)
committerPaul Ramsey <pramsey@cleverelephant.ca>
Thu, 23 Apr 2015 22:56:23 +0000 (22:56 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@13442 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/lwin_wkt.c

index b7262bcbb2d21f01b1f7f361bf07ec84912121e6..ee325030bca98700ec6fba4b198133ec285d3816 100644 (file)
@@ -96,55 +96,68 @@ static int wkt_parser_set_dims(LWGEOM *geom, uint8_t flags)
 
        FLAGS_SET_Z(geom->flags, hasz);
        FLAGS_SET_M(geom->flags, hasm);
-               
-       if( ! lwgeom_is_empty(geom) )
+       
+       switch( geom->type )
        {
-               if( geom->type == POINTTYPE )
+               case POINTTYPE:
                {
                        LWPOINT *pt = (LWPOINT*)geom;
-                       FLAGS_SET_Z(pt->point->flags, hasz);
-                       FLAGS_SET_M(pt->point->flags, hasm);
-                       return LW_SUCCESS;
+                       if ( pt->point )
+                       {
+                               FLAGS_SET_Z(pt->point->flags, hasz);
+                               FLAGS_SET_M(pt->point->flags, hasm);
+                       }
+                       break;
                }
-               else if ( (geom->type == TRIANGLETYPE) || 
-                         (geom->type == CIRCSTRINGTYPE) || 
-                         (geom->type == LINETYPE) )
+               case TRIANGLETYPE:
+               case CIRCSTRINGTYPE:
+               case LINETYPE:
                {
                        LWLINE *ln = (LWLINE*)geom;
-                       FLAGS_SET_Z(ln->points->flags, hasz);
-                       FLAGS_SET_M(ln->points->flags, hasm);
-                       return LW_SUCCESS;
+                       if ( ln->points )
+                       {
+                               FLAGS_SET_Z(ln->points->flags, hasz);
+                               FLAGS_SET_M(ln->points->flags, hasm);
+                       }
+                       break;
                }
-               else if ( geom->type == POLYGONTYPE )
+               case POLYGONTYPE:
                {
                        LWPOLY *poly = (LWPOLY*)geom;
                        for ( i = 0; i < poly->nrings; i++ )
                        {
-                               FLAGS_SET_Z(poly->rings[i]->flags, hasz);
-                               FLAGS_SET_M(poly->rings[i]->flags, hasm);
+                               if( poly->rings[i] )
+                               {
+                                       FLAGS_SET_Z(poly->rings[i]->flags, hasz);
+                                       FLAGS_SET_M(poly->rings[i]->flags, hasm);
+                               }
                        }
-                       return LW_SUCCESS;
+                       break;
                }
-               else if ( geom->type == CURVEPOLYTYPE )
+               case CURVEPOLYTYPE:
                {
                        LWCURVEPOLY *poly = (LWCURVEPOLY*)geom;
                        for ( i = 0; i < poly->nrings; i++ )
                                wkt_parser_set_dims(poly->rings[i], flags);
-                       return LW_SUCCESS;
+                       break;
                }
-               else if ( lwtype_is_collection(geom->type) )
+               default: 
                {
-                       LWCOLLECTION *col = (LWCOLLECTION*)geom;
-                       for ( i = 0; i < col->ngeoms; i++ )
-                               wkt_parser_set_dims(col->geoms[i], flags);                      
-                       return LW_SUCCESS;
+                       if ( lwtype_is_collection(geom->type) )
+                       {
+                               LWCOLLECTION *col = (LWCOLLECTION*)geom;
+                               for ( i = 0; i < col->ngeoms; i++ )
+                                       wkt_parser_set_dims(col->geoms[i], flags);                      
+                               return LW_SUCCESS;
+                       }
+                       else
+                       {
+                               LWDEBUGF(2,"Unknown geometry type: %d", geom->type);
+                               return LW_FAILURE;
+                       }
                }
-               else
-               {
-                       LWDEBUGF(2,"Unknown geometry type: %d", geom->type);
-                       return LW_FAILURE;
-               }       
        }
+
        return LW_SUCCESS;                              
 }
 
@@ -687,7 +700,7 @@ LWGEOM* wkt_parser_collection_new(LWGEOM *geom)
        geoms[0] = geom;
        
        /* Make a new collection */
-       col = lwcollection_construct(COLLECTIONTYPE, SRID_UNKNOWN, NULL, ngeoms, geoms); 
+       col = lwcollection_construct(COLLECTIONTYPE, SRID_UNKNOWN, NULL, ngeoms, geoms);
 
        /* Return the result. */
        return lwcollection_as_lwgeom(col);
@@ -736,26 +749,17 @@ LWGEOM* wkt_parser_collection_add_geom(LWGEOM *col, LWGEOM *geom)
                SET_PARSER_ERROR(PARSER_ERROR_OTHER);
                return NULL;
        }
-               
-       /* All the elements must agree on dimensionality */
-       if( FLAGS_NDIMS(col->flags) != FLAGS_NDIMS(geom->flags) )
-       {
-               lwgeom_free(col);
-               lwgeom_free(geom);
-               SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
-               return NULL;
-       }
-       
+                       
        return lwcollection_as_lwgeom(lwcollection_add_lwgeom(lwgeom_as_lwcollection(col), geom));
 }
 
-LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *col, char *dimensionality) 
+LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *geom, char *dimensionality) 
 {
        uint8_t flags = wkt_dimensionality(dimensionality);
        int flagdims = FLAGS_NDIMS(flags);
        
        /* No geometry means it is empty */
-       if( ! col )
+       if( ! geom )
        {
                return lwcollection_as_lwgeom(lwcollection_construct_empty(lwtype, SRID_UNKNOWN, FLAGS_GET_Z(flags), FLAGS_GET_M(flags)));
        }
@@ -763,37 +767,44 @@ LWGEOM* wkt_parser_collection_finalize(int lwtype, LWGEOM *col, char *dimensiona
        /* There are 'Z' or 'M' tokens in the signature */
        if ( flagdims > 2 )
        {
-               /* If the number of dimensions are not consistent, we have a problem. */
-               if( flagdims != FLAGS_NDIMS(col->flags) )
-               {
-                       lwgeom_free(col);
-                       SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
-                       return NULL;
-               }
-
-               /* For GEOMETRYCOLLECTION, the exact type of the dimensions must match too */
-               if( lwtype == COLLECTIONTYPE &&
-                   ( (FLAGS_GET_Z(flags) != FLAGS_GET_Z(col->flags)) ||
-                     (FLAGS_GET_M(flags) != FLAGS_GET_M(col->flags)) ) )
+               LWCOLLECTION *col = lwgeom_as_lwcollection(geom);
+               int i;
+               
+               for ( i = 0 ; i < col->ngeoms; i++ )
                {
-                       lwgeom_free(col);
-                       SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
-                       return NULL;
+                       LWGEOM *subgeom = col->geoms[i];
+                       if ( FLAGS_NDIMS(flags) != FLAGS_NDIMS(subgeom->flags) &&
+                                ! lwgeom_is_empty(subgeom) )
+                       {
+                               lwgeom_free(geom);
+                               SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
+                               return NULL;
+                       }
+                       
+                       if ( lwtype == COLLECTIONTYPE &&
+                          ( (FLAGS_GET_Z(flags) != FLAGS_GET_Z(subgeom->flags)) ||
+                            (FLAGS_GET_M(flags) != FLAGS_GET_M(subgeom->flags)) ) &&
+                               ! lwgeom_is_empty(subgeom) )
+                       {
+                               lwgeom_free(geom);
+                               SET_PARSER_ERROR(PARSER_ERROR_MIXDIMS);
+                               return NULL;
+                       }
                }
                
                /* Harmonize the collection dimensionality */
-               if( LW_FAILURE == wkt_parser_set_dims(col, flags) )
+               if( LW_FAILURE == wkt_parser_set_dims(geom, flags) )
                {
-                       lwgeom_free(col);
+                       lwgeom_free(geom);
                        SET_PARSER_ERROR(PARSER_ERROR_OTHER);
                        return NULL;
                }
        }
                
        /* Set the collection type */
-       col->type=lwtype;
+       geom->type = lwtype;
                        
-       return col;
+       return geom;
 }
 
 void wkt_parser_geometry_new(LWGEOM *geom, int srid)