PostGIS  2.3.7dev-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  * PostGIS is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * PostGIS is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18  *
19  **********************************************************************
20  *
21  * Copyright (C) 2001-2006 Refractions Research Inc.
22  *
23  **********************************************************************/
24 
25 
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "liblwgeom_internal.h"
31 #include "lwgeom_log.h"
32 
33 
35 {
36  return (LWTIN*)lwcollection_add_lwgeom((LWCOLLECTION*)mobj, (LWGEOM*)obj);
37 }
38 
39 void lwtin_free(LWTIN *tin)
40 {
41  int i;
42  if ( ! tin ) return;
43  if ( tin->bbox )
44  lwfree(tin->bbox);
45 
46  for ( i = 0; i < tin->ngeoms; i++ )
47  if ( tin->geoms && tin->geoms[i] )
48  lwtriangle_free(tin->geoms[i]);
49 
50  if ( tin->geoms )
51  lwfree(tin->geoms);
52 
53  lwfree(tin);
54 }
55 
56 
57 void printLWTIN(LWTIN *tin)
58 {
59  int i;
60  LWTRIANGLE *triangle;
61 
62  if (tin->type != TINTYPE)
63  lwerror("printLWTIN called with something else than a TIN");
64 
65  lwnotice("LWTIN {");
66  lwnotice(" ndims = %i", (int)FLAGS_NDIMS(tin->flags));
67  lwnotice(" SRID = %i", (int)tin->srid);
68  lwnotice(" ngeoms = %i", (int)tin->ngeoms);
69 
70  for (i=0; i<tin->ngeoms; i++)
71  {
72  triangle = (LWTRIANGLE *) tin->geoms[i];
73  printPA(triangle->points);
74  }
75  lwnotice("}");
76 }
77 
78 
79 /*
80  * TODO rewrite all this stuff to be based on a truly topological model
81  */
82 
84 {
85  double ax, ay, az;
86  double bx, by, bz;
87  int cnt, face;
88 };
89 typedef struct struct_tin_arcs *tin_arcs;
90 
91 /* We supposed that the geometry is valid
92  we could have wrong result if not */
93 int lwtin_is_closed(const LWTIN *tin)
94 {
95  int i, j, k;
96  int narcs, carc;
97  int found;
98  tin_arcs arcs;
99  POINT4D pa, pb;
100  LWTRIANGLE *patch;
101 
102  /* If surface is not 3D, it's can't be closed */
103  if (!FLAGS_GET_Z(tin->flags)) return 0;
104 
105  /* Max theorical arcs number if no one is shared ... */
106  narcs = 3 * tin->ngeoms;
107 
108  arcs = lwalloc(sizeof(struct struct_tin_arcs) * narcs);
109  for (i=0, carc=0; i < tin->ngeoms ; i++)
110  {
111 
112  patch = (LWTRIANGLE *) tin->geoms[i];
113  for (j=0; j < 3 ; j++)
114  {
115 
116  getPoint4d_p(patch->points, j, &pa);
117  getPoint4d_p(patch->points, j+1, &pb);
118 
119  /* Make sure to order the 'lower' point first */
120  if ( (pa.x > pb.x) ||
121  (pa.x == pb.x && pa.y > pb.y) ||
122  (pa.x == pb.x && pa.y == pb.y && pa.z > pb.z) )
123  {
124  pa = pb;
125  getPoint4d_p(patch->points, j, &pb);
126  }
127 
128  for (found=0, k=0; k < carc ; k++)
129  {
130 
131  if ( ( arcs[k].ax == pa.x && arcs[k].ay == pa.y &&
132  arcs[k].az == pa.z && arcs[k].bx == pb.x &&
133  arcs[k].by == pb.y && arcs[k].bz == pb.z &&
134  arcs[k].face != i) )
135  {
136  arcs[k].cnt++;
137  found = 1;
138 
139  /* Look like an invalid TIN
140  anyway not a closed one */
141  if (arcs[k].cnt > 2)
142  {
143  lwfree(arcs);
144  return 0;
145  }
146  }
147  }
148 
149  if (!found)
150  {
151  arcs[carc].cnt=1;
152  arcs[carc].face=i;
153  arcs[carc].ax = pa.x;
154  arcs[carc].ay = pa.y;
155  arcs[carc].az = pa.z;
156  arcs[carc].bx = pb.x;
157  arcs[carc].by = pb.y;
158  arcs[carc].bz = pb.z;
159  carc++;
160 
161  /* Look like an invalid TIN
162  anyway not a closed one */
163  if (carc > narcs)
164  {
165  lwfree(arcs);
166  return 0;
167  }
168  }
169  }
170  }
171 
172  /* A TIN is closed if each edge
173  is shared by exactly 2 faces */
174  for (k=0; k < carc ; k++)
175  {
176  if (arcs[k].cnt != 2)
177  {
178  lwfree(arcs);
179  return 0;
180  }
181  }
182  lwfree(arcs);
183 
184  /* Invalid TIN case */
185  if (carc < tin->ngeoms) return 0;
186 
187  return 1;
188 }
double x
Definition: liblwgeom.h:351
POINTARRAY * points
Definition: liblwgeom.h:432
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:89
void lwfree(void *mem)
Definition: lwutil.c:242
GBOX * bbox
Definition: liblwgeom.h:582
double bx
Definition: lwtin.c:86
double by
Definition: lwtin.c:86
void lwtin_free(LWTIN *tin)
Definition: lwtin.c:39
double az
Definition: lwtin.c:85
struct struct_tin_arcs * tin_arcs
Definition: lwtin.c:89
int ngeoms
Definition: liblwgeom.h:584
#define TINTYPE
Definition: liblwgeom.h:98
LWTRIANGLE ** geoms
Definition: liblwgeom.h:586
double bz
Definition: lwtin.c:86
#define FLAGS_GET_Z(flags)
Macros for manipulating the 'flags' byte.
Definition: liblwgeom.h:139
double z
Definition: liblwgeom.h:351
uint8_t type
Definition: liblwgeom.h:580
int lwtin_is_closed(const LWTIN *tin)
Definition: lwtin.c:93
void lwtriangle_free(LWTRIANGLE *triangle)
Definition: lwtriangle.c:69
double ax
Definition: lwtin.c:85
void printPA(POINTARRAY *pa)
Definition: lwgeom_api.c:611
LWTIN * lwtin_add_lwtriangle(LWTIN *mobj, const LWTRIANGLE *obj)
Definition: lwtin.c:34
void printLWTIN(LWTIN *tin)
Definition: lwtin.c:57
void * lwalloc(size_t size)
Definition: lwutil.c:227
uint8_t flags
Definition: liblwgeom.h:581
double y
Definition: liblwgeom.h:351
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:151
double ay
Definition: lwtin.c:85
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
Definition: lwcollection.c:187
int32_t srid
Definition: liblwgeom.h:583
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:102
int getPoint4d_p(const POINTARRAY *pa, int n, POINT4D *point)
Definition: lwgeom_api.c:244