PostGIS 3.0.6dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
lwcompound.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#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include "liblwgeom_internal.h"
30#include "lwgeom_log.h"
31
32
33
34int
36{
37 size_t size;
38 int npoints=0;
39
40 if ( lwgeom_has_z((LWGEOM*)compound) )
41 {
42 size = sizeof(POINT3D);
43 }
44 else
45 {
46 size = sizeof(POINT2D);
47 }
48
49 if ( compound->geoms[compound->ngeoms - 1]->type == CIRCSTRINGTYPE )
50 {
51 npoints = ((LWCIRCSTRING *)compound->geoms[compound->ngeoms - 1])->points->npoints;
52 }
53 else if (compound->geoms[compound->ngeoms - 1]->type == LINETYPE)
54 {
55 npoints = ((LWLINE *)compound->geoms[compound->ngeoms - 1])->points->npoints;
56 }
57
58 if ( memcmp(getPoint_internal( (POINTARRAY *)compound->geoms[0]->data, 0),
59 getPoint_internal( (POINTARRAY *)compound->geoms[compound->ngeoms - 1]->data,
60 npoints - 1),
61 size) )
62 {
63 return LW_FALSE;
64 }
65
66 return LW_TRUE;
67}
68
69double lwcompound_length(const LWCOMPOUND *comp)
70{
71 return lwcompound_length_2d(comp);
72}
73
75{
76 uint32_t i;
77 double length = 0.0;
78 if ( lwgeom_is_empty((LWGEOM*)comp) )
79 return 0.0;
80
81 for (i = 0; i < comp->ngeoms; i++)
82 {
83 length += lwgeom_length_2d(comp->geoms[i]);
84 }
85 return length;
86}
87
89{
90 LWCOLLECTION *col = (LWCOLLECTION*)comp;
91
92 /* Empty things can't continuously join up with other things */
93 if ( lwgeom_is_empty(geom) )
94 {
95 LWDEBUG(4, "Got an empty component for a compound curve!");
96 return LW_FAILURE;
97 }
98
99 if( col->ngeoms > 0 )
100 {
101 POINT4D last, first;
102 /* First point of the component we are adding */
103 LWLINE *newline = (LWLINE*)geom;
104 /* Last point of the previous component */
105 LWLINE *prevline = (LWLINE*)(col->geoms[col->ngeoms-1]);
106
107 getPoint4d_p(newline->points, 0, &first);
108 getPoint4d_p(prevline->points, prevline->points->npoints-1, &last);
109
110 if ( !(FP_EQUALS(first.x,last.x) && FP_EQUALS(first.y,last.y)) )
111 {
112 LWDEBUG(4, "Components don't join up end-to-end!");
113 LWDEBUGF(4, "first pt (%g %g %g %g) last pt (%g %g %g %g)", first.x, first.y, first.z, first.m, last.x, last.y, last.z, last.m);
114 return LW_FAILURE;
115 }
116 }
117
118 col = lwcollection_add_lwgeom(col, geom);
119 return LW_SUCCESS;
120}
121
123lwcompound_construct_empty(int32_t srid, char hasz, char hasm)
124{
126 return ret;
127}
128
129int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt)
130{
131 switch( geom->type )
132 {
133 case LINETYPE:
134 return ptarray_contains_point(((LWLINE*)geom)->points, pt);
135 case CIRCSTRINGTYPE:
136 return ptarrayarc_contains_point(((LWCIRCSTRING*)geom)->points, pt);
137 case COMPOUNDTYPE:
138 return lwcompound_contains_point((LWCOMPOUND*)geom, pt);
139 }
140 lwerror("lwgeom_contains_point failed");
141 return LW_FAILURE;
142}
143
144int
146{
147 uint32_t i;
148 LWLINE *lwline;
149 LWCIRCSTRING *lwcirc;
150 int wn = 0;
151 int winding_number = 0;
152 int result;
153
154 for ( i = 0; i < comp->ngeoms; i++ )
155 {
156 LWGEOM *lwgeom = comp->geoms[i];
157 if ( lwgeom->type == LINETYPE )
158 {
159 lwline = lwgeom_as_lwline(lwgeom);
160 if ( comp->ngeoms == 1 )
161 {
162 return ptarray_contains_point(lwline->points, pt);
163 }
164 else
165 {
166 /* Don't check closure while doing p-i-p test */
167 result = ptarray_contains_point_partial(lwline->points, pt, LW_FALSE, &winding_number);
168 }
169 }
170 else
171 {
172 lwcirc = lwgeom_as_lwcircstring(lwgeom);
173 if ( ! lwcirc ) {
174 lwerror("Unexpected component of type %s in compound curve", lwtype_name(lwgeom->type));
175 return 0;
176 }
177 if ( comp->ngeoms == 1 )
178 {
179 return ptarrayarc_contains_point(lwcirc->points, pt);
180 }
181 else
182 {
183 /* Don't check closure while doing p-i-p test */
184 result = ptarrayarc_contains_point_partial(lwcirc->points, pt, LW_FALSE, &winding_number);
185 }
186 }
187
188 /* Propogate boundary condition */
189 if ( result == LW_BOUNDARY )
190 return LW_BOUNDARY;
191
192 wn += winding_number;
193 }
194
195 /* Outside */
196 if (wn == 0)
197 return LW_OUTSIDE;
198
199 /* Inside */
200 return LW_INSIDE;
201}
202
205{
206 LWCOMPOUND* ogeom = lwcompound_construct_empty(lwline->srid, FLAGS_GET_Z(lwline->flags), FLAGS_GET_M(lwline->flags));
207 lwcompound_add_lwgeom(ogeom, lwgeom_clone((LWGEOM*)lwline));
208 /* ogeom->bbox = lwline->bbox; */
209 return ogeom;
210}
211
212LWPOINT*
213lwcompound_get_lwpoint(const LWCOMPOUND *lwcmp, uint32_t where)
214{
215 uint32_t i;
216 uint32_t count = 0;
217 uint32_t npoints = 0;
218 if ( lwgeom_is_empty((LWGEOM*)lwcmp) )
219 return NULL;
220
221 npoints = lwgeom_count_vertices((LWGEOM*)lwcmp);
222 if ( where >= npoints )
223 {
224 lwerror("%s: index %d is not in range of number of vertices (%d) in input", __func__, where, npoints);
225 return NULL;
226 }
227
228 for ( i = 0; i < lwcmp->ngeoms; i++ )
229 {
230 LWGEOM* part = lwcmp->geoms[i];
231 uint32_t npoints_part = lwgeom_count_vertices(part);
232 if ( where >= count && where < count + npoints_part )
233 {
234 return lwline_get_lwpoint((LWLINE*)part, where - count);
235 }
236 else
237 {
238 count += npoints_part;
239 }
240 }
241
242 return NULL;
243}
244
245
246
247LWPOINT *
249{
250 return lwcompound_get_lwpoint(lwcmp, 0);
251}
252
253LWPOINT *
255{
256 LWLINE *lwline;
257 if ( lwcmp->ngeoms < 1 )
258 {
259 return NULL;
260 }
261
262 lwline = (LWLINE*)(lwcmp->geoms[lwcmp->ngeoms-1]);
263
264 if ( (!lwline) || (!lwline->points) || (lwline->points->npoints < 1) )
265 {
266 return NULL;
267 }
268
269 return lwline_get_lwpoint(lwline, lwline->points->npoints-1);
270}
271
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition lwutil.c:216
#define LW_FALSE
Definition liblwgeom.h:108
#define COMPOUNDTYPE
Definition liblwgeom.h:124
#define LW_FAILURE
Definition liblwgeom.h:110
LWPOINT * lwline_get_lwpoint(const LWLINE *line, uint32_t where)
Returns freshly allocated LWPOINT that corresponds to the index where.
Definition lwline.c:309
#define LINETYPE
Definition liblwgeom.h:117
#define LW_SUCCESS
Definition liblwgeom.h:111
LWGEOM * lwgeom_clone(const LWGEOM *lwgeom)
Clone LWGEOM object.
Definition lwgeom.c:473
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition lwgeom.c:916
#define FLAGS_GET_Z(flags)
Definition liblwgeom.h:179
uint32_t lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Definition lwgeom.c:1229
LWCIRCSTRING * lwgeom_as_lwcircstring(const LWGEOM *lwgeom)
Definition lwgeom.c:170
#define CIRCSTRINGTYPE
Definition liblwgeom.h:123
double lwgeom_length_2d(const LWGEOM *geom)
Definition lwgeom.c:1952
#define FLAGS_GET_M(flags)
Definition liblwgeom.h:180
int getPoint4d_p(const POINTARRAY *pa, uint32_t n, POINT4D *point)
Definition lwgeom_api.c:125
LWLINE * lwgeom_as_lwline(const LWGEOM *lwgeom)
Definition lwgeom.c:161
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
#define LW_TRUE
Return types for functions with status returns.
Definition liblwgeom.h:107
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
int ptarray_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number)
Definition ptarray.c:746
#define LW_INSIDE
Constants for point-in-polygon return values.
#define LW_BOUNDARY
int ptarrayarc_contains_point(const POINTARRAY *pa, const POINT2D *pt)
For POINTARRAYs representing CIRCULARSTRINGS.
Definition ptarray.c:839
#define FP_EQUALS(A, B)
int ptarray_contains_point(const POINTARRAY *pa, const POINT2D *pt)
Return 1 if the point is inside the POINTARRAY, -1 if it is outside, and 0 if it is on the boundary.
Definition ptarray.c:740
int ptarrayarc_contains_point_partial(const POINTARRAY *pa, const POINT2D *pt, int check_closed, int *winding_number)
Definition ptarray.c:845
#define LW_OUTSIDE
double lwcompound_length_2d(const LWCOMPOUND *comp)
Definition lwcompound.c:74
int lwcompound_contains_point(const LWCOMPOUND *comp, const POINT2D *pt)
Definition lwcompound.c:145
LWPOINT * lwcompound_get_lwpoint(const LWCOMPOUND *lwcmp, uint32_t where)
Definition lwcompound.c:213
int lwcompound_is_closed(const LWCOMPOUND *compound)
Definition lwcompound.c:35
LWPOINT * lwcompound_get_endpoint(const LWCOMPOUND *lwcmp)
Definition lwcompound.c:254
double lwcompound_length(const LWCOMPOUND *comp)
Definition lwcompound.c:69
LWPOINT * lwcompound_get_startpoint(const LWCOMPOUND *lwcmp)
Definition lwcompound.c:248
LWCOMPOUND * lwcompound_construct_from_lwline(const LWLINE *lwline)
Construct an equivalent compound curve from a linestring.
Definition lwcompound.c:204
LWCOMPOUND * lwcompound_construct_empty(int32_t srid, char hasz, char hasm)
Definition lwcompound.c:123
int lwgeom_contains_point(const LWGEOM *geom, const POINT2D *pt)
Definition lwcompound.c:129
int lwcompound_add_lwgeom(LWCOMPOUND *comp, LWGEOM *geom)
Add a component, allocating extra space if necessary.
Definition lwcompound.c:88
#define LWDEBUG(level, msg)
Definition lwgeom_log.h:83
#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
static uint8_t * getPoint_internal(const POINTARRAY *pa, uint32_t n)
Definition lwinline.h:67
static int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members)
Definition lwinline.h:193
POINTARRAY * points
Definition liblwgeom.h:493
uint32_t ngeoms
Definition liblwgeom.h:566
LWGEOM ** geoms
Definition liblwgeom.h:561
uint32_t ngeoms
Definition liblwgeom.h:580
LWGEOM ** geoms
Definition liblwgeom.h:575
void * data
Definition liblwgeom.h:445
uint8_t type
Definition liblwgeom.h:448
lwflags_t flags
Definition liblwgeom.h:471
POINTARRAY * points
Definition liblwgeom.h:469
int32_t srid
Definition liblwgeom.h:470
double m
Definition liblwgeom.h:400
double x
Definition liblwgeom.h:400
double z
Definition liblwgeom.h:400
double y
Definition liblwgeom.h:400
uint32_t npoints
Definition liblwgeom.h:413