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