PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwpsurface.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#include "liblwgeom_internal.h"
30#include "lwgeom_log.h"
31
32
37
38
40{
41 uint32_t i;
42 if ( ! psurf ) return;
43 if ( psurf->bbox )
44 lwfree(psurf->bbox);
45
46 for ( i = 0; i < psurf->ngeoms; i++ )
47 if ( psurf->geoms && psurf->geoms[i] )
48 lwpoly_free(psurf->geoms[i]);
49
50 if ( psurf->geoms )
51 lwfree(psurf->geoms);
52
53 lwfree(psurf);
54}
55
56
58{
59 uint32_t i, j;
60 LWPOLY *patch;
61
62 if (psurf->type != POLYHEDRALSURFACETYPE)
63 lwerror("printLWPSURFACE called with something else than a POLYHEDRALSURFACE");
64
65 lwnotice("LWPSURFACE {");
66 lwnotice(" ndims = %i", (int)FLAGS_NDIMS(psurf->flags));
67 lwnotice(" SRID = %i", (int)psurf->srid);
68 lwnotice(" ngeoms = %i", (int)psurf->ngeoms);
69
70 for (i=0; i<psurf->ngeoms; i++)
71 {
72 patch = (LWPOLY *) psurf->geoms[i];
73 for (j=0; j<patch->nrings; j++)
74 {
75 lwnotice(" RING # %i :",j);
76 printPA(patch->rings[j]);
77 }
78 }
79 lwnotice("}");
80}
81
82
83
84
85/*
86 * TODO rewrite all this stuff to be based on a truly topological model
87 */
88
90{
91 double ax, ay, az;
92 double bx, by, bz;
93 uint32_t cnt, face;
94};
96
97/* We supposed that the geometry is valid
98 we could have wrong result if not */
99int lwpsurface_is_closed(const LWPSURFACE *psurface)
100{
101 uint32_t i, j, k;
102 uint32_t narcs, carc;
103 int found;
104 psurface_arcs arcs;
105 POINT4D pa, pb;
106 LWPOLY *patch;
107
108 /* If surface is not 3D, it's can't be closed */
109 if (!FLAGS_GET_Z(psurface->flags)) return 0;
110
111 /* If surface is less than 4 faces hard to be closed too */
112 if (psurface->ngeoms < 4) return 0;
113
114 /* Max theoretical arcs number if no one is shared ... */
115 for (i=0, narcs=0 ; i < psurface->ngeoms ; i++)
116 {
117 patch = (LWPOLY *) psurface->geoms[i];
118 narcs += patch->rings[0]->npoints - 1;
119 }
120
121 arcs = lwalloc(sizeof(struct struct_psurface_arcs) * narcs);
122 for (i=0, carc=0; i < psurface->ngeoms ; i++)
123 {
124
125 patch = (LWPOLY *) psurface->geoms[i];
126 for (j=0; j < patch->rings[0]->npoints - 1; j++)
127 {
128
129 getPoint4d_p(patch->rings[0], j, &pa);
130 getPoint4d_p(patch->rings[0], j+1, &pb);
131
132 /* remove redundant points if any */
133 if (pa.x == pb.x && pa.y == pb.y && pa.z == pb.z) continue;
134
135 /* Make sure to order the 'lower' point first */
136 if ( (pa.x > pb.x) ||
137 (pa.x == pb.x && pa.y > pb.y) ||
138 (pa.x == pb.x && pa.y == pb.y && pa.z > pb.z) )
139 {
140 pa = pb;
141 getPoint4d_p(patch->rings[0], j, &pb);
142 }
143
144 for (found=0, k=0; k < carc ; k++)
145 {
146
147 if ( ( arcs[k].ax == pa.x && arcs[k].ay == pa.y &&
148 arcs[k].az == pa.z && arcs[k].bx == pb.x &&
149 arcs[k].by == pb.y && arcs[k].bz == pb.z &&
150 arcs[k].face != i) )
151 {
152 arcs[k].cnt++;
153 found = 1;
154
155 /* Look like an invalid PolyhedralSurface
156 anyway not a closed one */
157 if (arcs[k].cnt > 2)
158 {
159 lwfree(arcs);
160 return 0;
161 }
162 }
163 }
164
165 if (!found)
166 {
167 arcs[carc].cnt=1;
168 arcs[carc].face=i;
169 arcs[carc].ax = pa.x;
170 arcs[carc].ay = pa.y;
171 arcs[carc].az = pa.z;
172 arcs[carc].bx = pb.x;
173 arcs[carc].by = pb.y;
174 arcs[carc].bz = pb.z;
175 carc++;
176
177 /* Look like an invalid PolyhedralSurface
178 anyway not a closed one */
179 if (carc > narcs)
180 {
181 lwfree(arcs);
182 return 0;
183 }
184 }
185 }
186 }
187
188 /* A polyhedron is closed if each edge
189 is shared by exactly 2 faces */
190 for (k=0; k < carc ; k++)
191 {
192 if (arcs[k].cnt != 2)
193 {
194 lwfree(arcs);
195 return 0;
196 }
197 }
198 lwfree(arcs);
199
200 /* Invalid Polyhedral case */
201 if (carc < psurface->ngeoms) return 0;
202
203 return 1;
204}
void printPA(POINTARRAY *pa)
Definition lwgeom_api.c:440
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
void * lwalloc(size_t size)
Definition lwutil.c:227
void lwfree(void *mem)
Definition lwutil.c:248
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:179
#define POLYHEDRALSURFACETYPE
Definition liblwgeom.h:114
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition lwgeom_api.c:125
void lwpoly_free(LWPOLY *poly)
Definition lwpoly.c:175
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
void lwnotice(const char *fmt,...) __attribute__((format(printf
Write a notice out to the notice handler.
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
LWPSURFACE * lwpsurface_add_lwpoly(LWPSURFACE *mobj, const LWPOLY *obj)
Definition lwpsurface.c:33
int lwpsurface_is_closed(const LWPSURFACE *psurface)
Definition lwpsurface.c:99
struct struct_psurface_arcs * psurface_arcs
Definition lwpsurface.c:95
void lwpsurface_free(LWPSURFACE *psurf)
Definition lwpsurface.c:39
void printLWPSURFACE(LWPSURFACE *psurf)
Definition lwpsurface.c:57
POINTARRAY ** rings
Definition liblwgeom.h:519
uint32_t nrings
Definition liblwgeom.h:524
lwflags_t flags
Definition liblwgeom.h:647
LWPOLY ** geoms
Definition liblwgeom.h:645
uint32_t ngeoms
Definition liblwgeom.h:650
uint8_t type
Definition liblwgeom.h:648
int32_t srid
Definition liblwgeom.h:646
GBOX * bbox
Definition liblwgeom.h:644
double x
Definition liblwgeom.h:414
double z
Definition liblwgeom.h:414
double y
Definition liblwgeom.h:414
uint32_t npoints
Definition liblwgeom.h:427