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 */
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 */
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 */
}
-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;
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 */
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)
}
-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.
*/
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};
+++ /dev/null
-/**********************************************************************
- * $Id:$
- *
- * PostGIS - Spatial Types for PostgreSQL
- * http://postgis.refractions.net
- * 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.
- *
- **********************************************************************/
-
-#include <limits.h>
-#include <assert.h>
-#include <stdlib.h>
-
-#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]);
- }
- }
-}