From 3194a27c1b4d7f981d1800ece4adea4f25b46e2d Mon Sep 17 00:00:00 2001 From: Olivier Courtin Date: Tue, 7 Feb 2012 21:01:48 +0000 Subject: [PATCH] Fix some bugfixes. Handle EMPTY use cases. Minor changes. Related to #665 git-svn-id: http://svn.osgeo.org/postgis/trunk@9073 b70326c6-7e19-0410-871a-916f4a2858ee --- liblwgeom/cunit/cu_surface.c | 65 ++++++++++++------------------------ liblwgeom/libtgeom.c | 44 +++++++++++------------- 2 files changed, 41 insertions(+), 68 deletions(-) diff --git a/liblwgeom/cunit/cu_surface.c b/liblwgeom/cunit/cu_surface.c index abc196f85..7033b3419 100644 --- a/liblwgeom/cunit/cu_surface.c +++ b/liblwgeom/cunit/cu_surface.c @@ -3,7 +3,7 @@ * * PostGIS - Spatial Types for PostgreSQL * http://postgis.refractions.net - * Copyright 2010 Olivier Courtin + * Copyright 2010-2012 Olivier Courtin * * 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 - - } diff --git a/liblwgeom/libtgeom.c b/liblwgeom/libtgeom.c index 574b503c6..27cc1d391 100644 --- a/liblwgeom/libtgeom.c +++ b/liblwgeom/libtgeom.c @@ -3,7 +3,7 @@ * * PostGIS - Spatial Types for PostgreSQL * http://postgis.refractions.net - * Copyright 2010 Olivier Courtin + * Copyright 2010-2012 Olivier Courtin * * 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]); } } -- 2.40.0