]> granicus.if.org Git - postgis/commitdiff
Fix some bugfixes. Handle EMPTY use cases. Minor changes. Related to #665
authorOlivier Courtin <olivier.courtin@camptocamp.com>
Tue, 7 Feb 2012 21:01:48 +0000 (21:01 +0000)
committerOlivier Courtin <olivier.courtin@camptocamp.com>
Tue, 7 Feb 2012 21:01:48 +0000 (21:01 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@9073 b70326c6-7e19-0410-871a-916f4a2858ee

liblwgeom/cunit/cu_surface.c
liblwgeom/libtgeom.c

index abc196f857291f9cbb6b55403cf86dcdaa58cd45..7033b34199146a662212e8e7a901402d20b2bda1 100644 (file)
@@ -3,7 +3,7 @@
  *
  * PostGIS - Spatial Types for PostgreSQL
  * http://postgis.refractions.net
- * Copyright 2010 Olivier Courtin <olivier.courtin@oslandia.com>
+ * Copyright 2010-2012 Olivier Courtin <olivier.courtin@oslandia.com>
  *
  * This is free software; you can redistribute and/or modify it under
  * the terms of the GNU General Public Licence. See the COPYING file.
@@ -84,11 +84,8 @@ void triangle_parse(void)
        /* EMPTY face */
        geom = lwgeom_from_wkt("TRIANGLE EMPTY", LW_PARSER_CHECK_NONE);
        CU_ASSERT_EQUAL(strlen(cu_error_msg), 0);
-       /*
-         NOTA: Theses 3 ASSERT results will change a day cf #294
-       */
        CU_ASSERT_EQUAL(geom->type, TRIANGLETYPE);
-//     CU_ASSERT_STRING_EQUAL("TRIANGLE EMPTY", lwgeom_to_wkt(geom, LW_PARSER_CHECK_NONE));
+       CU_ASSERT_STRING_EQUAL("TRIANGLE EMPTY", lwgeom_to_wkt(geom, LW_PARSER_CHECK_NONE, 0, 0));
        lwgeom_free(geom);
 
        /* explicit SRID */
@@ -121,13 +118,9 @@ void tin_parse(void)
        /* empty */
        geom = lwgeom_from_wkt("TIN EMPTY", LW_PARSER_CHECK_NONE);
        CU_ASSERT_EQUAL(strlen(cu_error_msg), 0);
-       /*
-         NOTA: Theses 3 ASSERT results will change a day cf #294
-       */
        CU_ASSERT_EQUAL(geom->type, TINTYPE);
-//     tmp = lwgeom_to_ewkt(geom);
-//     CU_ASSERT_STRING_EQUAL("TIN EMPTY", tmp);
-//     lwfree(tmp);
+       tmp = lwgeom_to_ewkt(geom);
+       CU_ASSERT_STRING_EQUAL("TIN EMPTY", tmp);
        lwgeom_free(geom);
 
        /* 2 dims */
@@ -193,11 +186,8 @@ void tin_parse(void)
        /* EMPTY face */
        geom = lwgeom_from_wkt("TIN EMPTY", LW_PARSER_CHECK_NONE);
        CU_ASSERT_EQUAL(strlen(cu_error_msg), 0);
-       /*
-         NOTA: Theses 3 ASSERT results will change a day cf #294
-       */
        CU_ASSERT_EQUAL(geom->type, TINTYPE);
-//     CU_ASSERT_STRING_EQUAL("GEOMETRYCOLLECTION EMPTY", lwgeom_to_ewkt(geom));
+       CU_ASSERT_STRING_EQUAL("TIN EMPTY", lwgeom_to_ewkt(geom));
        lwgeom_free(geom);
 
        /* A simple tetrahedron */
@@ -268,7 +258,7 @@ check_tgeom(char *ewkt, int type, uint32_t srid, int is_solid)
        g2 = lwgeom_from_tgeom(tgeom);
        if (!lwgeom_same(g1, g2))
        {
-               printf("\n[%s]\n, lwgeom_same I", ewkt);
+               printf("\n[%s]\nlwgeom_same I\n", ewkt);
                printTGEOM(tgeom);
                if (type == TINTYPE)
                {
@@ -282,14 +272,17 @@ check_tgeom(char *ewkt, int type, uint32_t srid, int is_solid)
                }
        }
        CU_ASSERT(lwgeom_same(g1, g2));
-       lwgeom_free(g2);
 
+       lwgeom_free(g2);
        tser = tgeom_serialize(tgeom);
        tgeom2 = tgeom_deserialize(tser);
+       lwfree(tser);
        g2 = lwgeom_from_tgeom(tgeom2);
+       tgeom_free(tgeom2);
+
        if (!lwgeom_same(g1, g2))
        {
-               printf("\n[%s]\n, lwgeom_same II", ewkt);
+               printf("\n[%s]\n, lwgeom_same II\n", ewkt);
                printTGEOM(tgeom);
                if (type == TINTYPE)
                {
@@ -303,11 +296,10 @@ check_tgeom(char *ewkt, int type, uint32_t srid, int is_solid)
                }
        }
        CU_ASSERT(lwgeom_same(g1, g2));
-       lwfree(tser);
-       tgeom_free(tgeom2);
+
+       lwgeom_free(g1);
        lwgeom_free(g2);
        tgeom_free(tgeom);
-       lwgeom_free(g1);
 }
 
 
@@ -324,8 +316,6 @@ void polyhedralsurface_parse(void)
        CU_ASSERT_EQUAL(strlen(cu_error_msg), 0);
        CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE);
        tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0);
-//     printf("%s\n",tmp);
-//     printf("010D00000001000000010300000001000000040000000000000000000000000000000000F03F00000000000000400000000000000840000000000000104000000000000014400000000000000000000000000000F03F\n");
        CU_ASSERT_STRING_EQUAL("010F00000001000000010300000001000000040000000000000000000000000000000000F03F00000000000000400000000000000840000000000000104000000000000014400000000000000000000000000000F03F", tmp);
        lwfree(tmp);
        tmp = lwgeom_to_ewkt(geom);
@@ -390,12 +380,9 @@ void polyhedralsurface_parse(void)
        /* EMPTY face */
        geom = lwgeom_from_wkt("POLYHEDRALSURFACE EMPTY", LW_PARSER_CHECK_NONE);
        CU_ASSERT_EQUAL(strlen(cu_error_msg), 0);
-       /*
-         NOTA: Theses 3 ASSERT results will change a day cf #294
-       */
        CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE);
-//     CU_ASSERT_STRING_EQUAL("010700000000000000", lwgeom_to_wkb(geom, WKB_HEX | WKB_ISO | WKB_NDR, 0));
-//     CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE EMPTY", lwgeom_to_ewkt(geom));
+       CU_ASSERT_STRING_EQUAL("010F00000000000000", lwgeom_to_wkb(geom, WKB_HEX | WKB_ISO | WKB_NDR, 0));
+       CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE EMPTY", lwgeom_to_ewkt(geom));
        lwgeom_free(geom);
 
        /* A simple tetrahedron */
@@ -451,6 +438,9 @@ void polyhedralsurface_parse(void)
 void
 tin_tgeom(void)
 {
+       /* EMPTY TIN */
+       check_tgeom("TIN EMPTY", TINTYPE, 0, 0);
+
        /* 2D a single face */
        check_tgeom("TIN(((0 0,0 1,1 1,0 0)))", TINTYPE, 0, 0);
 
@@ -465,19 +455,15 @@ tin_tgeom(void)
 
        /* 3D a simple polyhedron with SRID */
        check_tgeom("SRID=4326;TIN(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", TINTYPE, 4326, 1);
-
-#if 0
-       /* EMPTY TIN */
-       /* NOTA: This ASSERT type will change a day cf #294 */
-       check_tgeom("TIN EMPTY", COLLECTIONTYPE, 0, 0);
-       cu_error_msg_reset();
-#endif
 }
 
 
 void
 psurface_tgeom(void)
 {
+       /* EMPTY POLYHEDRALSURFACE */
+       check_tgeom("POLYHEDRALSURFACE EMPTY", POLYHEDRALSURFACETYPE, 0, 0);
+
        /* 2D a single face */
        check_tgeom("POLYHEDRALSURFACE(((0 0,0 1,1 1,0 0)))", POLYHEDRALSURFACETYPE, 0, 0);
 
@@ -496,12 +482,6 @@ psurface_tgeom(void)
        /* 4D a simple polyhedron */
        check_tgeom("POLYHEDRALSURFACE(((0 0 0 1,0 0 1 2,0 1 0 3,0 0 0 1)),((0 0 0 4,0 1 0 5,1 0 0 6,0 0 0 4)),((0 0 0 7,1 0 0 8,0 0 1 9,0 0 0 7)),((1 0 0 10,0 1 0 11,0 0 1 12,1 0 0 10)))", POLYHEDRALSURFACETYPE, 0, 0);
 
-#if 0
-       /* EMPTY POLYHEDRALSURFACE */
-       /* NOTA: This ASSERT type will change a day cf #294 */
-       check_tgeom("POLYHEDRALSURFACE EMPTY", COLLECTIONTYPE, 0, 0);
-       cu_error_msg_reset();
-
        /* 2D single face with one internal ring */
        check_tgeom("POLYHEDRALSURFACE(((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7)))", POLYHEDRALSURFACETYPE, 0, 0);
 
@@ -510,9 +490,6 @@ psurface_tgeom(void)
 
        /* 4D single face with two internal rings */
        check_tgeom("POLYHEDRALSURFACE(((0 1 2 3,4 5 6 7,8 9 10 11,0 1 2 3),(12 13 14 15,16 17 18 19,20 21 22 23,12 13 14 15),(16 17 18 19,20 21 22 23,24 25 26 27,16 17 18 19)))", POLYHEDRALSURFACETYPE, 0, 0);
-#endif
-
-
 }
 
 
index 574b503c6d092f26f23d3d93010e4ecaf90fdb53..27cc1d39120be7a6c78963b1ec465337eca1ece1 100644 (file)
@@ -3,7 +3,7 @@
  *
  * PostGIS - Spatial Types for PostgreSQL
  * http://postgis.refractions.net
- * Copyright 2010 Olivier Courtin <olivier.courtin@oslandia.com>
+ * Copyright 2010-2012 Olivier Courtin <olivier.courtin@oslandia.com>
  *
  * This is free software; you can redistribute and/or modify it under
  * the terms of the GNU General Public Licence. See the COPYING file.
@@ -149,8 +149,7 @@ tgeom_add_face_edge(TGEOM *tgeom, int face_id, POINT4D *s, POINT4D *e)
        if (edge_id)
        {
                tgeom->edges[abs(edge_id)]->count++;
-               LWDEBUGF(3, "face [%i] Founded Edge: %i\n",
-                        face_id, edge_id);
+               LWDEBUGF(3, "face [%i] Founded Edge: %i\n", face_id, edge_id);
        }
        else
        {
@@ -163,7 +162,7 @@ tgeom_add_face_edge(TGEOM *tgeom, int face_id, POINT4D *s, POINT4D *e)
                        tgeom->edges = (TEDGE**) lwalloc(sizeof(TEDGE*) * 4);
                        tgeom->maxedges = 4;
                }
-               if (tgeom->maxedges >= (tgeom->nedges + 1))
+               if (tgeom->maxedges <= (tgeom->nedges + 1))
                {
                        tgeom->edges = (TEDGE **) lwrealloc(tgeom->edges,
                                                 sizeof(TEDGE*) * tgeom->maxedges * 2);
@@ -188,15 +187,15 @@ tgeom_add_face_edge(TGEOM *tgeom, int face_id, POINT4D *s, POINT4D *e)
                tgeom->faces[face_id]->edges = (int *) lwalloc(sizeof(int) * 4);
                tgeom->faces[face_id]->maxedges = 4;
        }
-       if (tgeom->faces[face_id]->maxedges == nedges)
+       if (tgeom->faces[face_id]->maxedges <= nedges +1)
        {
                tgeom->faces[face_id]->edges = (int *) lwrealloc(tgeom->faces[face_id]->edges,
                                               sizeof(int) * tgeom->faces[face_id]->maxedges * 2);
                tgeom->faces[face_id]->maxedges *= 2;
        }
 
-       LWDEBUGF(3, "face [%i] add %i in edge array in %i pos\n",
-                face_id, edge_id, tgeom->faces[face_id]->nedges);
+       LWDEBUGF(3, "face [%i] add %i in edge array in %i pos\n", face_id, edge_id, tgeom->faces[face_id]->nedges);
+
 
        tgeom->faces[face_id]->edges[nedges]= edge_id;
        tgeom->faces[face_id]->nedges++;
@@ -272,8 +271,7 @@ tgeom_add_polygon(TGEOM *tgeom, LWPOLY *poly)
 
        /* clone internal rings */
        for (i=0 ; i < tgeom->faces[tgeom->nfaces]->nrings ; i++)
-               tgeom->faces[tgeom->nfaces]->rings[i]
-               = ptarray_clone_deep(poly->rings[i+1]);
+               tgeom->faces[tgeom->nfaces]->rings[i] = ptarray_clone_deep(poly->rings[i+1]);
 
        tgeom->nfaces++;
 
@@ -315,7 +313,7 @@ tgeom_add_triangle(TGEOM *tgeom, LWTRIANGLE *triangle)
                tgeom->faces = lwalloc(sizeof(TFACE*) * 2);
                tgeom->maxfaces = 2;
        }
-       if ((tgeom->maxfaces - 1) == tgeom->nfaces)
+       if ((tgeom->maxfaces - 1) <= tgeom->nfaces)
        {
                tgeom->faces = lwrealloc(tgeom->faces,
                                         sizeof(TFACE*) * tgeom->maxfaces * 2);
@@ -363,9 +361,9 @@ tgeom_free(TGEOM *tgeom)
        /* edges */
        for (i=1 ; i <= tgeom->nedges ; i++)
        {
-               lwfree(tgeom->edges[i]->e);
-               lwfree(tgeom->edges[i]->s);
-               lwfree(tgeom->edges[i]);
+               if (tgeom->edges[i]->e) lwfree(tgeom->edges[i]->e);
+               if (tgeom->edges[i]->s) lwfree(tgeom->edges[i]->s);
+               if (tgeom->edges[i])    lwfree(tgeom->edges[i]);
        }
        if (tgeom->edges) lwfree(tgeom->edges);
 
@@ -384,7 +382,7 @@ tgeom_free(TGEOM *tgeom)
 
                lwfree(tgeom->faces[i]);
        }
-       if (tgeom->faces) lwfree(tgeom->faces);
+       if (tgeom->nfaces) lwfree(tgeom->faces);
 
        lwfree(tgeom);
 }
@@ -419,7 +417,6 @@ tgeom_from_lwgeom(const LWGEOM *lwgeom)
        if (lwgeom->srid < 1) tgeom->srid = SRID_UNKNOWN;
        else tgeom->srid = lwgeom->srid;
 
-       if (lwgeom_is_empty(lwgeom)) return tgeom;
 
        switch (lwgeom->type)
        {
@@ -428,8 +425,7 @@ tgeom_from_lwgeom(const LWGEOM *lwgeom)
                tin = (LWTIN *) lwgeom;
 
                for (i=0 ; i < tin->ngeoms ; i++)
-                       tgeom = tgeom_add_triangle(tgeom,
-                                                  (LWTRIANGLE *) tin->geoms[i]);
+                       tgeom = tgeom_add_triangle(tgeom, (LWTRIANGLE *) tin->geoms[i]);
 
                break;
 
@@ -437,8 +433,7 @@ tgeom_from_lwgeom(const LWGEOM *lwgeom)
                tgeom->type = POLYHEDRALSURFACETYPE;
                psurf = (LWPSURFACE *) lwgeom;
                for (i=0 ; i < psurf->ngeoms ; i++)
-                       tgeom = tgeom_add_polygon(tgeom,
-                                                 (LWPOLY *) psurf->geoms[i]);
+                       tgeom = tgeom_add_polygon(tgeom, (LWPOLY *) psurf->geoms[i]);
 
                break;
 
@@ -449,7 +444,7 @@ tgeom_from_lwgeom(const LWGEOM *lwgeom)
                        tgeom->type, lwtype_name(tgeom->type));
        }
 
-
+       if (lwgeom_is_empty(lwgeom)) return tgeom; /* empty is not a solid */
 
        for (solid=1, i=1 ; i <= tgeom->nedges ; i++)
        {
@@ -514,6 +509,7 @@ lwgeom_from_tgeom(TGEOM *tgeom)
                        FLAGS_SET_Z(dims, hasz?1:0);
                        FLAGS_SET_M(dims, hasm?1:0);
                        dpa = ptarray_construct_empty(hasz, hasm, 4);
+                       FLAGS_SET_READONLY(dpa->flags, 0);
 
                        for (j=0 ; j < tgeom->faces[i]->nedges ; j++)
                        {
@@ -569,7 +565,7 @@ lwgeom_from_tgeom(TGEOM *tgeom)
                                      * (tgeom->faces[i]->nrings + 1));
                        ppa[0] = dpa;
                        for (k=0; k < tgeom->faces[i]->nrings ; k++)
-                               ppa[k+1] = tgeom->faces[i]->rings[k];
+                               ppa[k+1] = ptarray_clone_deep(tgeom->faces[i]->rings[k]);
 
                        geom = (LWGEOM *) lwpsurface_add_lwpoly((LWPSURFACE *) geom,
                                                                lwpoly_construct(tgeom->srid, NULL, k + 1, ppa));
@@ -1009,8 +1005,8 @@ printTGEOM(TGEOM *tgeom)
        printf("TGEOM:\n");
        printf(" - type %i, %s\n", tgeom->type, lwtype_name(tgeom->type));
        printf(" - srid %i\n", tgeom->srid);
-       printf(" - nedges %i\n", tgeom->nedges);
-       printf(" - nfaces %i\n", tgeom->nfaces);
+       printf(" - nedges %i (max:%i)\n", tgeom->nedges, tgeom->maxedges);
+       printf(" - nfaces %i (max:%i)\n", tgeom->nfaces, tgeom->maxfaces);
        printf("  => EDGES:\n");
 
        for (i=1 ; i <= tgeom->nedges ; i++)
@@ -1112,7 +1108,7 @@ printTGEOM(TGEOM *tgeom)
 
                for (j=0 ; j < tgeom->faces[i]->nrings ; j++)
                {
-                       printf("    - Ring[%i/%i]", j, tgeom->faces[i]->nrings);
+                       printf("    - Ring[%i/%i]", j+1, tgeom->faces[i]->nrings);
                        printPA(tgeom->faces[i]->rings[j]);
                }
        }