PostGIS 3.7.0dev-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, const 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 * Construct a new LWCIRCSTRING. points will *NOT* be copied
46 * use SRID=SRID_UNKNOWN for unknown SRID (will have 8bit type's S = 0)
47 */
49lwcircstring_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
50{
52
53 /*
54 * The first arc requires three points. Each additional
55 * arc requires two more points. Thus the minimum point count
56 * is three, and the count must be odd.
57 */
58 if (points->npoints % 2 != 1 || points->npoints < 3)
59 {
60 lwnotice("lwcircstring_construct: invalid point count %d", points->npoints);
61 }
62
64
65 result->type = CIRCSTRINGTYPE;
66
67 result->flags = points->flags;
68 FLAGS_SET_BBOX(result->flags, bbox?1:0);
69
70 result->srid = srid;
71 result->points = points;
72 result->bbox = bbox;
73
74 return result;
75}
76
78lwcircstring_construct_empty(int32_t srid, char hasz, char hasm)
79{
81 result->type = CIRCSTRINGTYPE;
82 result->flags = lwflags(hasz,hasm,0);
83 result->srid = srid;
84 result->points = ptarray_construct_empty(hasz, hasm, 1);
85 result->bbox = NULL;
86 return result;
87}
88
89void
94
95
97{
98 if ( ! curve ) return;
99
100 if ( curve->bbox )
101 lwfree(curve->bbox);
102 if ( curve->points )
103 ptarray_free(curve->points);
104 lwfree(curve);
105}
106
107
108
110{
111 lwnotice("LWCIRCSTRING {");
112 lwnotice(" ndims = %i", (int)FLAGS_NDIMS(curve->flags));
113 lwnotice(" srid = %i", (int)curve->srid);
114 printPA(curve->points);
115 lwnotice("}");
116}
117
118/* @brief Clone LWCIRCSTRING object. Serialized point lists are not copied.
119 *
120 * @see ptarray_clone
121 */
124{
125 return (LWCIRCSTRING *)lwline_clone((LWLINE *)g);
126}
127
128/* check coordinate equality */
129char
131{
132 return ptarray_same(me->points, you->points);
133}
134
135/*
136 * Construct a LWCIRCSTRING from an array of LWPOINTs
137 * LWCIRCSTRING dimensions are large enough to host all input dimensions.
138 */
140lwcircstring_from_lwpointarray(int32_t srid, uint32_t npoints, const LWPOINT **points)
141{
142 uint32_t i;
143 POINTARRAY *pa;
144 int has_z = 0, has_m = 0;
145 POINT4D pt;
146
147 /*
148 * Find output dimensions, check integrity
149 */
150 for (i = 0; i < npoints; i++)
151 {
152 const LWGEOM *lwg = (LWGEOM*)points[i];
153 if (lwg->type != POINTTYPE)
154 {
155 lwerror("%s: invalid input type: %s", __func__, lwtype_name(lwg->type));
156 return NULL;
157 }
158 has_z |= lwgeom_has_z(lwg);
159 has_m |= lwgeom_has_m(lwg);
160 if (has_z && has_m) break;
161 }
162
163 /*
164 * Allocate output points array
165 */
166 pa = ptarray_construct(has_z, has_m, npoints);
167
168 for (i = 0; i < npoints; i++)
169 {
170 const LWPOINT *lwpt = points[i];
171 if (!getPoint4d_p(lwpt->point, 0, &pt))
172 {
173 lwerror("%s: failed getPoint4d_p", __func__);
174 return NULL;
175 }
176 ptarray_set_point4d(pa, i, &pt);
177 }
178
179 return lwcircstring_construct(srid, NULL, pa);
180}
181
182/*
183 * Construct a LWCIRCSTRING from a LWMPOINT
184 */
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
220lwcircstring_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
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 * */
248void
249lwcircstring_setPoint4d(LWCIRCSTRING *curve, uint32_t index, POINT4D *newpoint)
250{
251 ptarray_set_point4d(curve->points, index, newpoint);
252}
253
254int
256{
257 if (lwgeom_has_z((LWGEOM*)curve))
258 return ptarray_is_closed_3d(curve->points);
259
260 return ptarray_is_closed_2d(curve->points);
261}
262
264{
265 return lwcircstring_length_2d(circ);
266}
267
269{
270 if ( lwcircstring_is_empty(circ) )
271 return 0.0;
272
273 return ptarray_arc_length_2d(circ->points);
274}
275
276/*
277 * Returns freshly allocated #LWPOINT that corresponds to the index where.
278 * Returns NULL if the geometry is empty or the index invalid.
279 */
280LWPOINT* lwcircstring_get_lwpoint(const LWCIRCSTRING *circ, uint32_t where) {
281 POINT4D pt;
282 LWPOINT *lwpoint;
283 POINTARRAY *pa;
284
285 if ( lwcircstring_is_empty(circ) || where >= circ->points->npoints )
286 return NULL;
287
289 pt = getPoint4d(circ->points, where);
291 lwpoint = lwpoint_construct(circ->srid, NULL, pa);
292 return lwpoint;
293}
294
295
char result[OUT_DOUBLE_BUFFER_SIZE]
Definition cu_print.c:267
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:107
int ptarray_is_closed_3d(const POINTARRAY *pa)
Definition ptarray.c:723
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:174
void printPA(POINTARRAY *pa)
Definition lwgeom_api.c:440
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:962
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition liblwgeom.h:102
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:165
void * lwalloc(size_t size)
Definition lwutil.c:227
void lwfree(void *mem)
Definition lwutil.c:248
#define FLAGS_NDIMS(flags)
Definition liblwgeom.h:179
#define CIRCSTRINGTYPE
Definition liblwgeom.h:109
POINTARRAY * ptarray_removePoint(POINTARRAY *pa, uint32_t where)
Remove a point from a pointarray.
Definition ptarray.c:582
#define FLAGS_GET_M(flags)
Definition liblwgeom.h:166
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition lwgeom_api.c:125
void ptarray_free(POINTARRAY *pa)
Definition ptarray.c:327
#define FLAGS_GET_ZM(flags)
Definition liblwgeom.h:180
POINTARRAY * ptarray_addPoint(const POINTARRAY *pa, uint8_t *p, size_t pdims, uint32_t where)
Add a point in a pointarray.
Definition ptarray.c:530
LWGEOM * lwcircstring_as_lwgeom(const LWCIRCSTRING *obj)
Definition lwgeom.c:342
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:710
lwflags_t lwflags(int hasz, int hasm, int geodetic)
Construct a new flags bitmask.
Definition lwutil.c:477
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:93
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition lwgeom.c:496
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition lwgeom.c:969
void ptarray_set_point4d(POINTARRAY *pa, uint32_t n, const POINT4D *p4d)
Definition lwgeom_api.c:369
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
Definition ptarray.c:51
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:1948
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)
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)
LWCIRCSTRING * lwcircstring_from_lwpointarray(int32_t srid, uint32_t npoints, const LWPOINT **points)
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
void lwnotice(const char *fmt,...) __attribute__((format(printf
Write a notice out to the notice handler.
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition lwinline.h:75
int32_t srid
Definition liblwgeom.h:508
lwflags_t flags
Definition liblwgeom.h:509
POINTARRAY * points
Definition liblwgeom.h:507
GBOX * bbox
Definition liblwgeom.h:506
uint8_t type
Definition liblwgeom.h:462
lwflags_t flags
Definition liblwgeom.h:535
uint32_t ngeoms
Definition liblwgeom.h:538
LWPOINT ** geoms
Definition liblwgeom.h:533
POINTARRAY * point
Definition liblwgeom.h:471
lwflags_t flags
Definition liblwgeom.h:473
lwflags_t flags
Definition liblwgeom.h:431
uint32_t npoints
Definition liblwgeom.h:427