PostGIS  2.2.8dev-r@@SVN_REVISION@@
lwcollection.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 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include "liblwgeom_internal.h"
17 #include "lwgeom_log.h"
18 
19 
20 #define CHECK_LWGEOM_ZM 1
21 
22 void
24 {
26 }
27 
28 
30 lwcollection_construct(uint8_t type, int srid, GBOX *bbox,
31  uint32_t ngeoms, LWGEOM **geoms)
32 {
33  LWCOLLECTION *ret;
34  int hasz, hasm;
35 #ifdef CHECK_LWGEOM_ZM
36  char zm;
37  uint32_t i;
38 #endif
39 
40  LWDEBUGF(2, "lwcollection_construct called with %d, %d, %p, %d, %p.", type, srid, bbox, ngeoms, geoms);
41 
42  if( ! lwtype_is_collection(type) )
43  lwerror("Non-collection type specified in collection constructor!");
44 
45  hasz = 0;
46  hasm = 0;
47  if ( ngeoms > 0 )
48  {
49  hasz = FLAGS_GET_Z(geoms[0]->flags);
50  hasm = FLAGS_GET_M(geoms[0]->flags);
51 #ifdef CHECK_LWGEOM_ZM
52  zm = FLAGS_GET_ZM(geoms[0]->flags);
53 
54  LWDEBUGF(3, "lwcollection_construct type[0]=%d", geoms[0]->type);
55 
56  for (i=1; i<ngeoms; i++)
57  {
58  LWDEBUGF(3, "lwcollection_construct type=[%d]=%d", i, geoms[i]->type);
59 
60  if ( zm != FLAGS_GET_ZM(geoms[i]->flags) )
61  lwerror("lwcollection_construct: mixed dimension geometries: %d/%d", zm, FLAGS_GET_ZM(geoms[i]->flags));
62  }
63 #endif
64  }
65 
66 
67  ret = lwalloc(sizeof(LWCOLLECTION));
68  ret->type = type;
69  ret->flags = gflags(hasz,hasm,0);
70  FLAGS_SET_BBOX(ret->flags, bbox?1:0);
71  ret->srid = srid;
72  ret->ngeoms = ngeoms;
73  ret->maxgeoms = ngeoms;
74  ret->geoms = geoms;
75  ret->bbox = bbox;
76 
77  return ret;
78 }
79 
81 lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
82 {
83  LWCOLLECTION *ret;
84  if( ! lwtype_is_collection(type) )
85  lwerror("Non-collection type specified in collection constructor!");
86 
87  ret = lwalloc(sizeof(LWCOLLECTION));
88  ret->type = type;
89  ret->flags = gflags(hasz,hasm,0);
90  ret->srid = srid;
91  ret->ngeoms = 0;
92  ret->maxgeoms = 1; /* Allocate room for sub-members, just in case. */
93  ret->geoms = lwalloc(ret->maxgeoms * sizeof(LWGEOM*));
94  ret->bbox = NULL;
95 
96  return ret;
97 }
98 
99 LWGEOM *
101 {
102  return (LWGEOM *)col->geoms[gnum];
103 }
104 
109 LWCOLLECTION *
111 {
112  uint32_t i;
113  LWCOLLECTION *ret = lwalloc(sizeof(LWCOLLECTION));
114  memcpy(ret, g, sizeof(LWCOLLECTION));
115  if ( g->ngeoms > 0 )
116  {
117  ret->geoms = lwalloc(sizeof(LWGEOM *)*g->ngeoms);
118  for (i=0; i<g->ngeoms; i++)
119  {
120  ret->geoms[i] = lwgeom_clone(g->geoms[i]);
121  }
122  if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
123  }
124  else
125  {
126  ret->bbox = NULL; /* empty collection */
127  ret->geoms = NULL;
128  }
129  return ret;
130 }
131 
135 LWCOLLECTION *
137 {
138  uint32_t i;
139  LWCOLLECTION *ret = lwalloc(sizeof(LWCOLLECTION));
140  memcpy(ret, g, sizeof(LWCOLLECTION));
141  if ( g->ngeoms > 0 )
142  {
143  ret->geoms = lwalloc(sizeof(LWGEOM *)*g->ngeoms);
144  for (i=0; i<g->ngeoms; i++)
145  {
146  ret->geoms[i] = lwgeom_clone_deep(g->geoms[i]);
147  }
148  if ( g->bbox ) ret->bbox = gbox_copy(g->bbox);
149  }
150  else
151  {
152  ret->bbox = NULL; /* empty collection */
153  ret->geoms = NULL;
154  }
155  return ret;
156 }
157 
161 void lwcollection_reserve(LWCOLLECTION *col, int ngeoms)
162 {
163  if ( ngeoms <= col->maxgeoms ) return;
164 
165  /* Allocate more space if we need it */
166  do { col->maxgeoms *= 2; } while ( col->maxgeoms < ngeoms );
167  col->geoms = lwrealloc(col->geoms, sizeof(LWGEOM*) * col->maxgeoms);
168 }
169 
175 {
176  if ( col == NULL || geom == NULL ) return NULL;
177 
178  if ( col->geoms == NULL && (col->ngeoms || col->maxgeoms) ) {
179  lwerror("Collection is in inconsistent state. Null memory but non-zero collection counts.");
180  return NULL;
181  }
182 
183  /* Check type compatibility */
184  if ( ! lwcollection_allows_subtype(col->type, geom->type) ) {
185  lwerror("%s cannot contain %s element", lwtype_name(col->type), lwtype_name(geom->type));
186  return NULL;
187  }
188 
189  /* In case this is a truly empty, make some initial space */
190  if ( col->geoms == NULL )
191  {
192  col->maxgeoms = 2;
193  col->ngeoms = 0;
194  col->geoms = lwalloc(col->maxgeoms * sizeof(LWGEOM*));
195  }
196 
197  /* Allocate more space if we need it */
198  lwcollection_reserve(col, col->ngeoms + 1);
199 
200 #if PARANOIA_LEVEL > 1
201  /* See http://trac.osgeo.org/postgis/ticket/2933 */
202  /* Make sure we don't already have a reference to this geom */
203  {
204  int i = 0;
205  for ( i = 0; i < col->ngeoms; i++ )
206  {
207  if ( col->geoms[i] == geom )
208  {
209  LWDEBUGF(4, "Found duplicate geometry in collection %p == %p", col->geoms[i], geom);
210  return col;
211  }
212  }
213  }
214 #endif
215 
216  col->geoms[col->ngeoms] = (LWGEOM*)geom;
217  col->ngeoms++;
218  return col;
219 }
220 
221 
222 LWCOLLECTION *
224 {
225  uint32_t i;
226  LWGEOM **newgeoms;
227 
228  if ( ! col->ngeoms ) return lwcollection_clone(col);
229 
230  newgeoms = lwalloc(sizeof(LWGEOM *)*col->ngeoms);
231  for (i=0; i<col->ngeoms; i++)
232  {
233  newgeoms[i] = lwgeom_segmentize2d(col->geoms[i], dist);
234  if ( ! newgeoms[i] ) {
235  while (i--) lwgeom_free(newgeoms[i]);
236  lwfree(newgeoms);
237  return NULL;
238  }
239  }
240 
241  return lwcollection_construct(col->type, col->srid, NULL, col->ngeoms, newgeoms);
242 }
243 
247 char
249 {
250  uint32_t i;
251 
252  LWDEBUG(2, "lwcollection_same called");
253 
254  if ( c1->type != c2->type ) return LW_FALSE;
255  if ( c1->ngeoms != c2->ngeoms ) return LW_FALSE;
256 
257  for ( i = 0; i < c1->ngeoms; i++ )
258  {
259  if ( ! lwgeom_same(c1->geoms[i], c2->geoms[i]) )
260  return LW_FALSE;
261  }
262 
263  /* Former method allowed out-of-order equality between collections
264 
265  hit = lwalloc(sizeof(uint32_t)*c1->ngeoms);
266  memset(hit, 0, sizeof(uint32_t)*c1->ngeoms);
267 
268  for (i=0; i<c1->ngeoms; i++)
269  {
270  char found=0;
271  for (j=0; j<c2->ngeoms; j++)
272  {
273  if ( hit[j] ) continue;
274  if ( lwgeom_same(c1->geoms[i], c2->geoms[j]) )
275  {
276  hit[j] = 1;
277  found=1;
278  break;
279  }
280  }
281  if ( ! found ) return LW_FALSE;
282  }
283  */
284 
285  return LW_TRUE;
286 }
287 
289 {
290  int i;
291  int ngeoms = 0;
292 
293  if ( ! col )
294  {
295  lwerror("Null input geometry.");
296  return 0;
297  }
298 
299  for ( i = 0; i < col->ngeoms; i++ )
300  {
301  if ( col->geoms[i])
302  {
303  switch (col->geoms[i]->type)
304  {
305  case POINTTYPE:
306  case LINETYPE:
307  case CIRCSTRINGTYPE:
308  case POLYGONTYPE:
309  ngeoms += 1;
310  break;
311  case MULTIPOINTTYPE:
312  case MULTILINETYPE:
313  case MULTICURVETYPE:
314  case MULTIPOLYGONTYPE:
315  ngeoms += col->ngeoms;
316  break;
317  case COLLECTIONTYPE:
318  ngeoms += lwcollection_ngeoms((LWCOLLECTION*)col->geoms[i]);
319  break;
320  }
321  }
322  }
323  return ngeoms;
324 }
325 
327 {
328  int i;
329  if ( ! col ) return;
330 
331  if ( col->bbox )
332  {
333  lwfree(col->bbox);
334  }
335  for ( i = 0; i < col->ngeoms; i++ )
336  {
337  LWDEBUGF(4,"freeing geom[%d]", i);
338  if ( col->geoms && col->geoms[i] )
339  lwgeom_free(col->geoms[i]);
340  }
341  if ( col->geoms )
342  {
343  lwfree(col->geoms);
344  }
345  lwfree(col);
346 }
347 
348 
354 {
355  int i = 0;
356  LWGEOM **geomlist;
357  LWCOLLECTION *outcol;
358  int geomlistsize = 16;
359  int geomlistlen = 0;
360  uint8_t outtype;
361 
362  if ( ! col ) return NULL;
363 
364  switch (type)
365  {
366  case POINTTYPE:
367  outtype = MULTIPOINTTYPE;
368  break;
369  case LINETYPE:
370  outtype = MULTILINETYPE;
371  break;
372  case POLYGONTYPE:
373  outtype = MULTIPOLYGONTYPE;
374  break;
375  default:
376  lwerror("Only POLYGON, LINESTRING and POINT are supported by lwcollection_extract. %s requested.", lwtype_name(type));
377  return NULL;
378  }
379 
380  geomlist = lwalloc(sizeof(LWGEOM*) * geomlistsize);
381 
382  /* Process each sub-geometry */
383  for ( i = 0; i < col->ngeoms; i++ )
384  {
385  int subtype = col->geoms[i]->type;
386  /* Don't bother adding empty sub-geometries */
387  if ( lwgeom_is_empty(col->geoms[i]) )
388  {
389  continue;
390  }
391  /* Copy our sub-types into the output list */
392  if ( subtype == type )
393  {
394  /* We've over-run our buffer, double the memory segment */
395  if ( geomlistlen == geomlistsize )
396  {
397  geomlistsize *= 2;
398  geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize);
399  }
400  geomlist[geomlistlen] = lwgeom_clone(col->geoms[i]);
401  geomlistlen++;
402  }
403  /* Recurse into sub-collections */
404  if ( lwtype_is_collection( subtype ) )
405  {
406  int j = 0;
407  LWCOLLECTION *tmpcol = lwcollection_extract((LWCOLLECTION*)col->geoms[i], type);
408  for ( j = 0; j < tmpcol->ngeoms; j++ )
409  {
410  /* We've over-run our buffer, double the memory segment */
411  if ( geomlistlen == geomlistsize )
412  {
413  geomlistsize *= 2;
414  geomlist = lwrealloc(geomlist, sizeof(LWGEOM*) * geomlistsize);
415  }
416  geomlist[geomlistlen] = tmpcol->geoms[j];
417  geomlistlen++;
418  }
419  lwfree(tmpcol);
420  }
421  }
422 
423  if ( geomlistlen > 0 )
424  {
425  GBOX gbox;
426  outcol = lwcollection_construct(outtype, col->srid, NULL, geomlistlen, geomlist);
427  lwgeom_calculate_gbox((LWGEOM *) outcol, &gbox);
428  outcol->bbox = gbox_copy(&gbox);
429  }
430  else
431  {
432  lwfree(geomlist);
433  outcol = lwcollection_construct_empty(outtype, col->srid, FLAGS_GET_Z(col->flags), FLAGS_GET_M(col->flags));
434  }
435 
436  return outcol;
437 }
438 
439 LWGEOM*
441 {
442  uint32_t i;
443  LWGEOM **newgeoms;
444 
445  newgeoms = lwalloc(sizeof(LWGEOM *)*coll->ngeoms);
446  for (i=0; i<coll->ngeoms; i++)
447  {
448  newgeoms[i] = lwgeom_remove_repeated_points(coll->geoms[i], tolerance);
449  }
450 
451  return (LWGEOM*)lwcollection_construct(coll->type,
452  coll->srid, coll->bbox ? gbox_copy(coll->bbox) : NULL,
453  coll->ngeoms, newgeoms);
454 }
455 
456 
458 lwcollection_force_dims(const LWCOLLECTION *col, int hasz, int hasm)
459 {
460  LWCOLLECTION *colout;
461 
462  /* Return 2D empty */
463  if( lwcollection_is_empty(col) )
464  {
465  colout = lwcollection_construct_empty(col->type, col->srid, hasz, hasm);
466  }
467  else
468  {
469  int i;
470  LWGEOM **geoms = NULL;
471  geoms = lwalloc(sizeof(LWGEOM*) * col->ngeoms);
472  for( i = 0; i < col->ngeoms; i++ )
473  {
474  geoms[i] = lwgeom_force_dims(col->geoms[i], hasz, hasm);
475  }
476  colout = lwcollection_construct(col->type, col->srid, NULL, col->ngeoms, geoms);
477  }
478  return colout;
479 }
480 
482 {
483  int i;
484  if ( (col->ngeoms == 0) || (!col->geoms) )
485  return LW_TRUE;
486  for( i = 0; i < col->ngeoms; i++ )
487  {
488  if ( ! lwgeom_is_empty(col->geoms[i]) ) return LW_FALSE;
489  }
490  return LW_TRUE;
491 }
492 
493 
495 {
496  int i = 0;
497  int v = 0; /* vertices */
498  assert(col);
499  for ( i = 0; i < col->ngeoms; i++ )
500  {
501  v += lwgeom_count_vertices(col->geoms[i]);
502  }
503  return v;
504 }
505 
506 LWCOLLECTION* lwcollection_simplify(const LWCOLLECTION *igeom, double dist, int preserve_collapsed)
507 {
508  int i;
509  LWCOLLECTION *out = lwcollection_construct_empty(igeom->type, igeom->srid, FLAGS_GET_Z(igeom->flags), FLAGS_GET_M(igeom->flags));
510 
511  if( lwcollection_is_empty(igeom) )
512  return out; /* should we return NULL instead ? */
513 
514  for( i = 0; i < igeom->ngeoms; i++ )
515  {
516  LWGEOM *ngeom = lwgeom_simplify(igeom->geoms[i], dist, preserve_collapsed);
517  if ( ngeom ) out = lwcollection_add_lwgeom(out, ngeom);
518  }
519 
520  return out;
521 }
522 
523 int lwcollection_allows_subtype(int collectiontype, int subtype)
524 {
525  if ( collectiontype == COLLECTIONTYPE )
526  return LW_TRUE;
527  if ( collectiontype == MULTIPOINTTYPE &&
528  subtype == POINTTYPE )
529  return LW_TRUE;
530  if ( collectiontype == MULTILINETYPE &&
531  subtype == LINETYPE )
532  return LW_TRUE;
533  if ( collectiontype == MULTIPOLYGONTYPE &&
534  subtype == POLYGONTYPE )
535  return LW_TRUE;
536  if ( collectiontype == COMPOUNDTYPE &&
537  (subtype == LINETYPE || subtype == CIRCSTRINGTYPE) )
538  return LW_TRUE;
539  if ( collectiontype == CURVEPOLYTYPE &&
540  (subtype == CIRCSTRINGTYPE || subtype == LINETYPE || subtype == COMPOUNDTYPE) )
541  return LW_TRUE;
542  if ( collectiontype == MULTICURVETYPE &&
543  (subtype == CIRCSTRINGTYPE || subtype == LINETYPE || subtype == COMPOUNDTYPE) )
544  return LW_TRUE;
545  if ( collectiontype == MULTISURFACETYPE &&
546  (subtype == POLYGONTYPE || subtype == CURVEPOLYTYPE) )
547  return LW_TRUE;
548  if ( collectiontype == POLYHEDRALSURFACETYPE &&
549  subtype == POLYGONTYPE )
550  return LW_TRUE;
551  if ( collectiontype == TINTYPE &&
552  subtype == TRIANGLETYPE )
553  return LW_TRUE;
554 
555  /* Must be a bad combination! */
556  return LW_FALSE;
557 }
558 
559 int
561 {
562  if ( col->ngeoms < 1 )
563  return LW_FAILURE;
564 
565  return lwgeom_startpoint(col->geoms[0], pt);
566 }
567 
568 
570 {
571  uint32_t i;
572  LWCOLLECTION *newcoll;
573 
574  newcoll = lwcollection_construct_empty(coll->type, coll->srid, lwgeom_has_z((LWGEOM*)coll), lwgeom_has_m((LWGEOM*)coll));
575 
576  for (i=0; i<coll->ngeoms; i++)
577  {
578  LWGEOM *g = lwgeom_grid(coll->geoms[i], grid);
579  if ( g )
580  lwcollection_add_lwgeom(newcoll, g);
581  }
582 
583  return newcoll;
584 }
#define LINETYPE
Definition: liblwgeom.h:71
GBOX * gbox_copy(const GBOX *box)
Return a copy of the GBOX, based on dimensionality of flags.
Definition: g_box.c:403
void lwcollection_release(LWCOLLECTION *lwcollection)
Definition: lwcollection.c:23
void lwcollection_reserve(LWCOLLECTION *col, int ngeoms)
Ensure the collection can hold up at least ngeoms.
Definition: lwcollection.c:161
GBOX * bbox
Definition: liblwgeom.h:382
#define MULTICURVETYPE
Definition: liblwgeom.h:80
LWGEOM * lwgeom_grid(const LWGEOM *lwgeom, const gridspec *grid)
Definition: lwgeom.c:1868
int lwcollection_count_vertices(LWCOLLECTION *col)
Definition: lwcollection.c:494
void lwfree(void *mem)
Definition: lwutil.c:214
uint8_t type
Definition: liblwgeom.h:487
int lwgeom_startpoint(const LWGEOM *lwgeom, POINT4D *pt)
Definition: lwgeom.c:1837
#define POLYGONTYPE
Definition: liblwgeom.h:72
LWCOLLECTION * lwcollection_clone(const LWCOLLECTION *g)
Clone LWCOLLECTION object.
Definition: lwcollection.c:110
#define CURVEPOLYTYPE
Definition: liblwgeom.h:79
void lwgeom_free(LWGEOM *geom)
Definition: lwgeom.c:1050
#define COMPOUNDTYPE
Definition: liblwgeom.h:78
#define MULTIPOINTTYPE
Definition: liblwgeom.h:73
GBOX * bbox
Definition: liblwgeom.h:489
#define FLAGS_GET_ZM(flags)
Definition: liblwgeom.h:137
void lwcollection_free(LWCOLLECTION *col)
Definition: lwcollection.c:326
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
#define TRIANGLETYPE
Definition: liblwgeom.h:83
#define POLYHEDRALSURFACETYPE
Definition: liblwgeom.h:82
LWCOLLECTION * lwcollection_segmentize2d(LWCOLLECTION *col, double dist)
Definition: lwcollection.c:223
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
Definition: lwgeom.c:433
int lwgeom_has_z(const LWGEOM *geom)
Return LW_TRUE if geometry has Z ordinates.
Definition: lwgeom.c:836
LWCOLLECTION * lwcollection_grid(const LWCOLLECTION *coll, const gridspec *grid)
Definition: lwcollection.c:569
int lwcollection_is_empty(const LWCOLLECTION *col)
Definition: lwcollection.c:481
#define LW_FAILURE
Definition: liblwgeom.h:64
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
Definition: lwcollection.c:81
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
Definition: lwgeom.c:652
uint8_t flags
Definition: liblwgeom.h:488
LWCOLLECTION * lwcollection_construct(uint8_t type, int srid, GBOX *bbox, uint32_t ngeoms, LWGEOM **geoms)
Definition: lwcollection.c:30
LWGEOM * lwgeom_remove_repeated_points(LWGEOM *in, double tolerance)
Remove repeated points!
Definition: lwgeom.c:1407
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
Definition: lwutil.c:188
#define LW_FALSE
Definition: liblwgeom.h:62
LWCOLLECTION * lwcollection_extract(LWCOLLECTION *col, int type)
Takes a potentially heterogeneous collection and returns a homogeneous collection consisting only of ...
Definition: lwcollection.c:353
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
Definition: lwcollection.c:174
int lwcollection_ngeoms(const LWCOLLECTION *col)
Definition: lwcollection.c:288
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:61
LWGEOM ** geoms
Definition: liblwgeom.h:493
LWGEOM * lwgeom_simplify(const LWGEOM *igeom, double dist, int preserve_collapsed)
Definition: lwgeom.c:1558
#define TINTYPE
Definition: liblwgeom.h:84
int lwtype_is_collection(uint8_t type)
Determine whether a type number is a collection or not.
Definition: lwgeom.c:999
char lwcollection_same(const LWCOLLECTION *c1, const LWCOLLECTION *c2)
check for same geometry composition
Definition: lwcollection.c:248
int lwcollection_allows_subtype(int collectiontype, int subtype)
Check if subtype is allowed in collectiontype.
Definition: lwcollection.c:523
int32_t srid
Definition: liblwgeom.h:490
LWCOLLECTION * lwcollection_clone_deep(const LWCOLLECTION *g)
Deep clone LWCOLLECTION object.
Definition: lwcollection.c:136
#define FLAGS_GET_Z(flags)
Macros for manipulating the &#39;flags&#39; byte.
Definition: liblwgeom.h:124
LWGEOM * lwgeom_force_dims(const LWGEOM *lwgeom, int hasz, int hasm)
Definition: lwgeom.c:714
LWGEOM * lwcollection_remove_repeated_points(LWCOLLECTION *coll, double tolerance)
Definition: lwcollection.c:440
LWGEOM * lwgeom_clone(const LWGEOM *lwgeom)
Clone LWGEOM object.
Definition: lwgeom.c:395
char lwgeom_same(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2)
geom1 same as geom2 iff
Definition: lwgeom.c:495
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
Definition: g_util.c:130
#define MULTIPOLYGONTYPE
Definition: liblwgeom.h:75
#define FLAGS_SET_BBOX(flags, value)
Definition: liblwgeom.h:132
LWCOLLECTION * lwcollection_force_dims(const LWCOLLECTION *col, int hasz, int hasm)
Definition: lwcollection.c:458
int lwcollection_startpoint(const LWCOLLECTION *col, POINT4D *pt)
Definition: lwcollection.c:560
#define MULTISURFACETYPE
Definition: liblwgeom.h:81
LWGEOM * lwcollection_getsubgeom(LWCOLLECTION *col, int gnum)
Definition: lwcollection.c:100
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:207
LWGEOM * lwgeom_segmentize2d(LWGEOM *line, double dist)
Definition: lwgeom.c:668
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
Definition: liblwgeom.h:70
#define FLAGS_GET_M(flags)
Definition: liblwgeom.h:125
void lwgeom_release(LWGEOM *lwgeom)
Free the containing LWGEOM and the associated BOX.
Definition: lwgeom.c:372
uint8_t type
Definition: liblwgeom.h:380
type
Definition: ovdump.py:41
#define CIRCSTRINGTYPE
Definition: liblwgeom.h:77
void * lwalloc(size_t size)
Definition: lwutil.c:199
int lwgeom_is_empty(const LWGEOM *geom)
Return true or false depending on whether a geometry is an "empty" geometry (no vertices members) ...
Definition: lwgeom.c:1297
int lwgeom_count_vertices(const LWGEOM *geom)
Count the total number of vertices in any LWGEOM.
Definition: lwgeom.c:1140
#define MULTILINETYPE
Definition: liblwgeom.h:74
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
int lwgeom_has_m(const LWGEOM *geom)
Return LW_TRUE if geometry has M ordinates.
Definition: lwgeom.c:843
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:74
LWCOLLECTION * lwcollection_simplify(const LWCOLLECTION *igeom, double dist, int preserve_collapsed)
Definition: lwcollection.c:506
#define COLLECTIONTYPE
Definition: liblwgeom.h:76
LWGEOM * lwcollection_as_lwgeom(const LWCOLLECTION *obj)
Definition: lwgeom.c:219
Snap to grid.