PostGIS  2.5.0beta2dev-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  }
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 }
#define LINETYPE
Definition: liblwgeom.h:85
LWCURVEPOLY * lwcurvepoly_construct_empty(int srid, char hasz, char hasm)
Definition: lwcurvepoly.c:36
LWGEOM ** rings
Definition: liblwgeom.h:537
double lwcurvepoly_perimeter_2d(const LWCURVEPOLY *poly)
Definition: lwcurvepoly.c:159
Datum area(PG_FUNCTION_ARGS)
#define CURVEPOLYTYPE
Definition: liblwgeom.h:93
#define COMPOUNDTYPE
Definition: liblwgeom.h:92
#define LW_SUCCESS
Definition: liblwgeom.h:79
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
uint8_t type
Definition: liblwgeom.h:531
double lwcurvepoly_perimeter(const LWCURVEPOLY *poly)
Definition: lwcurvepoly.c:147
GBOX * bbox
Definition: liblwgeom.h:455
LWPOLY * lwcurvepoly_stroke(const LWCURVEPOLY *curvepoly, uint32_t perQuad)
Definition: lwstroke.c:577
double lwgeom_length_2d(const LWGEOM *geom)
Definition: lwgeom.c:1946
uint32_t nrings
Definition: liblwgeom.h:457
#define LW_FAILURE
Definition: liblwgeom.h:78
unsigned int uint32_t
Definition: uthash.h:78
int lwcurvepoly_add_ring(LWCURVEPOLY *poly, LWGEOM *ring)
Add a ring, allocating extra space if necessary.
Definition: lwcurvepoly.c:72
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:218
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
Definition: lwgeom.c:330
int32_t srid
Definition: liblwgeom.h:534
GBOX * bbox
Definition: liblwgeom.h:533
void lwpoly_free(LWPOLY *poly)
Definition: lwpoly.c:175
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwline.c:42
POINTARRAY ** rings
Definition: liblwgeom.h:459
POINTARRAY * ptarray_clone_deep(const POINTARRAY *ptarray)
Deep clone a pointarray (also clones serialized pointlist)
Definition: ptarray.c:628
double lwpoly_area(const LWPOLY *poly)
Find the area of the outer ring - sum (area of inner rings).
Definition: lwpoly.c:441
double lwcurvepoly_area(const LWCURVEPOLY *curvepoly)
This should be rewritten to make use of the curve itself.
Definition: lwcurvepoly.c:133
uint8_t flags
Definition: liblwgeom.h:532
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
int32_t srid
Definition: liblwgeom.h:456
double lwgeom_length(const LWGEOM *geom)
Definition: lwgeom.c:1924
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:237
uint8_t type
Definition: liblwgeom.h:398
uint32_t nrings
Definition: liblwgeom.h:535
GBOX * gbox_clone(const GBOX *gbox)
Definition: g_box.c:52
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:91
uint8_t flags
Definition: liblwgeom.h:454
void * lwalloc(size_t size)
Definition: lwutil.c:229
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
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
LWCURVEPOLY * lwcurvepoly_construct_from_lwpoly(LWPOLY *lwpoly)
Construct an equivalent curve polygon from a polygon.
Definition: lwcurvepoly.c:53
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
uint32_t maxrings
Definition: liblwgeom.h:536