PostGIS  2.4.9dev-r@@SVN_REVISION@@
lwtriangle.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) 2010 - Oslandia
22  *
23  **********************************************************************/
24 
25 
26 /* basic LWTRIANGLE manipulation */
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include "liblwgeom_internal.h"
32 #include "lwgeom_log.h"
33 
34 
35 
36 /* construct a new LWTRIANGLE.
37  * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
38  */
40 lwtriangle_construct(int srid, GBOX *bbox, POINTARRAY *points)
41 {
42  LWTRIANGLE *result;
43 
44  result = (LWTRIANGLE*) lwalloc(sizeof(LWTRIANGLE));
45  result->type = TRIANGLETYPE;
46 
47  result->flags = points->flags;
48  FLAGS_SET_BBOX(result->flags, bbox?1:0);
49 
50  result->srid = srid;
51  result->points = points;
52  result->bbox = bbox;
53 
54  return result;
55 }
56 
58 lwtriangle_construct_empty(int srid, char hasz, char hasm)
59 {
60  LWTRIANGLE *result = lwalloc(sizeof(LWTRIANGLE));
61  result->type = TRIANGLETYPE;
62  result->flags = gflags(hasz,hasm,0);
63  result->srid = srid;
64  result->points = ptarray_construct_empty(hasz, hasm, 1);
65  result->bbox = NULL;
66  return result;
67 }
68 
69 void lwtriangle_free(LWTRIANGLE *triangle)
70 {
71  if ( ! triangle ) return;
72 
73  if (triangle->bbox)
74  lwfree(triangle->bbox);
75 
76  if (triangle->points)
77  ptarray_free(triangle->points);
78 
79  lwfree(triangle);
80 }
81 
82 void printLWTRIANGLE(LWTRIANGLE *triangle)
83 {
84  if (triangle->type != TRIANGLETYPE)
85  lwerror("printLWTRIANGLE called with something else than a Triangle");
86 
87  lwnotice("LWTRIANGLE {");
88  lwnotice(" ndims = %i", (int)FLAGS_NDIMS(triangle->flags));
89  lwnotice(" SRID = %i", (int)triangle->srid);
90  printPA(triangle->points);
91  lwnotice("}");
92 }
93 
94 /* @brief Clone LWTRIANGLE object. Serialized point lists are not copied.
95  *
96  * @see ptarray_clone
97  */
98 LWTRIANGLE *
100 {
101  LWDEBUGF(2, "lwtriangle_clone called with %p", g);
102  return (LWTRIANGLE *)lwline_clone((const LWLINE *)g);
103 }
104 
105 void
107 {
108  if ( ptarray_isccw(triangle->points) )
109  ptarray_reverse(triangle->points);
110 }
111 
112 int
114 {
115  return !ptarray_isccw(triangle->points);
116 }
117 
118 void
120 {
121  if( lwtriangle_is_empty(triangle) ) return;
122  ptarray_reverse(triangle->points);
123 }
124 
125 void
127 {
129 }
130 
131 /* check coordinate equality */
132 char
133 lwtriangle_same(const LWTRIANGLE *t1, const LWTRIANGLE *t2)
134 {
135  char r = ptarray_same(t1->points, t2->points);
136  LWDEBUGF(5, "returning %d", r);
137  return r;
138 }
139 
140 /*
141  * Construct a triangle from a LWLINE being
142  * the shell
143  * Pointarray from intput geom are cloned.
144  * Input line must have 4 points, and be closed.
145  */
146 LWTRIANGLE *
148 {
149  LWTRIANGLE *ret;
150  POINTARRAY *pa;
151 
152  if ( shell->points->npoints != 4 )
153  lwerror("lwtriangle_from_lwline: shell must have exactly 4 points");
154 
155  if ( (!FLAGS_GET_Z(shell->flags) && !ptarray_is_closed_2d(shell->points)) ||
156  (FLAGS_GET_Z(shell->flags) && !ptarray_is_closed_3d(shell->points)) )
157  lwerror("lwtriangle_from_lwline: shell must be closed");
158 
159  pa = ptarray_clone_deep(shell->points);
160  ret = lwtriangle_construct(shell->srid, NULL, pa);
161 
163  lwerror("lwtriangle_from_lwline: some points are repeated in triangle");
164 
165  return ret;
166 }
167 
168 char
170 {
171  char ret;
172  POINTARRAY *pa;
173 
174  pa = ptarray_remove_repeated_points(triangle->points, 0.0);
175  ret = ptarray_same(pa, triangle->points);
176  ptarray_free(pa);
177 
178  return ret;
179 }
180 
181 int lwtriangle_is_empty(const LWTRIANGLE *triangle)
182 {
183  if ( !triangle->points || triangle->points->npoints < 1 )
184  return LW_TRUE;
185  return LW_FALSE;
186 }
187 
191 double
192 lwtriangle_area(const LWTRIANGLE *triangle)
193 {
194  double area=0.0;
195  int i;
196  POINT2D p1;
197  POINT2D p2;
198 
199  if (! triangle->points->npoints) return area; /* empty triangle */
200 
201  for (i=0; i < triangle->points->npoints-1; i++)
202  {
203  getPoint2d_p(triangle->points, i, &p1);
204  getPoint2d_p(triangle->points, i+1, &p2);
205  area += ( p1.x * p2.y ) - ( p1.y * p2.x );
206  }
207 
208  area /= 2.0;
209 
210  return fabs(area);
211 }
212 
213 
214 double
216 {
217  if( triangle->points )
218  return ptarray_length(triangle->points);
219  else
220  return 0.0;
221 }
222 
223 double
225 {
226  if( triangle->points )
227  return ptarray_length_2d(triangle->points);
228  else
229  return 0.0;
230 }
int lwtriangle_is_empty(const LWTRIANGLE *triangle)
Definition: lwtriangle.c:181
POINTARRAY * ptarray_remove_repeated_points(const POINTARRAY *in, double tolerance)
Definition: ptarray.c:1546
POINTARRAY * points
Definition: liblwgeom.h:433
double lwtriangle_area(const LWTRIANGLE *triangle)
Find the area of the outer ring.
Definition: lwtriangle.c:192
char * r
Definition: cu_in_wkt.c:24
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:177
LWTRIANGLE * lwtriangle_construct_empty(int srid, char hasz, char hasm)
Definition: lwtriangle.c:58
void lwfree(void *mem)
Definition: lwutil.c:244
LWLINE * lwline_clone(const LWLINE *lwgeom)
Definition: lwline.c:102
int npoints
Definition: liblwgeom.h:371
int ptarray_is_closed_3d(const POINTARRAY *pa)
Definition: ptarray.c:710
void lwtriangle_release(LWTRIANGLE *lwtriangle)
Definition: lwtriangle.c:126
Datum area(PG_FUNCTION_ARGS)
LWTRIANGLE * lwtriangle_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwtriangle.c:40
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition: ptarray.c:70
void ptarray_free(POINTARRAY *pa)
Definition: ptarray.c:330
double ptarray_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY (even if it&#39;s 3d)
Definition: ptarray.c:1692
POINT2D * p1
Definition: lwtree.h:33
#define TRIANGLETYPE
Definition: liblwgeom.h:98
LWTRIANGLE * lwtriangle_clone(const LWTRIANGLE *g)
Definition: lwtriangle.c:99
GBOX * bbox
Definition: liblwgeom.h:431
int32_t srid
Definition: liblwgeom.h:421
int ptarray_is_closed_2d(const POINTARRAY *pa)
Definition: ptarray.c:697
uint8_t type
Definition: liblwgeom.h:429
POINT2D * p2
Definition: lwtree.h:34
char lwtriangle_is_repeated_points(LWTRIANGLE *triangle)
Definition: lwtriangle.c:169
double x
Definition: liblwgeom.h:328
int ptarray_isccw(const POINTARRAY *pa)
Definition: ptarray.c:1029
void lwtriangle_free(LWTRIANGLE *triangle)
Definition: lwtriangle.c:69
#define LW_FALSE
Definition: liblwgeom.h:77
uint8_t flags
Definition: liblwgeom.h:369
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
void lwtriangle_reverse(LWTRIANGLE *triangle)
Definition: lwtriangle.c:119
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:630
LWGEOM * lwtriangle_as_lwgeom(const LWTRIANGLE *obj)
Definition: lwgeom.c:293
double y
Definition: liblwgeom.h:328
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
Definition: lwgeom_api.c:347
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:140
int lwtriangle_is_clockwise(LWTRIANGLE *triangle)
Definition: lwtriangle.c:113
LWTRIANGLE * lwtriangle_from_lwline(const LWLINE *shell)
Definition: lwtriangle.c:147
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
void printLWTRIANGLE(LWTRIANGLE *triangle)
Definition: lwtriangle.c:82
double ptarray_length(const POINTARRAY *pts)
Find the 3d/2d length of the given POINTARRAY (depending on its dimensionality)
Definition: ptarray.c:1720
#define FLAGS_SET_BBOX(flags, value)
Definition: liblwgeom.h:148
void printPA(POINTARRAY *pa)
Definition: lwgeom_api.c:472
char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
Definition: ptarray.c:479
char lwtriangle_same(const LWTRIANGLE *t1, const LWTRIANGLE *t2)
Definition: lwtriangle.c:133
void ptarray_reverse(POINTARRAY *pa)
Definition: ptarray.c:343
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition: lwgeom.c:421
double lwtriangle_perimeter_2d(const LWTRIANGLE *triangle)
Definition: lwtriangle.c:224
void * lwalloc(size_t size)
Definition: lwutil.c:229
void lwtriangle_force_clockwise(LWTRIANGLE *triangle)
Definition: lwtriangle.c:106
uint8_t flags
Definition: liblwgeom.h:419
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:152
double lwtriangle_perimeter(const LWTRIANGLE *triangle)
Definition: lwtriangle.c:215
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
int32_t srid
Definition: liblwgeom.h:432
uint8_t flags
Definition: liblwgeom.h:430
POINTARRAY * points
Definition: liblwgeom.h:422