PostGIS  2.5.0beta2dev-r@@SVN_REVISION@@
lwcircstring.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 LWCIRCSTRING functions */
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 void printLWCIRCSTRING(LWCIRCSTRING *curve);
36 char lwcircstring_same(const LWCIRCSTRING *me, const LWCIRCSTRING *you);
37 LWCIRCSTRING *lwcircstring_from_lwpointarray(int srid, uint32_t npoints, LWPOINT **points);
41 void lwcircstring_setPoint4d(LWCIRCSTRING *curve, uint32_t index, POINT4D *newpoint);
42 
43 
44 
45 /*
46  * Construct a new LWCIRCSTRING. points will *NOT* be copied
47  * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
48  */
50 lwcircstring_construct(int srid, GBOX *bbox, POINTARRAY *points)
51 {
52  LWCIRCSTRING *result;
53 
54  /*
55  * The first arc requires three points. Each additional
56  * arc requires two more points. Thus the minimum point count
57  * is three, and the count must be odd.
58  */
59  if (points->npoints % 2 != 1 || points->npoints < 3)
60  {
61  lwnotice("lwcircstring_construct: invalid point count %d", points->npoints);
62  }
63 
64  result = (LWCIRCSTRING*) lwalloc(sizeof(LWCIRCSTRING));
65 
66  result->type = CIRCSTRINGTYPE;
67 
68  result->flags = points->flags;
69  FLAGS_SET_BBOX(result->flags, bbox?1:0);
70 
71  result->srid = srid;
72  result->points = points;
73  result->bbox = bbox;
74 
75  return result;
76 }
77 
79 lwcircstring_construct_empty(int srid, char hasz, char hasm)
80 {
81  LWCIRCSTRING *result = lwalloc(sizeof(LWCIRCSTRING));
82  result->type = CIRCSTRINGTYPE;
83  result->flags = gflags(hasz,hasm,0);
84  result->srid = srid;
85  result->points = ptarray_construct_empty(hasz, hasm, 1);
86  result->bbox = NULL;
87  return result;
88 }
89 
90 void
92 {
94 }
95 
96 
98 {
99  if ( ! curve ) return;
100 
101  if ( curve->bbox )
102  lwfree(curve->bbox);
103  if ( curve->points )
104  ptarray_free(curve->points);
105  lwfree(curve);
106 }
107 
108 
109 
111 {
112  lwnotice("LWCIRCSTRING {");
113  lwnotice(" ndims = %i", (int)FLAGS_NDIMS(curve->flags));
114  lwnotice(" srid = %i", (int)curve->srid);
115  printPA(curve->points);
116  lwnotice("}");
117 }
118 
119 /* @brief Clone LWCIRCSTRING object. Serialized point lists are not copied.
120  *
121  * @see ptarray_clone
122  */
123 LWCIRCSTRING *
125 {
126  return (LWCIRCSTRING *)lwline_clone((LWLINE *)g);
127 }
128 
129 /* check coordinate equality */
130 char
132 {
133  return ptarray_same(me->points, you->points);
134 }
135 
136 /*
137  * Construct a LWCIRCSTRING from an array of LWPOINTs
138  * LWCIRCSTRING dimensions are large enough to host all input dimensions.
139  */
140 LWCIRCSTRING *
141 lwcircstring_from_lwpointarray(int srid, uint32_t npoints, LWPOINT **points)
142 {
143  int zmflag=0;
144  uint32_t i;
145  POINTARRAY *pa;
146  uint8_t *newpoints, *ptr;
147  size_t ptsize, size;
148 
149  /*
150  * Find output dimensions, check integrity
151  */
152  for (i = 0; i < npoints; i++)
153  {
154  if (points[i]->type != POINTTYPE)
155  {
156  lwerror("lwcurve_from_lwpointarray: invalid input type: %s",
157  lwtype_name(points[i]->type));
158  return NULL;
159  }
160  if (FLAGS_GET_Z(points[i]->flags)) zmflag |= 2;
161  if (FLAGS_GET_M(points[i]->flags)) zmflag |= 1;
162  if (zmflag == 3) break;
163  }
164 
165  if (zmflag == 0) ptsize = 2 * sizeof(double);
166  else if (zmflag == 3) ptsize = 4 * sizeof(double);
167  else ptsize = 3 * sizeof(double);
168 
169  /*
170  * Allocate output points array
171  */
172  size = ptsize * npoints;
173  newpoints = lwalloc(size);
174  memset(newpoints, 0, size);
175 
176  ptr = newpoints;
177  for (i = 0; i < npoints; i++)
178  {
179  size = ptarray_point_size(points[i]->point);
180  memcpy(ptr, getPoint_internal(points[i]->point, 0), size);
181  ptr += ptsize;
182  }
183  pa = ptarray_construct_reference_data(zmflag&2, zmflag&1, npoints, newpoints);
184 
185  return lwcircstring_construct(srid, NULL, pa);
186 }
187 
188 /*
189  * Construct a LWCIRCSTRING from a LWMPOINT
190  */
191 LWCIRCSTRING *
193 {
194  uint32_t i;
195  POINTARRAY *pa;
196  char zmflag = FLAGS_GET_ZM(mpoint->flags);
197  size_t ptsize, size;
198  uint8_t *newpoints, *ptr;
199 
200  if (zmflag == 0) ptsize = 2 * sizeof(double);
201  else if (zmflag == 3) ptsize = 4 * sizeof(double);
202  else ptsize = 3 * sizeof(double);
203 
204  /* Allocate space for output points */
205  size = ptsize * mpoint->ngeoms;
206  newpoints = lwalloc(size);
207  memset(newpoints, 0, size);
208 
209  ptr = newpoints;
210  for (i = 0; i < mpoint->ngeoms; i++)
211  {
212  memcpy(ptr,
213  getPoint_internal(mpoint->geoms[i]->point, 0),
214  ptsize);
215  ptr += ptsize;
216  }
217 
218  pa = ptarray_construct_reference_data(zmflag&2, zmflag&1, mpoint->ngeoms, newpoints);
219 
220  LWDEBUGF(3, "lwcurve_from_lwmpoint: constructed pointarray for %d points, %d zmflag", mpoint->ngeoms, zmflag);
221 
222  return lwcircstring_construct(srid, NULL, pa);
223 }
224 
225 LWCIRCSTRING *
227 {
228  POINTARRAY *newpa;
229  LWCIRCSTRING *ret;
230 
231  newpa = ptarray_addPoint(curve->points,
232  getPoint_internal(point->point, 0),
233  FLAGS_NDIMS(point->flags), where);
234  ret = lwcircstring_construct(curve->srid, NULL, newpa);
235 
236  return ret;
237 }
238 
239 LWCIRCSTRING *
241 {
242  POINTARRAY *newpa;
243  LWCIRCSTRING *ret;
244 
245  newpa = ptarray_removePoint(curve->points, index);
246  ret = lwcircstring_construct(curve->srid, NULL, newpa);
247 
248  return ret;
249 }
250 
251 /*
252  * Note: input will be changed, make sure you have permissions for this.
253  * */
254 void
256 {
257  ptarray_set_point4d(curve->points, index, newpoint);
258 }
259 
260 int
262 {
263  if (FLAGS_GET_Z(curve->flags))
264  return ptarray_is_closed_3d(curve->points);
265 
266  return ptarray_is_closed_2d(curve->points);
267 }
268 
270 {
271  if ( !circ->points || circ->points->npoints < 1 )
272  return LW_TRUE;
273  return LW_FALSE;
274 }
275 
277 {
278  return lwcircstring_length_2d(circ);
279 }
280 
282 {
283  if ( lwcircstring_is_empty(circ) )
284  return 0.0;
285 
286  return ptarray_arc_length_2d(circ->points);
287 }
288 
289 /*
290  * Returns freshly allocated #LWPOINT that corresponds to the index where.
291  * Returns NULL if the geometry is empty or the index invalid.
292  */
294  POINT4D pt;
295  LWPOINT *lwpoint;
296  POINTARRAY *pa;
297 
298  if ( lwcircstring_is_empty(circ) || where >= circ->points->npoints )
299  return NULL;
300 
302  pt = getPoint4d(circ->points, where);
303  ptarray_append_point(pa, &pt, LW_TRUE);
304  lwpoint = lwpoint_construct(circ->srid, NULL, pa);
305  return lwpoint;
306 }
307 
308 
size_t ptarray_point_size(const POINTARRAY *pa)
Definition: ptarray.c:54
LWCIRCSTRING * lwcircstring_addpoint(LWCIRCSTRING *curve, LWPOINT *point, uint32_t where)
Definition: lwcircstring.c:226
LWCIRCSTRING * lwcircstring_from_lwpointarray(int srid, uint32_t npoints, LWPOINT **points)
Definition: lwcircstring.c:141
uint8_t flags
Definition: liblwgeom.h:443
uint32_t ngeoms
Definition: liblwgeom.h:470
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition: lwutil.c:177
void lwcircstring_setPoint4d(LWCIRCSTRING *curve, uint32_t index, POINT4D *newpoint)
Definition: lwcircstring.c:255
void lwfree(void *mem)
Definition: lwutil.c:244
double ptarray_arc_length_2d(const POINTARRAY *pts)
Find the 2d length of the given POINTARRAY, using circular arc interpolation between each coordinate ...
Definition: ptarray.c:1655
LWLINE * lwline_clone(const LWLINE *lwgeom)
Definition: lwline.c:102
int ptarray_is_closed_3d(const POINTARRAY *pa)
Definition: ptarray.c:701
LWPOINT * lwcircstring_get_lwpoint(const LWCIRCSTRING *circ, uint32_t where)
Definition: lwcircstring.c:293
int32_t srid
Definition: liblwgeom.h:445
char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
Definition: ptarray.c:478
LWGEOM * lwcircstring_as_lwgeom(const LWCIRCSTRING *obj)
Definition: lwgeom.c:305
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:328
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
Definition: lwgeom_api.c:425
#define FLAGS_GET_ZM(flags)
Definition: liblwgeom.h:152
double lwcircstring_length_2d(const LWCIRCSTRING *circ)
Definition: lwcircstring.c:281
uint8_t flags
Definition: liblwgeom.h:467
LWCIRCSTRING * lwcircstring_clone(const LWCIRCSTRING *g)
Definition: lwcircstring.c:124
POINTARRAY * point
Definition: liblwgeom.h:413
int ptarray_is_closed_2d(const POINTARRAY *pa)
Definition: ptarray.c:688
unsigned int uint32_t
Definition: uthash.h:78
POINTARRAY * ptarray_addPoint(const POINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where)
Add a point in a pointarray.
Definition: ptarray.c:503
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:218
POINT4D getPoint4d(const POINTARRAY *pa, uint32_t n)
Definition: lwgeom_api.c:96
int ptarray_append_point(POINTARRAY *pa, const POINT4D *pt, int allow_duplicates)
Append a point to the end of an existing POINTARRAY If allow_duplicate is LW_FALSE, then a duplicate point will not be added.
Definition: ptarray.c:156
#define LW_FALSE
Definition: liblwgeom.h:76
int lwcircstring_is_closed(const LWCIRCSTRING *curve)
Definition: lwcircstring.c:261
LWCIRCSTRING * lwcircstring_construct_empty(int srid, char hasz, char hasm)
Definition: lwcircstring.c:79
uint8_t flags
Definition: liblwgeom.h:371
LWCIRCSTRING * lwcircstring_removepoint(LWCIRCSTRING *curve, uint32_t index)
Definition: lwcircstring.c:240
void printLWCIRCSTRING(LWCIRCSTRING *curve)
Definition: lwcircstring.c:110
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:75
void lwcircstring_free(LWCIRCSTRING *curve)
Definition: lwcircstring.c:97
uint8_t type
Definition: liblwgeom.h:442
POINTARRAY * ptarray_construct_reference_data(char hasz, char hasm, uint32_t npoints, uint8_t *ptlist)
Construct a new POINTARRAY, referencing to the data from ptlist.
Definition: ptarray.c:293
LWPOINT ** geoms
Definition: liblwgeom.h:472
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:139
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:145
GBOX * bbox
Definition: liblwgeom.h:444
char lwcircstring_same(const LWCIRCSTRING *me, const LWCIRCSTRING *you)
Definition: lwcircstring.c:131
uint8_t flags
Definition: liblwgeom.h:410
#define FLAGS_SET_BBOX(flags, value)
Definition: liblwgeom.h:147
LWCIRCSTRING * lwcircstring_from_lwmpoint(int srid, LWMPOINT *mpoint)
Definition: lwcircstring.c:192
void printPA(POINTARRAY *pa)
Definition: lwgeom_api.c:496
uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition: ptarray.c:1743
void lwcircstring_release(LWCIRCSTRING *lwcirc)
Definition: lwcircstring.c:91
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:84
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:140
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition: lwgeom.c:459
type
Definition: ovdump.py:41
POINTARRAY * points
Definition: liblwgeom.h:446
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:91
POINTARRAY * ptarray_removePoint(POINTARRAY *pa, uint32_t where)
Remove a point from a pointarray.
Definition: ptarray.c:555
LWPOINT * lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
Definition: lwpoint.c:129
void * lwalloc(size_t size)
Definition: lwutil.c:229
int lwcircstring_is_empty(const LWCIRCSTRING *circ)
Definition: lwcircstring.c:269
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
#define FLAGS_NDIMS(flags)
Definition: liblwgeom.h:151
double lwcircstring_length(const LWCIRCSTRING *circ)
Definition: lwcircstring.c:276
unsigned char uint8_t
Definition: uthash.h:79
LWCIRCSTRING * lwcircstring_construct(int srid, GBOX *bbox, POINTARRAY *points)
Definition: lwcircstring.c:50
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
uint32_t npoints
Definition: liblwgeom.h:373