From: Olivier Courtin Date: Mon, 25 Mar 2013 18:41:48 +0000 (+0000) Subject: Related to #1553. Add missing free in cu_surface cunit to be valgrind clean. As TGEOM... X-Git-Tag: 2.1.0beta2~145 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f7c75179718dab34e00977dbc299cbad1f602a43;p=postgis Related to #1553. Add missing free in cu_surface cunit to be valgrind clean. As TGEOM was not used as storage serialization, i purely remove TGEOM for now, and kept only the TIN/POLYHEDRALSURFACE lwgeom expression (will see in future if we really need to have a 3D topological storage PostGIS side) git-svn-id: http://svn.osgeo.org/postgis/trunk@11205 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/liblwgeom/Makefile.in b/liblwgeom/Makefile.in index 7ee6bd2ef..f88fee4cd 100644 --- a/liblwgeom/Makefile.in +++ b/liblwgeom/Makefile.in @@ -76,7 +76,6 @@ SA_OBJS = \ lwgeodetic.o \ lwgeodetic_tree.o \ lwtree.o \ - libtgeom.o \ lwout_gml.o \ lwout_kml.o \ lwout_geojson.o \ @@ -99,7 +98,6 @@ LT_OBJS = $(LT_SA_OBJS) $(LT_NM_OBJS) SA_HEADERS = \ liblwgeom.h \ liblwgeom_internal.h \ - libtgeom.h \ lwgeom_log.h \ lwgeom_geos.h diff --git a/liblwgeom/cunit/cu_surface.c b/liblwgeom/cunit/cu_surface.c index 56416c625..59d5dfb69 100644 --- a/liblwgeom/cunit/cu_surface.c +++ b/liblwgeom/cunit/cu_surface.c @@ -85,7 +85,9 @@ void triangle_parse(void) geom = lwgeom_from_wkt("TRIANGLE EMPTY", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TRIANGLETYPE); - CU_ASSERT_STRING_EQUAL("TRIANGLE EMPTY", lwgeom_to_wkt(geom, LW_PARSER_CHECK_NONE, 0, 0)); + tmp = lwgeom_to_wkt(geom, LW_PARSER_CHECK_NONE, 0, 0); + CU_ASSERT_STRING_EQUAL("TRIANGLE EMPTY", tmp); + lwfree(tmp); lwgeom_free(geom); /* explicit SRID */ @@ -121,6 +123,7 @@ void tin_parse(void) CU_ASSERT_EQUAL(geom->type, TINTYPE); tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("TIN EMPTY", tmp); + lwfree(tmp); lwgeom_free(geom); /* 2 dims */ @@ -187,7 +190,9 @@ void tin_parse(void) geom = lwgeom_from_wkt("TIN EMPTY", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, TINTYPE); - CU_ASSERT_STRING_EQUAL("TIN EMPTY", lwgeom_to_ewkt(geom)); + tmp = lwgeom_to_ewkt(geom); + CU_ASSERT_STRING_EQUAL("TIN EMPTY", tmp); + lwfree(tmp); lwgeom_free(geom); /* A simple tetrahedron */ @@ -230,80 +235,6 @@ void tin_parse(void) } -static void -check_tgeom(char *ewkt, int type, uint32_t srid, int is_solid) -{ - LWGEOM *g1, *g2; - TGEOM *tgeom, *tgeom2; - TSERIALIZED *tser; - - g1 = lwgeom_from_wkt(ewkt, LW_PARSER_CHECK_NONE); - if (strlen(cu_error_msg)) printf("\n[%s], %s\n", ewkt, cu_error_msg); - CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); - - if (g1->type != type) - printf("\n[%s], TYPE %s\n", ewkt, lwtype_name(g1->type)); - CU_ASSERT_EQUAL(g1->type, type); - tgeom = tgeom_from_lwgeom(g1); - - if (srid != tgeom->srid) - printf("\n[%s], srid %i / %i\n", ewkt, srid, tgeom->srid); - CU_ASSERT_EQUAL(srid, tgeom->srid); - - if (FLAGS_GET_SOLID(tgeom->flags) != is_solid) - printf("\n[%s], solid %i / %i\n", ewkt, - FLAGS_GET_SOLID(tgeom->flags), is_solid); - CU_ASSERT_EQUAL(FLAGS_GET_SOLID(tgeom->flags), is_solid); - - g2 = lwgeom_from_tgeom(tgeom); - if (!lwgeom_same(g1, g2)) - { - printf("\n[%s]\nlwgeom_same I\n", ewkt); - printTGEOM(tgeom); - if (type == TINTYPE) - { - printLWTIN((LWTIN *)g1); - printLWTIN((LWTIN *)g2); - } - else - { - printLWPSURFACE((LWPSURFACE *)g1); - printLWPSURFACE((LWPSURFACE *)g2); - } - } - CU_ASSERT(lwgeom_same(g1, 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\n", ewkt); - printTGEOM(tgeom); - printTGEOM(tgeom2); - if (type == TINTYPE) - { - printLWTIN((LWTIN *)g1); - printLWTIN((LWTIN *)g2); - } - else - { - printLWPSURFACE((LWPSURFACE *)g1); - printLWPSURFACE((LWPSURFACE *)g2); - } - } - CU_ASSERT(lwgeom_same(g1, g2)); - - lwgeom_free(g1); - lwgeom_free(g2); - tgeom_free(tgeom); -} - - void polyhedralsurface_parse(void) { LWGEOM *geom; @@ -382,8 +313,12 @@ void polyhedralsurface_parse(void) geom = lwgeom_from_wkt("POLYHEDRALSURFACE EMPTY", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); - 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)); + tmp = lwgeom_to_wkb(geom, WKB_HEX | WKB_ISO | WKB_NDR, 0); + CU_ASSERT_STRING_EQUAL("010F00000000000000", tmp); + lwfree(tmp); + tmp = lwgeom_to_ewkt(geom); + CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE EMPTY", tmp); + lwfree(tmp); lwgeom_free(geom); /* A simple tetrahedron */ @@ -436,63 +371,6 @@ void polyhedralsurface_parse(void) lwfree(g); } -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); - - /* 3DM a single face */ - check_tgeom("TINM(((0 1 2,3 4 5,6 7 8,0 1 2)))", TINTYPE, 0, 0); - - /* 4D a single face */ - check_tgeom("TIN(((0 1 2 3,4 5 6 7,8 9 10 11,0 1 2 3)))", TINTYPE, 0, 0); - - /* 3D a simple polyhedron */ - check_tgeom("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, 0, 1); - - /* 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); -} - - -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); - - /* 3DM a single face */ - check_tgeom("POLYHEDRALSURFACEM(((0 1 2,3 4 5,6 7 8,0 1 2)))", POLYHEDRALSURFACETYPE, 0, 0); - - /* 4D a single face */ - check_tgeom("POLYHEDRALSURFACE(((0 1 2 3,4 5 6 7,8 9 10 11,0 1 2 3)))", POLYHEDRALSURFACETYPE, 0, 0); - - /* 3D a simple polyhedron */ - check_tgeom("POLYHEDRALSURFACE(((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)))", POLYHEDRALSURFACETYPE, 0, 1); - - /* 3D a simple polyhedron with SRID */ - check_tgeom("SRID=4326;POLYHEDRALSURFACE(((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)))", POLYHEDRALSURFACETYPE, 4326, 1); - - /* 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); - - /* 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); - - /* 2D single face with two internal rings */ - check_tgeom("POLYHEDRALSURFACE(((0 1,2 3,4 5,0 1),(6 7,8 9,10 11,6 7),(12 13,14 15,16 17,12 13)))", POLYHEDRALSURFACETYPE, 0, 0); - - /* 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); -} - static void check_dimension(char *ewkt, int dim) @@ -522,40 +400,6 @@ surface_dimension(void) } -static void -check_perimeter(char *ewkt, int dim, double p) -{ - LWGEOM *geom; - TGEOM *tgeom; - - geom = lwgeom_from_wkt(ewkt, LW_PARSER_CHECK_NONE); - CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); - tgeom = tgeom_from_lwgeom(geom); - - if (dim == 2) CU_ASSERT_DOUBLE_EQUAL(tgeom_perimeter2d(tgeom), p, 0.01); - if (dim == 3) CU_ASSERT_DOUBLE_EQUAL(tgeom_perimeter(tgeom), p, 0.01); - - tgeom_free(tgeom); - lwgeom_free(geom); -} - -void -surface_perimeter(void) -{ - /* 2D single face */ - check_perimeter("POLYHEDRALSURFACE(((0 0,0 1,1 1,0 0)))", 2, 3.4142); - check_perimeter("TIN(((0 0,0 1,1 1,0 0)))", 2, 3.4142); - - /* 3D single face */ - check_perimeter("POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)))", 3, 3.4142); - check_perimeter("TIN(((0 0 0,0 0 1,0 1 0,0 0 0)))", 3, 3.4142); - - /* 3D Tetrahedron */ - check_perimeter("POLYHEDRALSURFACE(((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)))", 3, 0.0); - check_perimeter("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)))", 3, 0.0); -} - - /* ** Used by test harness to register the tests in this file. */ @@ -567,10 +411,7 @@ CU_TestInfo surface_tests[] = PG_TEST(triangle_parse), PG_TEST(tin_parse), PG_TEST(polyhedralsurface_parse), - PG_TEST(tin_tgeom), - PG_TEST(psurface_tgeom), PG_TEST(surface_dimension), - PG_TEST(surface_perimeter), CU_TEST_INFO_NULL }; CU_SuiteInfo surface_suite = {"surface", NULL, NULL, surface_tests}; diff --git a/liblwgeom/cunit/cu_surface.h b/liblwgeom/cunit/cu_surface.h index 549905980..1ea849246 100644 --- a/liblwgeom/cunit/cu_surface.h +++ b/liblwgeom/cunit/cu_surface.h @@ -16,14 +16,10 @@ #include "CUnit/Basic.h" #include "liblwgeom_internal.h" -#include "libtgeom.h" #include "cu_tester.h" /* Test functions */ void triangle_parse(void); void tin_parse(void); void polyhedralsurface_parse(void); -void tin_tgeom(void); -void psurface_tgeom(void); void surface_dimension(void); -void surface_perimeter(void); diff --git a/liblwgeom/libtgeom.c b/liblwgeom/libtgeom.c deleted file mode 100644 index e575919ba..000000000 --- a/liblwgeom/libtgeom.c +++ /dev/null @@ -1,1179 +0,0 @@ -/********************************************************************** - * $Id:$ - * - * PostGIS - Spatial Types for PostgreSQL - * http://postgis.refractions.net - * 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. - * - **********************************************************************/ - -#include -#include -#include - -#include "liblwgeom_internal.h" -#include "lwgeom_log.h" -#include "libtgeom.h" - - -/* - * Create a new empty tgeom struct - * Return a pointer on the newly allocated struct - */ -TGEOM* -tgeom_new(uint8_t type, int hasz, int hasm) -{ - TGEOM *tgeom; - - tgeom = lwalloc(sizeof(TGEOM)); - tgeom->type = type; - FLAGS_SET_Z(tgeom->flags, hasz); - FLAGS_SET_M(tgeom->flags, hasm); - tgeom->bbox=NULL; - tgeom->srid=0; - tgeom->nedges=0; - tgeom->maxedges=0; - tgeom->edges=NULL; - tgeom->maxfaces=0; - tgeom->nfaces=0; - tgeom->faces=NULL; - - return tgeom; -} - - -/* - * Check if a edge (start and end points) are or not already - * in a given tgeom. - * Return 0 if not in. - * Return positive index edge number if the edge is well oriented - * Return negative index edge number if the edge is reversed - */ -static int -tgeom_is_edge(const TGEOM *tgeom, const POINT4D *s, const POINT4D *e) -{ - int i, hasz, hasm; - POINT4D *p1, *p2; - - assert(tgeom); - assert(s); - assert(e); - - hasz = FLAGS_GET_Z(tgeom->flags); - hasm = FLAGS_GET_M(tgeom->flags); - - LWDEBUGF(3, "To check [%lf,%lf,%lf,%lf] -> [%lf,%lf,%lf,%lf]\n", - s->x, s->y, s->z, s->m, e->x, e->y, e->z, e->m); - - for (i=1 ; i <= tgeom->nedges ; i++) /* edges are 1 based */ - { - p1 = tgeom->edges[i]->s; - p2 = tgeom->edges[i]->e; - - LWDEBUGF(3, "[%i]/[%i] (%lf,%lf,%lf,%lf) -> (%lf,%lf,%lf,%lf)\n", - i, tgeom->nedges, - p1->x, p1->y, p1->z, p1->m, - p2->x, p2->y, p2->z, p2->m); - - /* X,Y,Z,M */ - if (hasz && hasm) - { - if ( p1->x == e->x && p1->y == e->y && p1->z == e->z && p1->m == e->m && - p2->x == s->x && p2->y == s->y && p2->z == s->z && p2->m == s->m) - return -i; - - if ( p1->x == s->x && p1->y == s->y && p1->z == s->z && p1->m == s->m && - p2->x == e->x && p2->y == e->y && p2->z == e->z && p2->m == e->m) - return i; - } - /* X,Y,Z */ - else if (hasz && !hasm) - { - if ( p1->x == e->x && p1->y == e->y && p1->z == e->z && - p2->x == s->x && p2->y == s->y && p2->z == s->z ) - return -i; - - if ( p1->x == s->x && p1->y == s->y && p1->z == s->z && - p2->x == e->x && p2->y == e->y && p2->z == e->z ) - return i; - } - /* X,Y,M */ - else if (!hasz && hasm) - { - if ( p1->x == e->x && p1->y == e->y && p1->m == e->m && - p2->x == s->x && p2->y == s->y && p2->m == s->m ) - return -i; - - if ( p1->x == s->x && p1->y == s->y && p1->m == s->m && - p2->x == e->x && p2->y == e->y && p2->m == e->m ) - return i; - } - else /*X,Y */ - { - if ( p1->x == e->x && p1->y == e->y && - p2->x == s->x && p2->y == s->y) - return -i; - - if ( p1->x == s->x && p1->y == s->y && - p2->x == e->x && p2->y == e->y) - return i; - } - } - - LWDEBUG(3, "Edge not found in array"); - - return 0; -} - - -/* - * Add an edge to a face in a tgeom - * Edge is describded as a starting and an ending point - * Points are really copied - * Return the new tgeom pointer - */ -static TGEOM* -tgeom_add_face_edge(TGEOM *tgeom, int face_id, POINT4D *s, POINT4D *e) -{ - int nedges, edge_id; - - assert(tgeom); - assert(s); - assert(e); - - edge_id = tgeom_is_edge(tgeom, s, e); - - if (edge_id) - { - tgeom->edges[abs(edge_id)]->count++; - LWDEBUGF(3, "face [%i] Founded Edge: %i\n", face_id, edge_id); - } - else - { - if ((tgeom->nedges + 1) == INT_MAX) - lwerror("tgeom_add_face_edge: Unable to alloc more than %i edges", INT_MAX); - - /* alloc edges array */ - if (tgeom->maxedges == 0) - { - tgeom->edges = (TEDGE**) lwalloc(sizeof(TEDGE*) * 4); - tgeom->maxedges = 4; - } - if (tgeom->maxedges <= (tgeom->nedges + 1)) - { - tgeom->edges = (TEDGE **) lwrealloc(tgeom->edges, - sizeof(TEDGE*) * tgeom->maxedges * 2); - tgeom->maxedges *= 2; - } - - edge_id = ++tgeom->nedges; /* edge_id is 1 based */ - tgeom->edges[edge_id] = (TEDGE*) lwalloc(sizeof(TEDGE)); - tgeom->edges[edge_id]->s = lwalloc(sizeof(POINT4D)); - tgeom->edges[edge_id]->e = lwalloc(sizeof(POINT4D)); - memcpy(tgeom->edges[edge_id]->s, s, sizeof(POINT4D)); - memcpy(tgeom->edges[edge_id]->e, e, sizeof(POINT4D)); - tgeom->edges[edge_id]->count = 1; - - LWDEBUGF(3, "face [%i] adding edge [%i] (%lf, %lf, %lf, %lf) -> (%lf, %lf, %lf, %lf)\n", - face_id, edge_id, s->x, s->y, s->z, s->m, e->x, e->y, e->z, e->m); - } - - nedges = tgeom->faces[face_id]->nedges; - if (tgeom->faces[face_id]->maxedges == 0) - { - tgeom->faces[face_id]->edges = (int *) lwalloc(sizeof(int) * 4); - tgeom->faces[face_id]->maxedges = 4; - } - 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); - - - tgeom->faces[face_id]->edges[nedges]= edge_id; - tgeom->faces[face_id]->nedges++; - - return tgeom; -} - - -/* - * Add a LWPOLY inside a tgeom - * Copy geometries from LWPOLY - */ -static TGEOM* -tgeom_add_polygon(TGEOM *tgeom, LWPOLY *poly) -{ - int i; - - assert(tgeom); - assert(poly); - - if ((tgeom->nfaces + 1) == INT_MAX) - lwerror("tgeom_add_polygon: Unable to alloc more than %i faces", INT_MAX); - - /* Integrity checks on subgeom, dims and srid */ - if (tgeom->type != POLYHEDRALSURFACETYPE) - lwerror("tgeom_add_polygon: Unable to handle %s - %s type", - tgeom->type, lwtype_name(tgeom->type)); - - if (FLAGS_NDIMS(tgeom->flags) != FLAGS_NDIMS(poly->flags)) - lwerror("tgeom_add_polygon: Mixed dimension"); - - if (tgeom->srid != poly->srid && (tgeom->srid != 0 && poly->srid != SRID_UNKNOWN)) - lwerror("tgeom_add_polygon: Mixed srid. Tgeom: %i / Polygon: %i", - tgeom->srid, poly->srid); - - /* handle face array allocation */ - if (tgeom->maxfaces == 0) - { - tgeom->faces = lwalloc(sizeof(TFACE*) * 2); - tgeom->maxfaces = 2; - } - if ((tgeom->maxfaces - 1) == tgeom->nfaces) - { - tgeom->faces = lwrealloc(tgeom->faces, - sizeof(TFACE*) * tgeom->maxfaces * 2); - tgeom->maxfaces *= 2; - } - - /* add an empty face */ - tgeom->faces[tgeom->nfaces] = lwalloc(sizeof(TFACE)); - tgeom->faces[tgeom->nfaces]->rings = NULL; - tgeom->faces[tgeom->nfaces]->nrings = 0; - tgeom->faces[tgeom->nfaces]->nedges = 0; - tgeom->faces[tgeom->nfaces]->maxedges = 0; - - /* Compute edge on poly external ring */ - for (i=1 ; i < poly->rings[0]->npoints ; i++) - { - POINT4D p1, p2; - - getPoint4d_p(poly->rings[0], i-1, &p1); - getPoint4d_p(poly->rings[0], i, &p2); - tgeom_add_face_edge(tgeom, tgeom->nfaces, &p1, &p2); - } - - /* External ring is already handled by edges */ - tgeom->faces[tgeom->nfaces]->nrings = poly->nrings - 1; - - /* handle rings array allocation */ - if (tgeom->faces[tgeom->nfaces]->nrings >= 1) - tgeom->faces[tgeom->nfaces]->rings = lwalloc(sizeof(POINTARRAY*) - * tgeom->faces[tgeom->nfaces]->nrings); - - /* 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->nfaces++; - - return tgeom; -} - - -/* - * Add a LWTRIANGLE inside a tgeom - * Copy geometries from LWTRIANGLE - */ -static TGEOM* -tgeom_add_triangle(TGEOM *tgeom, LWTRIANGLE *triangle) -{ - int i; - - assert(tgeom); - assert(triangle); - - if ((tgeom->nfaces + 1) == INT_MAX) - lwerror("tgeom_add_triangle: Unable to alloc more than %i faces", INT_MAX); - - /* Integrity checks on subgeom, dims and srid */ - if (tgeom->type != TINTYPE) - lwerror("tgeom_add_triangle: Unable to handle %s - %s type", - tgeom->type, lwtype_name(tgeom->type)); - - if (FLAGS_NDIMS(tgeom->flags) != FLAGS_NDIMS(triangle->flags)) - lwerror("tgeom_add_triangle: Mixed dimension"); - - if (tgeom->srid != triangle->srid - && (tgeom->srid != 0 && triangle->srid != SRID_UNKNOWN)) - lwerror("tgeom_add_triangle: Mixed srid. Tgeom: %i / Triangle: %i", - tgeom->srid, triangle->srid); - - /* handle face array allocation */ - if (tgeom->maxfaces == 0) - { - tgeom->faces = lwalloc(sizeof(TFACE*) * 2); - tgeom->maxfaces = 2; - } - if ((tgeom->maxfaces - 1) <= tgeom->nfaces) - { - tgeom->faces = lwrealloc(tgeom->faces, - sizeof(TFACE*) * tgeom->maxfaces * 2); - tgeom->maxfaces *= 2; - } - - /* add an empty face */ - tgeom->faces[tgeom->nfaces] = lwalloc(sizeof(TFACE)); - tgeom->faces[tgeom->nfaces]->rings = NULL; - tgeom->faces[tgeom->nfaces]->nrings = 0; - tgeom->faces[tgeom->nfaces]->nedges = 0; - tgeom->faces[tgeom->nfaces]->maxedges = 0; - - /* Compute edge on triangle */ - for (i=1 ; i < triangle->points->npoints ; i++) - { - POINT4D p1, p2; - - getPoint4d_p(triangle->points, i-1, &p1); - getPoint4d_p(triangle->points, i, &p2); - - tgeom_add_face_edge(tgeom, tgeom->nfaces, &p1, &p2); - } - - tgeom->nfaces++; - - return tgeom; -} - - -/* - * Free a tgeom struct - * and even the geometries inside - */ -void -tgeom_free(TGEOM *tgeom) -{ - int i, j; - - assert(tgeom); - - /* bbox */ - if (tgeom->bbox) lwfree(tgeom->bbox); - - /* edges */ - for (i=1 ; i <= tgeom->nedges ; 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); - - /* faces */ - for (i=0 ; i < tgeom->nfaces ; i++) - { - /* edges array */ - if (tgeom->faces[i]->edges) - lwfree(tgeom->faces[i]->edges); - - /* rings */ - for (j=0 ; j < tgeom->faces[i]->nrings ; j++) - ptarray_free(tgeom->faces[i]->rings[j]); - if (tgeom->faces[i]->nrings) - lwfree(tgeom->faces[i]->rings); - - lwfree(tgeom->faces[i]); - } - if (tgeom->nfaces) lwfree(tgeom->faces); - - lwfree(tgeom); -} - - -/* - * Return a TSERIALIZED pointer from an LWGEOM - */ -TSERIALIZED* -tserialized_from_lwgeom(LWGEOM *lwgeom) -{ - assert(lwgeom); - - return tgeom_serialize(tgeom_from_lwgeom(lwgeom)); -} - - -/* - * Return a TGEOM pointer from an LWGEOM - * Caution: Geometries from LWGEOM are copied - */ -TGEOM* -tgeom_from_lwgeom(const LWGEOM *lwgeom) -{ - int i, solid; - LWTIN *tin; - LWPSURFACE *psurf; - TGEOM *tgeom = NULL; - - tgeom = tgeom_new(0, FLAGS_GET_Z(lwgeom->flags), FLAGS_GET_M(lwgeom->flags)); - - if (lwgeom->srid < 1) tgeom->srid = SRID_UNKNOWN; - else tgeom->srid = lwgeom->srid; - - - switch (lwgeom->type) - { - case TINTYPE: - tgeom->type = TINTYPE; - tin = (LWTIN *) lwgeom; - - for (i=0 ; i < tin->ngeoms ; i++) - tgeom = tgeom_add_triangle(tgeom, (LWTRIANGLE *) tin->geoms[i]); - - break; - - case POLYHEDRALSURFACETYPE: - tgeom->type = POLYHEDRALSURFACETYPE; - psurf = (LWPSURFACE *) lwgeom; - for (i=0 ; i < psurf->ngeoms ; i++) - tgeom = tgeom_add_polygon(tgeom, (LWPOLY *) psurf->geoms[i]); - - break; - - /* TODO handle COLLECTIONTYPE */ - - default: - lwerror("tgeom_from_lwgeom: unknown geometry type %i - %s", - tgeom->type, lwtype_name(tgeom->type)); - } - - if (tgeom->nedges == 0) { - FLAGS_SET_SOLID(tgeom->flags, 0); - FLAGS_SET_BBOX(tgeom->flags, 0); - return tgeom; /* empty is not a solid, neither need BBOX */ - } - - for (solid=1, i=1 ; i <= tgeom->nedges ; i++) - { - if (tgeom->edges[i]->count != 2) - { - LWDEBUGF(3, "no solid, edges: [%i], count: [%i] (%lf,%lf,%lf,%lf)->(%lf,%lf,%lf,%lf)\n", - i, tgeom->edges[i]->count, - tgeom->edges[i]->s->x, tgeom->edges[i]->s->y, - tgeom->edges[i]->s->z, tgeom->edges[i]->s->m, - tgeom->edges[i]->e->x, tgeom->edges[i]->e->y, - tgeom->edges[i]->e->z, tgeom->edges[i]->e->m); - - solid = 0; - break; - } - } - if (solid) FLAGS_SET_SOLID(tgeom->flags, 1); - else FLAGS_SET_SOLID(tgeom->flags, 0); - - /* compute bbox */ - tgeom->bbox = lwalloc(sizeof(BOX3D)); - for (i=1 ; i <= tgeom->nedges ; i++) { - - if (i == 1 || tgeom->edges[i]->s->x < tgeom->bbox->xmin) tgeom->bbox->xmin = tgeom->edges[i]->s->x; - if (tgeom->edges[i]->e->x < tgeom->bbox->xmin) tgeom->bbox->xmin = tgeom->edges[i]->e->x; - - if (i == 1 || tgeom->edges[i]->s->y < tgeom->bbox->ymin) tgeom->bbox->ymin = tgeom->edges[i]->s->y; - if (tgeom->edges[i]->e->y < tgeom->bbox->ymin) tgeom->bbox->ymin = tgeom->edges[i]->e->y; - - if (i == 1 || tgeom->edges[i]->s->z < tgeom->bbox->zmin) tgeom->bbox->zmin = tgeom->edges[i]->s->z; - if (tgeom->edges[i]->e->z < tgeom->bbox->zmin) tgeom->bbox->zmin = tgeom->edges[i]->e->z; - - if (i == 1 || tgeom->edges[i]->s->x > tgeom->bbox->xmax) tgeom->bbox->xmax = tgeom->edges[i]->s->x; - if (tgeom->edges[i]->e->x > tgeom->bbox->xmax) tgeom->bbox->xmax = tgeom->edges[i]->e->x; - - if (i == 1 || tgeom->edges[i]->s->y > tgeom->bbox->ymax) tgeom->bbox->ymax = tgeom->edges[i]->s->y; - if (tgeom->edges[i]->e->y > tgeom->bbox->ymax) tgeom->bbox->ymax = tgeom->edges[i]->e->y; - - if (i == 1 || tgeom->edges[i]->s->z > tgeom->bbox->zmax) tgeom->bbox->zmax = tgeom->edges[i]->s->z; - if (tgeom->edges[i]->e->z > tgeom->bbox->zmax) tgeom->bbox->zmax = tgeom->edges[i]->e->z; - } - - return tgeom; -} - - -/* - * Return a LWGEOM pointer from an TSERIALIZED struct - */ -LWGEOM* -lwgeom_from_tserialized(TSERIALIZED *t) -{ - assert(t); - - return lwgeom_from_tgeom(tgeom_deserialize(t)); -} - - -/* - * Return a LWGEOM pointer from an TGEOM struct - * Geometries are NOT copied - */ -LWGEOM* -lwgeom_from_tgeom(TGEOM *tgeom) -{ - int i, j, k; - LWGEOM *geom; - POINTARRAY *dpa; - POINTARRAY **ppa; - int hasz, hasm, edge_id; - int dims=0; - - assert(tgeom); - - hasz=FLAGS_GET_Z(tgeom->flags); - hasm=FLAGS_GET_M(tgeom->flags); - - geom = (LWGEOM *)lwcollection_construct_empty(COLLECTIONTYPE, tgeom->srid, hasz, hasm); - - switch (tgeom->type) - { - case TINTYPE: - geom->type = TINTYPE; - for (i=0 ; i < tgeom->nfaces ; i++) - { - 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++) - { - edge_id = tgeom->faces[i]->edges[j]; - LWDEBUGF(3, "TIN edge_id: %i\n", edge_id); - - assert(edge_id); - if (edge_id > 0) - ptarray_append_point(dpa, tgeom->edges[edge_id]->s, LW_TRUE); - else - ptarray_append_point(dpa, tgeom->edges[-edge_id]->e, LW_TRUE); - } - - edge_id = tgeom->faces[i]->edges[0]; - LWDEBUGF(3, "TIN edge_id: %i\n", edge_id); - if (edge_id > 0) - ptarray_append_point(dpa, tgeom->edges[edge_id]->s, LW_TRUE); - else - ptarray_append_point(dpa, tgeom->edges[-edge_id]->e, LW_TRUE); - - geom = (LWGEOM *) lwtin_add_lwtriangle((LWTIN *) geom, - lwtriangle_construct(tgeom->srid, NULL, dpa)); - } - break; - - case POLYHEDRALSURFACETYPE: - geom->type = POLYHEDRALSURFACETYPE; - for (i=0 ; i < tgeom->nfaces ; i++) - { - FLAGS_SET_Z(dims, hasz?1:0); - FLAGS_SET_M(dims, hasm?1:0);; - dpa = ptarray_construct_empty(hasz, hasm, 4); - - for (j=0 ; j < tgeom->faces[i]->nedges ; j++) - { - edge_id = tgeom->faces[i]->edges[j]; - assert(edge_id); - LWDEBUGF(3, "POLYHEDRALSURFACE edge_id: %i\n", edge_id); - if (edge_id > 0) - ptarray_append_point(dpa, tgeom->edges[edge_id]->s, LW_TRUE); - else - ptarray_append_point(dpa, tgeom->edges[-edge_id]->e, LW_TRUE); - } - - edge_id = tgeom->faces[i]->edges[0]; - LWDEBUGF(3, "POLYHEDRALSURFACE edge_id: %i\n", edge_id); - if (edge_id > 0) - ptarray_append_point(dpa, tgeom->edges[edge_id]->s, LW_TRUE); - else - ptarray_append_point(dpa, tgeom->edges[-edge_id]->e, LW_TRUE); - - ppa = lwalloc(sizeof(POINTARRAY*) - * (tgeom->faces[i]->nrings + 1)); - ppa[0] = dpa; - for (k=0; k < tgeom->faces[i]->nrings ; 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)); - } - break; - - default: - lwerror("lwgeom_from_tgeom: Unkwnown type %i - %s\n", - tgeom->type, lwtype_name(tgeom->type)); - } - - if (geom->srid == 0) geom->srid = SRID_UNKNOWN; - - return geom; -} - - -/* - * Compute the memory size needed to serialize - * a TGEOM struct - */ -static size_t -tgeom_serialize_size(const TGEOM *tgeom) -{ - int i,j; - size_t size; - int dims = FLAGS_NDIMS(tgeom->flags); - - size = sizeof(uint8_t); /* type */ - size += sizeof(uint8_t); /* flags */ - size += sizeof(uint32_t); /* srid */ - if (tgeom->bbox) size += sizeof(float) * 6; /* bbox */ - - size += sizeof(uint32_t); /* nedges */ - size += (sizeof(double) * dims * 2 + 4) * tgeom->nedges; /* edges */ - - size += sizeof(uint32_t); /* nfaces */ - for (i=0 ; i < tgeom->nfaces ; i++) - { - size += sizeof(uint32_t); /* nedges */ - size += sizeof(uint32_t) * tgeom->faces[i]->nedges; /* edges */ - - size += sizeof(uint32_t); /* nrings */ - for (j=0 ; j < tgeom->faces[i]->nrings ; j++) - { - size += sizeof(uint32_t); /* npoints */ - size += sizeof(double) * dims /* rings */ - * tgeom->faces[i]->rings[j]->npoints; - } - } - - return size; -} - - -/* - * Serialize a TGEOM to a buf - * retsize return by reference the allocated buf size - */ -static size_t -tgeom_serialize_buf(const TGEOM *tgeom, uint8_t *buf, size_t *retsize) -{ - int i,j; - float f; - size_t size=0; - uint8_t *loc=buf; - int dims = FLAGS_NDIMS(tgeom->flags); - uint8_t flags = tgeom->flags; - - assert(tgeom); - assert(buf); - - FLAGS_SET_BBOX(flags, tgeom->bbox?1:0); - - /* Write in the type. */ - memcpy(loc, &tgeom->type, sizeof(uint8_t)); - loc += 1; - size += 1; - - /* Write in the flags. */ - memcpy(loc, &flags, sizeof(uint8_t)); - loc += 1; - size += 1; - - /* Write in the srid. */ - memcpy(loc, &tgeom->srid, sizeof(uint32_t)); - loc += 4; - size += 4; - - /* Write in the bbox. */ - if (tgeom->bbox) - { - f = next_float_down(tgeom->bbox->xmin); - memcpy(loc, &f, sizeof(float)); - loc += sizeof(float); - - f = next_float_down(tgeom->bbox->ymin); - memcpy(loc, &f, sizeof(float)); - loc += sizeof(float); - - f = next_float_down(tgeom->bbox->zmin); - memcpy(loc, &f, sizeof(float)); - loc += sizeof(float); - - f = next_float_up(tgeom->bbox->xmax); - memcpy(loc, &f, sizeof(float)); - loc += sizeof(float); - - f = next_float_up(tgeom->bbox->ymax); - memcpy(loc, &f, sizeof(float)); - loc += sizeof(float); - - f = next_float_up(tgeom->bbox->zmax); - memcpy(loc, &f, sizeof(float)); - loc += sizeof(float); - - size += sizeof(float) * 6; - } - - /* Write in the number of edges (0 means EMPTY) */ - memcpy(loc, &tgeom->nedges, sizeof(uint32_t)); - loc += 4; - size += 4; - - /* Edges */ - for (i=1 ; i <= tgeom->nedges ; i++) - { - /* 3DM specific handle */ - if (!FLAGS_GET_Z(tgeom->flags) && FLAGS_GET_M(tgeom->flags)) - { - memcpy(loc, tgeom->edges[i]->s, 2 * sizeof(double)); - loc += sizeof(double) * 2; - memcpy(loc, &(tgeom->edges[i]->s->m), sizeof(double)); - loc += sizeof(double); - - memcpy(loc, tgeom->edges[i]->e, 2 * sizeof(double)); - loc += sizeof(double) * 2; - memcpy(loc, &(tgeom->edges[i]->e->m), sizeof(double)); - loc += sizeof(double); - } - else /* 2D, 3DZ && 4D */ - { - memcpy(loc, tgeom->edges[i]->s, dims * sizeof(double)); - loc += sizeof(double) * dims; - memcpy(loc, tgeom->edges[i]->e, dims * sizeof(double)); - loc += sizeof(double) * dims; - } - memcpy(loc, &tgeom->edges[i]->count, sizeof(uint32_t)); - loc += 4; - - size += sizeof(double) * dims * 2 + 4; - } - - /* Write in the number of faces */ - memcpy(loc, &tgeom->nfaces, sizeof(uint32_t)); - loc += 4; - size += 4; - - /* Faces */ - for (i=0 ; i < tgeom->nfaces ; i++) - { - /* Write in the number of edges */ - memcpy(loc, &tgeom->faces[i]->nedges, sizeof(uint32_t)); - loc += 4; - size += 4; - - /* Write in the edges array */ - memcpy(loc, tgeom->faces[i]->edges, - sizeof(uint32_t) * tgeom->faces[i]->nedges); - loc += 4 * tgeom->faces[i]->nedges; - size += 4 * tgeom->faces[i]->nedges; - - /* Write the number of rings */ - memcpy(loc, &tgeom->faces[i]->nrings, sizeof(uint32_t)); - loc += 4; - size += 4; - - for (j=0 ; j < tgeom->faces[i]->nrings ; j++) - { - /* Write the number of points */ - memcpy(loc, &tgeom->faces[i]->rings[j]->npoints, sizeof(uint32_t)); - loc += 4; - size += 4; - - /* Write the points */ - memcpy(loc, getPoint_internal(tgeom->faces[i]->rings[j], 0), - sizeof(double) * dims * tgeom->faces[i]->rings[j]->npoints); - loc += sizeof(double) * dims * tgeom->faces[i]->rings[j]->npoints; - size += sizeof(double) * dims * tgeom->faces[i]->rings[j]->npoints; - } - } - - if (retsize) *retsize = size; - - return (size_t) (loc - buf); -} - - -/* - * Serialize a tgeom struct and return a - * TSERIALIZED pointer - */ -TSERIALIZED * -tgeom_serialize(const TGEOM *tgeom) -{ - size_t size, retsize; - TSERIALIZED * t; - uint8_t *data; - size = tgeom_serialize_size(tgeom); - data = lwalloc(size); - tgeom_serialize_buf(tgeom, data, &retsize); - - if ( retsize != size ) - { - lwerror("tgeom_serialize_size returned %d, ..serialize_buf returned %d", - size, retsize); - } - - t = lwalloc(sizeof(TSERIALIZED)); - t->flags = tgeom->flags; - t->srid = tgeom->srid; - t->data = data; - - /* - * We are aping PgSQL code here, PostGIS code should use - * VARSIZE to set this for real. - */ - t->size = retsize << 2; - - return t; -} - - - -/* - * Deserialize a TSERIALIZED struct and - * return a TGEOM pointer - */ -TGEOM * -tgeom_deserialize(TSERIALIZED *serialized_form) -{ - uint8_t type, flags; - TGEOM *result; - uint8_t *loc, *data; - int i, j; - - assert(serialized_form); - assert(serialized_form->data); - - data = serialized_form->data; - - /* type and flags */ - type = data[0]; - flags = data[1]; - result = tgeom_new(type, FLAGS_GET_Z(flags), FLAGS_GET_M(flags)); - loc = data + 2; - - /* srid */ - result->srid = lw_get_int32_t(loc); - loc += 4; - - /* bbox */ - if (FLAGS_GET_BBOX(flags)) - { - result->bbox = lwalloc(sizeof(BOX3D)); - memcpy(&(result->bbox->xmin), loc, sizeof(float)); - loc += sizeof(float); - memcpy(&(result->bbox->ymin), loc, sizeof(float)); - loc += sizeof(float); - memcpy(&(result->bbox->zmin), loc, sizeof(float)); - loc += sizeof(float); - memcpy(&(result->bbox->xmax), loc, sizeof(float)); - loc += sizeof(float); - memcpy(&(result->bbox->ymax), loc, sizeof(float)); - loc += sizeof(float); - memcpy(&(result->bbox->zmax), loc, sizeof(float)); - loc += sizeof(float); - } - else result->bbox = NULL; - - /* edges number (0 means EMPTY) */ - result->nedges = lw_get_uint32_t(loc); - loc += 4; - - /* edges */ - result->edges = lwalloc(sizeof(TEDGE*) * (result->nedges + 1)); - for (i=1 ; i <= result->nedges ; i++) - { - result->edges[i] = lwalloc(sizeof(TEDGE)); - result->edges[i]->s = lwalloc(sizeof(POINT4D)); - result->edges[i]->e = lwalloc(sizeof(POINT4D)); - - /* 3DM specific handle */ - if (!FLAGS_GET_Z(result->flags) && FLAGS_GET_M(result->flags)) - { - memcpy(result->edges[i]->s, loc, sizeof(double) * 2); - loc += sizeof(double) * 2; - memcpy(&(result->edges[i]->s->m), loc, sizeof(double)); - loc += sizeof(double); - - memcpy(result->edges[i]->e, loc, sizeof(double) * 2); - loc += sizeof(double) * 2; - memcpy(&(result->edges[i]->e->m), loc, sizeof(double)); - loc += sizeof(double); - } - else /* 2D,3DZ && 4D */ - { - memcpy(result->edges[i]->s, loc, - sizeof(double) * FLAGS_NDIMS(flags)); - loc += sizeof(double) * FLAGS_NDIMS(flags); - - result->edges[i]->e = lwalloc(sizeof(POINT4D)); - memcpy(result->edges[i]->e, loc, - sizeof(double) * FLAGS_NDIMS(flags)); - loc += sizeof(double) * FLAGS_NDIMS(flags); - } - - result->edges[i]->count = lw_get_uint32_t(loc); - loc += 4; - } - - /* faces number */ - result->nfaces = lw_get_uint32_t(loc); - loc += 4; - - /* faces */ - result->faces = lwalloc(sizeof(TFACE*) * result->nfaces); - for (i=0 ; i < result->nfaces ; i++) - { - result->faces[i] = lwalloc(sizeof(TFACE)); - - /* number of edges */ - result->faces[i]->nedges = lw_get_uint32_t(loc); - loc += 4; - - /* edges array */ - result->faces[i]->edges = lwalloc(sizeof(TEDGE*) - * result->faces[i]->nedges); - memcpy(result->faces[i]->edges, loc, sizeof(int32_t) - * result->faces[i]->nedges); - loc += 4 * result->faces[i]->nedges; - - /* number of rings */ - result->faces[i]->nrings = lw_get_uint32_t(loc); - loc += 4; - - if (result->faces[i]->nrings) - result->faces[i]->rings = lwalloc(sizeof(POINTARRAY*) - * result->faces[i]->nrings); - - for (j=0 ; j < result->faces[i]->nrings ; j++) - { - int npoints; - - /* number of points */ - npoints = lw_get_uint32_t(loc); - loc += 4; - - /* pointarray */ - result->faces[i]->rings[j] = ptarray_construct_copy_data(FLAGS_GET_Z(flags), FLAGS_GET_M(flags), npoints, loc); - - loc += sizeof(double)* FLAGS_NDIMS(flags) * npoints; - } - } - - return result; -} - - -/* - * Indicate if an given LWGEOM is or not a solid - */ -int -lwgeom_is_solid(LWGEOM *lwgeom) -{ - int solid=0; - TGEOM *tgeom; - - assert(lwgeom); - - /* Obvious case who could'nt be solid */ - if (lwgeom->type != POLYHEDRALSURFACETYPE && lwgeom->type != TINTYPE) return 0; - if (!FLAGS_GET_Z(lwgeom->flags)) return 0; - - /* Use TGEOM convert to know */ - tgeom = tgeom_from_lwgeom(lwgeom); - solid = FLAGS_GET_SOLID(tgeom->flags); - tgeom_free(tgeom); - - return solid; -} - - -/* - * Compute 2D perimeter of a TGEOM - */ -double -tgeom_perimeter2d(TGEOM* tgeom) -{ - int i; - double hz, vt, bdy = 0.0; - - assert(tgeom); - - if (tgeom->type != POLYHEDRALSURFACETYPE && tgeom->type != TINTYPE) - lwerror("tgeom_perimeter2d called with wrong type: %i - %s", - tgeom->type, lwtype_name(tgeom->type)); - - /* Solid have a 0.0 length perimeter */ - if (FLAGS_GET_SOLID(tgeom->flags)) return bdy; - - for (i=1 ; i <= tgeom->nedges ; i++) - { - if (tgeom->edges[i]->count == 1) - { - hz = tgeom->edges[i]->s->x - tgeom->edges[i]->e->x; - vt = tgeom->edges[i]->s->y - tgeom->edges[i]->e->y; - bdy += sqrt(hz*hz + vt*vt); - } - } - - return bdy; -} - - -/* - * Compute 2D/3D perimeter of a TGEOM - */ -double -tgeom_perimeter(TGEOM* tgeom) -{ - int i; - double hz, vt, ht, bdy = 0.0; - - assert(tgeom); - - if (tgeom->type != POLYHEDRALSURFACETYPE && tgeom->type != TINTYPE) - lwerror("tgeom_perimeter called with wrong type: %i - %s", - tgeom->type, lwtype_name(tgeom->type)); - - /* Solid have a 0.0 length perimeter */ - if (FLAGS_GET_SOLID(tgeom->flags)) return bdy; - - /* If no Z use 2d function instead */ - if (!FLAGS_GET_Z(tgeom->flags)) return tgeom_perimeter2d(tgeom); - - for (i=1 ; i <= tgeom->nedges ; i++) - { - if (tgeom->edges[i]->count == 1) - { - hz = tgeom->edges[i]->s->x - tgeom->edges[i]->e->x; - vt = tgeom->edges[i]->s->y - tgeom->edges[i]->e->y; - ht = tgeom->edges[i]->s->z - tgeom->edges[i]->e->z; - bdy += sqrt(hz*hz + vt*vt + ht*ht); - } - } - - return bdy; -} - - -/* - * Print a TGEOM struct - * Debug purpose only - */ -void -printTGEOM(TGEOM *tgeom) -{ - int i,j; - - assert(tgeom); - - printf("TGEOM:\n"); - printf(" - type %i, %s\n", tgeom->type, lwtype_name(tgeom->type)); - printf(" - srid %i\n", tgeom->srid); - 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++) - { - if (FLAGS_NDIMS(tgeom->flags) == 2) - printf(" [%i] (%lf,%lf) -> (%lf,%lf)\n", i, - tgeom->edges[i]->s->x, - tgeom->edges[i]->s->y, - tgeom->edges[i]->e->x, - tgeom->edges[i]->e->y); - else if (FLAGS_NDIMS(tgeom->flags) == 3) - printf(" [%i] (%lf,%lf,%lf) -> (%lf,%lf,%lf)\n", i, - tgeom->edges[i]->s->x, - tgeom->edges[i]->s->y, - tgeom->edges[i]->s->z, - tgeom->edges[i]->e->x, - tgeom->edges[i]->e->y, - tgeom->edges[i]->e->z); - else - printf(" [%i] (%lf,%lf,%lf,%lf) -> (%lf,%lf,%lf,%lf)\n", i, - tgeom->edges[i]->s->x, - tgeom->edges[i]->s->y, - tgeom->edges[i]->s->z, - tgeom->edges[i]->s->m, - tgeom->edges[i]->e->x, - tgeom->edges[i]->e->y, - tgeom->edges[i]->e->z, - tgeom->edges[i]->e->m); - } - - for (i=0 ; i < tgeom->nfaces ; i++) - { - printf(" => FACE [%i] nedges:%i nrings:%i\n", i, - tgeom->faces[i]->nedges, tgeom->faces[i]->nrings); - - for (j=0 ; j < tgeom->faces[i]->nedges ; j++) - { - int edge = tgeom->faces[i]->edges[j]; - printf(" -> EDGES [%i]{%i} ", j, edge); - - if (FLAGS_NDIMS(tgeom->flags) == 2) - { - if (tgeom->faces[i]->edges[j] > 0) - printf("(%lf,%lf) -> (%lf,%lf)\n", - tgeom->edges[edge]->s->x, - tgeom->edges[edge]->s->y, - tgeom->edges[edge]->e->x, - tgeom->edges[edge]->e->y); - else - printf("(%lf,%lf) -> (%lf,%lf)\n", - tgeom->edges[-edge]->e->x, - tgeom->edges[-edge]->e->y, - tgeom->edges[-edge]->s->x, - tgeom->edges[-edge]->s->y); - } - else if (FLAGS_NDIMS(tgeom->flags) == 3) - { - if (tgeom->faces[i]->edges[j] > 0) - printf("(%lf,%lf,%lf -> %lf,%lf,%lf)\n", - tgeom->edges[edge]->s->x, - tgeom->edges[edge]->s->y, - tgeom->edges[edge]->s->z, - tgeom->edges[edge]->e->x, - tgeom->edges[edge]->e->y, - tgeom->edges[edge]->e->z); - else - printf("(%lf,%lf,%lf -> %lf,%lf,%lf)\n", - tgeom->edges[-edge]->e->x, - tgeom->edges[-edge]->e->y, - tgeom->edges[-edge]->e->z, - tgeom->edges[-edge]->s->x, - tgeom->edges[-edge]->s->y, - tgeom->edges[-edge]->s->z); - } - else if (FLAGS_NDIMS(tgeom->flags) == 4) - { - if (tgeom->faces[i]->edges[j] > 0) - printf("(%lf,%lf,%lf,%lf -> %lf,%lf,%lf,%lf)\n", - tgeom->edges[edge]->s->x, - tgeom->edges[edge]->s->y, - tgeom->edges[edge]->s->z, - tgeom->edges[edge]->s->m, - tgeom->edges[edge]->e->x, - tgeom->edges[edge]->e->y, - tgeom->edges[edge]->e->z, - tgeom->edges[edge]->e->m); - else - printf("(%lf,%lf,%lf,%lf -> %lf,%lf,%lf,%lf)\n", - tgeom->edges[-edge]->e->x, - tgeom->edges[-edge]->e->y, - tgeom->edges[-edge]->e->z, - tgeom->edges[-edge]->e->m, - tgeom->edges[-edge]->s->x, - tgeom->edges[-edge]->s->y, - tgeom->edges[-edge]->s->z, - tgeom->edges[-edge]->s->m); - } - } - - for (j=0 ; j < tgeom->faces[i]->nrings ; j++) - { - printf(" - Ring[%i/%i]", j+1, tgeom->faces[i]->nrings); - printPA(tgeom->faces[i]->rings[j]); - } - } -} diff --git a/liblwgeom/libtgeom.h b/liblwgeom/libtgeom.h deleted file mode 100644 index 48dd9ed22..000000000 --- a/liblwgeom/libtgeom.h +++ /dev/null @@ -1,76 +0,0 @@ -/********************************************************************** - * $Id:$ - * - * PostGIS - Spatial Types for PostgreSQL - * http://postgis.refractions.net - * Copyright 2010 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. - * - **********************************************************************/ - -#ifndef _LIBTGEOM_H -#define _LIBTGEOM_H 1 - -#include - -/** -* TSERIALIZED (mostly inspired by GSERIALIZED struct) -*/ -typedef struct -{ - uint32_t size; /* For PgSQL use only, use VAR* macros to manipulate. */ - uint32_t srid; /* SRID */ - uint8_t flags; /* HasZ, HasM, HasBBox, IsGeodetic, IsReadOnly, IsSolid */ - uint8_t *data; /* See tserialized.txt */ -} TSERIALIZED; - - - -typedef struct -{ - POINT4D *s; /* Edge starting point */ - POINT4D *e; /* Edge ending point */ - int count; /* Count how many time this edge is used in the TGEOM. - Caution: We don't care about edge orientation ! */ -} TEDGE; - -typedef struct -{ - uint32_t nedges; - uint32_t maxedges; - int32_t *edges; /* Array of edge index, a negative value - means that the edge is reversed */ - int32_t nrings; - POINTARRAY **rings; /* Internal rings array */ -} TFACE; - -typedef struct -{ - uint8_t type; - uint8_t flags; - uint32_t srid; /* 0 == unknown */ - BOX3D *bbox; /* NULL == unneeded */ - uint32_t nedges; - uint32_t maxedges; - TEDGE **edges; - uint32_t nfaces; - uint32_t maxfaces; - TFACE **faces; -} TGEOM; - -extern TGEOM* tgeom_new(uint8_t type, int hasz, int hasm); -extern void tgeom_free(TGEOM *tgeom); -extern TSERIALIZED* tserialized_from_lwgeom(LWGEOM *lwgeom); -extern TGEOM* tgeom_from_lwgeom(const LWGEOM *lwgeom); -extern LWGEOM* lwgeom_from_tserialized(TSERIALIZED *t); -extern LWGEOM* lwgeom_from_tgeom(TGEOM *tgeom); -extern int lwgeom_is_solid(LWGEOM *lwgeom); -TSERIALIZED * tgeom_serialize(const TGEOM *tgeom); -TGEOM * tgeom_deserialize(TSERIALIZED *serialized_form); -double tgeom_perimeter2d(TGEOM* tgeom); -double tgeom_perimeter(TGEOM* tgeom); -extern void printTGEOM(TGEOM *tgeom); - -#endif /* !defined _LIBTGEOM_H */ diff --git a/liblwgeom/lwgeom.c b/liblwgeom/lwgeom.c index 7466fee38..a30ea0c23 100644 --- a/liblwgeom/lwgeom.c +++ b/liblwgeom/lwgeom.c @@ -16,7 +16,6 @@ #include "liblwgeom_internal.h" #include "lwgeom_log.h" -#include "libtgeom.h" /** Force Right-hand-rule on LWGEOM polygons **/ @@ -1253,7 +1252,7 @@ extern int lwgeom_dimensionality(LWGEOM *geom) case POLYHEDRALSURFACETYPE: case TINTYPE: - dim = lwgeom_is_solid(geom)?3:2; + dim = lwgeom_is_closed(geom)?3:2; return dim; break; @@ -1453,10 +1452,6 @@ double lwgeom_perimeter(const LWGEOM *geom) return lwcurvepoly_perimeter((LWCURVEPOLY*)geom); else if ( type == TRIANGLETYPE ) return lwtriangle_perimeter((LWTRIANGLE*)geom); - else if ( type == POLYHEDRALSURFACETYPE || type == TINTYPE ) - { - return tgeom_perimeter(tgeom_from_lwgeom(geom)); - } else if ( lwgeom_is_collection(geom) ) { double perimeter = 0.0; @@ -1479,10 +1474,6 @@ double lwgeom_perimeter_2d(const LWGEOM *geom) return lwcurvepoly_perimeter_2d((LWCURVEPOLY*)geom); else if ( type == TRIANGLETYPE ) return lwtriangle_perimeter_2d((LWTRIANGLE*)geom); - else if ( type == POLYHEDRALSURFACETYPE || type == TINTYPE ) - { - return tgeom_perimeter(tgeom_from_lwgeom(geom)); - } else if ( lwgeom_is_collection(geom) ) { double perimeter = 0.0; diff --git a/regress/run_test b/regress/run_test index 50b629b56..69f55ea59 100755 --- a/regress/run_test +++ b/regress/run_test @@ -668,7 +668,7 @@ create_spatial () { echo "Creating spatial db ${DB} " - createdb --encoding=UTF-8 --template=template0 --lc-collate="C" "${DB}" > ${PGIS_REG_TMPDIR}/regress_log 2>&1 + createdb --template=template0 --lc-collate="C" "${DB}" > ${PGIS_REG_TMPDIR}/regress_log 2>&1 if [ $? -gt 0 ]; then # { fail "createdb failed" "${PGIS_REG_TMPDIR}/regress_log" exit 1 diff --git a/regress/run_test.pl b/regress/run_test.pl index 30dc4f887..9e051f938 100755 --- a/regress/run_test.pl +++ b/regress/run_test.pl @@ -959,7 +959,7 @@ sub create_spatial my ($cmd, $rv); print "Creating database '$DB' \n"; - $cmd = "createdb --encoding=UTF-8 --template=template0 --lc-collate=C $DB > $REGRESS_LOG"; + $cmd = "createdb --template=template0 --lc-collate=C $DB > $REGRESS_LOG"; $rv = system($cmd); $cmd = "createlang plpgsql $DB >> $REGRESS_LOG 2>&1"; $rv = system($cmd);