PostGIS  2.2.8dev-r@@SVN_REVISION@@
lwtin.c
Go to the documentation of this file.
1 /**********************************************************************
2  *
3  * PostGIS - Spatial Types for PostgreSQL
4  * http://postgis.net
5  *
6  * Copyright (C) 2001-2006 Refractions Research Inc.
7  *
8  * This is free software; you can redistribute and/or modify it under
9  * the terms of the GNU General Public Licence. See the COPYING file.
10  *
11  **********************************************************************/
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 
17 #include "liblwgeom_internal.h"
18 #include "lwgeom_log.h"
19 
20 
22 {
23  return (LWTIN*)lwcollection_add_lwgeom((LWCOLLECTION*)mobj, (LWGEOM*)obj);
24 }
25 
26 void lwtin_free(LWTIN *tin)
27 {
28  int i;
29  if ( ! tin ) return;
30  if ( tin->bbox )
31  lwfree(tin->bbox);
32 
33  for ( i = 0; i < tin->ngeoms; i++ )
34  if ( tin->geoms && tin->geoms[i] )
35  lwtriangle_free(tin->geoms[i]);
36 
37  if ( tin->geoms )
38  lwfree(tin->geoms);
39 
40  lwfree(tin);
41 }
42 
43 
44 void printLWTIN(LWTIN *tin)
45 {
46  int i;
47  LWTRIANGLE *triangle;
48 
49  if (tin->type != TINTYPE)
50  lwerror("printLWTIN called with something else than a TIN");
51 
52  lwnotice("LWTIN {");
53  lwnotice(" ndims = %i", (int)FLAGS_NDIMS(tin->flags));
54  lwnotice(" SRID = %i", (int)tin->srid);
55  lwnotice(" ngeoms = %i", (int)tin->ngeoms);
56 
57  for (i=0; i<tin->ngeoms; i++)
58  {
59  triangle = (LWTRIANGLE *) tin->geoms[i];
60  printPA(triangle->points);
61  }
62  lwnotice("}");
63 }
64 
65 
66 /*
67  * TODO rewrite all this stuff to be based on a truly topological model
68  */
69 
71 {
72  double ax, ay, az;
73  double bx, by, bz;
74  int cnt, face;
75 };
76 typedef struct struct_tin_arcs *tin_arcs;
77 
78 /* We supposed that the geometry is valid
79  we could have wrong result if not */
80 int lwtin_is_closed(const LWTIN *tin)
81 {
82  int i, j, k;
83  int narcs, carc;
84  int found;
85  tin_arcs arcs;
86  POINT4D pa, pb;
87  LWTRIANGLE *patch;
88 
89  /* If surface is not 3D, it's can't be closed */
90  if (!FLAGS_GET_Z(tin->flags)) return 0;
91 
92  /* Max theorical arcs number if no one is shared ... */
93  narcs = 3 * tin->ngeoms;
94 
95  arcs = lwalloc(sizeof(struct struct_tin_arcs) * narcs);
96  for (i=0, carc=0; i < tin->ngeoms ; i++)
97  {
98 
99  patch = (LWTRIANGLE *) tin->geoms[i];
100  for (j=0; j < 3 ; j++)
101  {
102 
103  getPoint4d_p(patch->points, j, &pa);
104  getPoint4d_p(patch->points, j+1, &pb);
105 
106  /* Make sure to order the 'lower' point first */
107  if ( (pa.x > pb.x) ||
108  (pa.x == pb.x && pa.y > pb.y) ||
109  (pa.x == pb.x && pa.y == pb.y && pa.z > pb.z) )
110  {
111  pa = pb;
112  getPoint4d_p(patch->points, j, &pb);
113  }
114 
115  for (found=0, k=0; k < carc ; k++)
116  {
117 
118  if ( ( arcs[k].ax == pa.x && arcs[k].ay == pa.y &&
119  arcs[k].az == pa.z && arcs[k].bx == pb.x &&
120  arcs[k].by == pb.y && arcs[k].bz == pb.z &&
121  arcs[k].face != i) )
122  {
123  arcs[k].cnt++;
124  found = 1;
125 
126  /* Look like an invalid TIN
127  anyway not a closed one */
128  if (arcs[k].cnt > 2)
129  {
130  lwfree(arcs);
131  return 0;
132  }
133  }
134  }
135 
136  if (!found)
137  {
138  arcs[carc].cnt=1;
139  arcs[carc].face=i;
140  arcs[carc].ax = pa.x;
141  arcs[carc].ay = pa.y;
142  arcs[carc].az = pa.z;
143  arcs[carc].bx = pb.x;
144  arcs[carc].by = pb.y;
145  arcs[carc].bz = pb.z;
146  carc++;
147 
148  /* Look like an invalid TIN
149  anyway not a closed one */
150  if (carc > narcs)
151  {
152  lwfree(arcs);
153  return 0;
154  }
155  }
156  }
157  }
158 
159  /* A TIN is closed if each edge
160  is shared by exactly 2 faces */
161  for (k=0; k < carc ; k++)
162  {
163  if (arcs[k].cnt != 2)
164  {
165  lwfree(arcs);
166  return 0;
167  }
168  }
169  lwfree(arcs);
170 
171  /* Invalid TIN case */
172  if (carc < tin->ngeoms) return 0;
173 
174  return 1;
175 }
double x
Definition: liblwgeom.h:336
POINTARRAY * points
Definition: liblwgeom.h:417
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:61
void lwfree(void *mem)
Definition: lwutil.c:214
GBOX * bbox
Definition: liblwgeom.h:567
double bx
Definition: lwtin.c:73
double by
Definition: lwtin.c:73
void lwtin_free(LWTIN *tin)
Definition: lwtin.c:26
double az
Definition: lwtin.c:72
struct struct_tin_arcs * tin_arcs
Definition: lwtin.c:76
int ngeoms
Definition: liblwgeom.h:569
#define TINTYPE
Definition: liblwgeom.h:84
LWTRIANGLE ** geoms
Definition: liblwgeom.h:571
double bz
Definition: lwtin.c:73
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:124
double z
Definition: liblwgeom.h:336
uint8_t type
Definition: liblwgeom.h:565
int lwtin_is_closed(const LWTIN *tin)
Definition: lwtin.c:80
void lwtriangle_free(LWTRIANGLE *triangle)
Definition: lwtriangle.c:56
double ax
Definition: lwtin.c:72
void printPA(POINTARRAY *pa)
Definition: lwgeom_api.c:598
LWTIN * lwtin_add_lwtriangle(LWTIN *mobj, const LWTRIANGLE *obj)
Definition: lwtin.c:21
void printLWTIN(LWTIN *tin)
Definition: lwtin.c:44
void * lwalloc(size_t size)
Definition: lwutil.c:199
uint8_t flags
Definition: liblwgeom.h:566
double y
Definition: liblwgeom.h:336
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:136
double ay
Definition: lwtin.c:72
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
Definition: lwcollection.c:174
int32_t srid
Definition: liblwgeom.h:568
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:74
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:231