PostGIS  2.5.7dev-r@@SVN_REVISION@@
lwcurvepoly.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 /* basic LWCURVEPOLY 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 
36 lwcurvepoly_construct_empty(int srid, char hasz, char hasm)
37 {
38  LWCURVEPOLY *ret;
39 
40  ret = lwalloc(sizeof(LWCURVEPOLY));
41  ret->type = CURVEPOLYTYPE;
42  ret->flags = gflags(hasz, hasm, 0);
43  ret->srid = srid;
44  ret->nrings = 0;
45  ret->maxrings = 1; /* Allocate room for sub-members, just in case. */
46  ret->rings = lwalloc(ret->maxrings * sizeof(LWGEOM*));
47  ret->bbox = NULL;
48 
49  return ret;
50 }
51 
54 {
55  LWCURVEPOLY *ret;
56  uint32_t i;
57  ret = lwalloc(sizeof(LWCURVEPOLY));
58  ret->type = CURVEPOLYTYPE;
59  ret->flags = lwpoly->flags;
60  ret->srid = lwpoly->srid;
61  ret->nrings = lwpoly->nrings;
62  ret->maxrings = lwpoly->nrings; /* Allocate room for sub-members, just in case. */
63  ret->rings = lwalloc(ret->maxrings * sizeof(LWGEOM*));
64  ret->bbox = lwpoly->bbox ? gbox_clone(lwpoly->bbox) : NULL;
65  for ( i = 0; i < ret->nrings; i++ )
66  {
67  ret->rings[i] = lwline_as_lwgeom(lwline_construct(ret->srid, NULL, ptarray_clone_deep(lwpoly->rings[i])));
68  }
69  return ret;
70 }
71 
73 {
74  uint32_t i;
75 
76  /* Can't do anything with NULLs */
77  if( ! poly || ! ring )
78  {
79  LWDEBUG(4,"NULL inputs!!! quitting");
80  return LW_FAILURE;
81  }
82 
83  /* Check that we're not working with garbage */
84  if ( poly->rings == NULL && (poly->nrings || poly->maxrings) )
85  {
86  LWDEBUG(4,"mismatched nrings/maxrings");
87  lwerror("Curvepolygon is in inconsistent state. Null memory but non-zero collection counts.");
88  return LW_FAILURE;
89  }
90 
91  /* Check that we're adding an allowed ring type */
92  if ( ! ( ring->type == LINETYPE || ring->type == CIRCSTRINGTYPE || ring->type == COMPOUNDTYPE ) )
93  {
94  LWDEBUGF(4,"got incorrect ring type: %s",lwtype_name(ring->type));
95  return LW_FAILURE;
96  }
97 
98 
99  /* In case this is a truly empty, make some initial space */
100  if ( poly->rings == NULL )
101  {
102  poly->maxrings = 2;
103  poly->nrings = 0;
104  poly->rings = lwalloc(poly->maxrings * sizeof(LWGEOM*));
105  }
106 
107  /* Allocate more space if we need it */
108  if ( poly->nrings == poly->maxrings )
109  {
110  poly->maxrings *= 2;
111  poly->rings = lwrealloc(poly->rings, sizeof(LWGEOM*) * poly->maxrings);
112  }
113 
114  /* Make sure we don't already have a reference to this geom */
115  for ( i = 0; i < poly->nrings; i++ )
116  {
117  if ( poly->rings[i] == ring )
118  {
119  LWDEBUGF(4, "Found duplicate geometry in collection %p == %p", poly->rings[i], ring);
120  return LW_SUCCESS;
121  }
122  }
123 
124  /* Add the ring and increment the ring count */
125  poly->rings[poly->nrings] = (LWGEOM*)ring;
126  poly->nrings++;
127  return LW_SUCCESS;
128 }
129 
133 double
134 lwcurvepoly_area(const LWCURVEPOLY *curvepoly)
135 {
136  double area = 0.0;
137  LWPOLY *poly;
138  if( lwgeom_is_empty((LWGEOM*)curvepoly) )
139  return 0.0;
140  poly = lwcurvepoly_stroke(curvepoly, 32);
141  area = lwpoly_area(poly);
142  lwpoly_free(poly);
143  return area;
144 }
145 
146 
147 double
149 {
150  double result=0.0;
151  uint32_t i;
152 
153  for (i=0; i<poly->nrings; i++)
154  result += lwgeom_length(poly->rings[i]);
155 
156  return result;
157 }
158 
159 double
161 {
162  double result=0.0;
163  uint32_t i;
164 
165  for (i=0; i<poly->nrings; i++)
166  result += lwgeom_length_2d(poly->rings[i]);
167 
168  return result;
169 }
GBOX * gbox_clone(const GBOX *gbox)
Definition: g_box.c:52
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:330
#define COMPOUNDTYPE
Definition: liblwgeom.h:93
#define LW_FAILURE
Definition: liblwgeom.h:79
#define CURVEPOLYTYPE
Definition: liblwgeom.h:94
#define LINETYPE
Definition: liblwgeom.h:86
#define LW_SUCCESS
Definition: liblwgeom.h:80
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:628
double lwgeom_length(const LWGEOM *geom)
Definition: lwgeom.c:1939
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:237
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:92
double lwgeom_length_2d(const LWGEOM *geom)
Definition: lwgeom.c:1961
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:218
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition: lwgeom.c:1393
void * lwalloc(size_t size)
Definition: lwutil.c:229
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:175
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
double lwpoly_area(const LWPOLY *poly)
Find the area of the outer ring - sum (area of inner rings).
Definition: lwpoly.c:441
LWPOLY * lwcurvepoly_stroke(const LWCURVEPOLY *curvepoly, uint32_t perQuad)
Definition: lwstroke.c:585
LWCURVEPOLY * lwcurvepoly_construct_empty(int srid, char hasz, char hasm)
Definition: lwcurvepoly.c:36
LWCURVEPOLY * lwcurvepoly_construct_from_lwpoly(LWPOLY *lwpoly)
Construct an equivalent curve polygon from a polygon.
Definition: lwcurvepoly.c:53
int lwcurvepoly_add_ring(LWCURVEPOLY *poly, LWGEOM *ring)
Add a ring, allocating extra space if necessary.
Definition: lwcurvepoly.c:72
double lwcurvepoly_perimeter(const LWCURVEPOLY *poly)
Definition: lwcurvepoly.c:148
double lwcurvepoly_area(const LWCURVEPOLY *curvepoly)
This should be rewritten to make use of the curve itself.
Definition: lwcurvepoly.c:134
double lwcurvepoly_perimeter_2d(const LWCURVEPOLY *poly)
Definition: lwcurvepoly.c:160
Datum area(PG_FUNCTION_ARGS)
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
int32_t srid
Definition: liblwgeom.h:535
GBOX * bbox
Definition: liblwgeom.h:534
uint8_t type
Definition: liblwgeom.h:532
LWGEOM ** rings
Definition: liblwgeom.h:538
uint8_t flags
Definition: liblwgeom.h:533
uint32_t nrings
Definition: liblwgeom.h:536
uint32_t maxrings
Definition: liblwgeom.h:537
uint8_t type
Definition: liblwgeom.h:399
POINTARRAY ** rings
Definition: liblwgeom.h:460
uint32_t nrings
Definition: liblwgeom.h:458
uint8_t flags
Definition: liblwgeom.h:455
GBOX * bbox
Definition: liblwgeom.h:456
int32_t srid
Definition: liblwgeom.h:457
unsigned int uint32_t
Definition: uthash.h:78