PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
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
36char lwcircstring_same(const LWCIRCSTRING *me, const LWCIRCSTRING *you);
37LWCIRCSTRING *lwcircstring_from_lwpointarray(int32_t srid, uint32_t npoints, LWPOINT **points);
39LWCIRCSTRING *lwcircstring_addpoint(LWCIRCSTRING *curve, LWPOINT *point, uint32_t where);
41void 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 */
50lwcircstring_construct(int32_t 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
79lwcircstring_construct_empty(int32_t srid, char hasz, char hasm)
80{
81 LWCIRCSTRING *result = lwalloc(sizeof(LWCIRCSTRING));
82 result->type = CIRCSTRINGTYPE;
83 result->flags = lwflags(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
90void
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 */
125{
126 return (LWCIRCSTRING *)lwline_clone((LWLINE *)g);
127}
128
129/* check coordinate equality */
130char
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 */
141lwcircstring_from_lwpointarray(int32_t 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 */
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
226lwcircstring_addpoint(LWCIRCSTRING *curve, LWPOINT *point, uint32_t where)
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
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 * */
254void
255lwcircstring_setPoint4d(LWCIRCSTRING *curve, uint32_t index, POINT4D *newpoint)
256{
257 ptarray_set_point4d(curve->points, index, newpoint);
258}
259
260int
262{
263 if (lwgeom_has_z((LWGEOM*)curve))
264 return ptarray_is_closed_3d(curve->points);
265
266 return ptarray_is_closed_2d(curve->points);
267}
268
270{
271 return lwcircstring_length_2d(circ);
272}
273
275{
276 if ( lwcircstring_is_empty(circ) )
277 return 0.0;
278
279 return ptarray_arc_length_2d(circ->points);
280}
281
282/*
283 * Returns freshly allocated #LWPOINT that corresponds to the index where.
284 * Returns NULL if the geometry is empty or the index invalid.
285 */
286LWPOINT* lwcircstring_get_lwpoint(const LWCIRCSTRING *circ, uint32_t where) {
287 POINT4D pt;
288 LWPOINT *lwpoint;
289 POINTARRAY *pa;
290
291 if ( lwcircstring_is_empty(circ) || where >= circ->points->npoints )
292 return NULL;
293
295 pt = getPoint4d(circ->points, where);
297 lwpoint = lwpoint_construct(circ->srid, NULL, pa);
298 return lwpoint;
299}
300
301
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition lwutil.c:216
POINT4D getPoint4d(const POINTARRAY *pa, uint32_t n)
Definition lwgeom_api.c:108
int ptarray_is_closed_3d(const POINTARRAY *pa)
Definition ptarray.c:714
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:291
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
Definition lwpoint.c:129
#define FLAGS_SET_BBOX(flags, value)
Definition liblwgeom.h:188
void printPA(POINTARRAY *pa)
Definition lwgeom_api.c:447
POINTARRAY * ptarray_construct_empty(char hasz, char hasm, uint32_t maxpoints)
Create a new POINTARRAY with no points.
Definition ptarray.c:59
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:916
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:116
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:179
void * lwalloc(size_t size)
Definition lwutil.c:227
void lwfree(void *mem)
Definition lwutil.c:242
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:193
#define CIRCSTRINGTYPE
Definition liblwgeom.h:123
POINTARRAY * ptarray_removePoint(POINTARRAY *pa, uint32_t where)
Remove a point from a pointarray.
Definition ptarray.c:561
#define FLAGS_GET_M(flags)
Definition liblwgeom.h:180
void ptarray_free(POINTARRAY *pa)
Definition ptarray.c:327
#define FLAGS_GET_ZM(flags)
Definition liblwgeom.h:194
POINTARRAY * ptarray_addPoint(const POINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where)
Add a point in a pointarray.
Definition ptarray.c:509
LWGEOM * lwcircstring_as_lwgeom(const LWCIRCSTRING *obj)
Definition lwgeom.c:296
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,...
Definition ptarray.c:147
int ptarray_is_closed_2d(const POINTARRAY *pa)
Definition ptarray.c:701
lwflags_t lwflags(int hasz, int hasm, int geodetic)
Construct a new flags bitmask.
Definition lwutil.c:471
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition lwgeom.c:450
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
Definition lwgeom_api.c:376
char ptarray_same(const POINTARRAY *pa1, const POINTARRAY *pa2)
Definition ptarray.c:484
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:1681
LWLINE * lwline_clone(const LWLINE *lwgeom)
Definition lwline.c:93
int lwcircstring_is_empty(const LWCIRCSTRING *circ)
LWCIRCSTRING * lwcircstring_from_lwmpoint(int32_t srid, LWMPOINT *mpoint)
double lwcircstring_length_2d(const LWCIRCSTRING *circ)
int lwcircstring_is_closed(const LWCIRCSTRING *curve)
LWCIRCSTRING * lwcircstring_addpoint(LWCIRCSTRING *curve, LWPOINT *point, uint32_t where)
void lwcircstring_setPoint4d(LWCIRCSTRING *curve, uint32_t index, POINT4D *newpoint)
LWPOINT * lwcircstring_get_lwpoint(const LWCIRCSTRING *circ, uint32_t where)
LWCIRCSTRING * lwcircstring_removepoint(LWCIRCSTRING *curve, uint32_t index)
char lwcircstring_same(const LWCIRCSTRING *me, const LWCIRCSTRING *you)
LWCIRCSTRING * lwcircstring_from_lwpointarray(int32_t srid, uint32_t npoints, LWPOINT **points)
void lwcircstring_free(LWCIRCSTRING *curve)
void printLWCIRCSTRING(LWCIRCSTRING *curve)
void lwcircstring_release(LWCIRCSTRING *lwcirc)
LWCIRCSTRING * lwcircstring_construct_empty(int32_t srid, char hasz, char hasm)
LWCIRCSTRING * lwcircstring_clone(const LWCIRCSTRING *g)
double lwcircstring_length(const LWCIRCSTRING *circ)
LWCIRCSTRING * lwcircstring_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
#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
void lwnotice(const char *fmt,...)
Write a notice out to the notice handler.
Definition lwutil.c:177
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition lwinline.h:67
static size_t ptarray_point_size(const POINTARRAY *pa)
Definition lwinline.h:48
uint8_t type
Definition liblwgeom.h:496
int32_t srid
Definition liblwgeom.h:494
lwflags_t flags
Definition liblwgeom.h:495
POINTARRAY * points
Definition liblwgeom.h:493
GBOX * bbox
Definition liblwgeom.h:492
lwflags_t flags
Definition liblwgeom.h:521
uint32_t ngeoms
Definition liblwgeom.h:524
LWPOINT ** geoms
Definition liblwgeom.h:519
POINTARRAY * point
Definition liblwgeom.h:457
lwflags_t flags
Definition liblwgeom.h:459
lwflags_t flags
Definition liblwgeom.h:417
uint32_t npoints
Definition liblwgeom.h:413