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