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